📄 treelistctrl.cpp
字号:
dc->DrawLine( x+w-1, y, x+w-1, y+1 );
#else // !GTK, !Mac
const int m_corner = 1;
dc->SetBrush( *wxTRANSPARENT_BRUSH );
dc->SetPen( *wxBLACK_PEN );
dc->DrawLine( x+w-m_corner+1, y, x+w, y+h ); // right (outer)
dc->DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer)
wxPen pen(wxSystemSettings::GetColour(
wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID);
dc->SetPen( pen );
dc->DrawLine( x+w-m_corner, y, x+w-1, y+h ); // right (inner)
dc->DrawRectangle( x+1, y+h-1, w-2, 1 ); // bottom (inner)
dc->SetPen( *wxWHITE_PEN );
dc->DrawRectangle( x, y, w-m_corner+1, 1 ); // top (outer)
dc->DrawRectangle( x, y, 1, h ); // left (outer)
dc->DrawLine( x, y+h-1, x+1, y+h-1 );
dc->DrawLine( x+w-1, y, x+w-1, y+1 );
#endif
}
// shift the DC origin to match the position of the main window horz
// scrollbar: this allows us to always use logical coords
void wxTreeListHeaderWindow::AdjustDC(wxDC& dc)
{
int xpix;
m_owner->GetScrollPixelsPerUnit( &xpix, NULL );
int x;
m_owner->GetViewStart( &x, NULL );
// account for the horz scrollbar offset
dc.SetDeviceOrigin( -x * xpix, 0 );
}
void wxTreeListHeaderWindow::OnEraseBackground( wxEraseEvent& event )
{
}
void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{
#ifdef __WXGTK__
wxClientDC real_dc( this );
#else
wxPaintDC real_dc( this );
#endif
AdjustDC( real_dc );
// width and height of the entire header window
int w, h;
GetClientSize( &w, &h );
m_owner->CalcUnscrolledPosition(w, 0, &w, NULL);
// Setup double buffering to eliminate the flicker
wxMemoryDC dc;
wxBitmap buffer(w, h);
dc.SelectObject(buffer);
dc.SetBackground(wxBrush(GetBackgroundColour()));
dc.Clear();
dc.SetFont( GetFont() );
dc.SetBackgroundMode(wxTRANSPARENT);
// do *not* use the listctrl colour for headers - one day we will have a
// function to set it separately
//dc.SetTextForeground( *wxBLACK );
dc.SetTextForeground(wxSystemSettings::
GetColour( wxSYS_COLOUR_WINDOWTEXT ));
int x = HEADER_OFFSET_X;
int numColumns = GetColumnCount();
for ( int i = 0; i < numColumns && x < w; i++ )
{
if (!GetColumnShown (i)) continue;
wxTreeListColumnInfo& column = GetColumn(i);
int wCol = column.GetWidth();
// the width of the rect to draw: make it smaller to fit entirely
// inside the column rect
int cw = wCol - 2;
dc.SetPen( *wxWHITE_PEN );
//DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 );
wxRendererNative::Get().DrawHeaderButton(
this, dc, wxRect(x, HEADER_OFFSET_Y, cw, h - 2),
m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED);
// if we have an image, draw it on the right of the label
int image = column.GetImage(); //item.m_image;
int ix = -2, iy = 0;
wxImageList* imageList = m_owner->GetImageList();
if(image != -1) {
if(imageList) {
imageList->GetSize(image, ix, iy);
}
//else: ignore the column image
}
int text_width = 0;
int text_x = x;
int image_offset = cw - ix - 1;
switch(column.GetAlignment()) {
case wxTL_ALIGN_LEFT:
text_x += EXTRA_WIDTH;
cw -= ix + 2;
break;
case wxTL_ALIGN_RIGHT:
dc.GetTextExtent(column.GetText(), &text_width, NULL);
text_x += cw - text_width - EXTRA_WIDTH;
image_offset = 0;
break;
case wxTL_ALIGN_CENTER:
dc.GetTextExtent(column.GetText(), &text_width, NULL);
text_x += (cw - text_width)/2 + ix + 2;
image_offset = (cw - text_width - ix - 2)/2;
break;
}
// draw the image
if(image != -1 && imageList) {
imageList->Draw(image, dc, x + image_offset/*cw - ix - 1*/,
HEADER_OFFSET_Y + (h - 4 - iy)/2,
wxIMAGELIST_DRAW_TRANSPARENT);
}
// draw the text clipping it so that it doesn't overwrite the column
// boundary
wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 );
dc.DrawText( column.GetText(),
text_x, HEADER_OFFSET_Y + EXTRA_HEIGHT );
x += wCol;
}
int more_w = m_owner->GetSize().x - x -1;
if (more_w > 0)
{
//DoDrawRect( &dc, x, HEADER_OFFSET_Y, more_w, h-2 );
wxRendererNative::Get().DrawHeaderButton(
this, dc, wxRect(x, HEADER_OFFSET_Y, more_w, h-2),
m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED);
}
// Finish up by drawing the buffer to the real dc
dc.SelectObject(wxNullBitmap);
real_dc.DrawBitmap(buffer, 0, 0, false);
}
void wxTreeListHeaderWindow::DrawCurrent()
{
int x1 = m_currentX;
int y1 = 0;
ClientToScreen( &x1, &y1 );
int x2 = m_currentX-1;
#ifdef __WXMSW__
++x2; // but why ?
#endif
int y2 = 0;
m_owner->GetClientSize( NULL, &y2 );
m_owner->ClientToScreen( &x2, &y2 );
wxScreenDC dc;
dc.SetLogicalFunction( wxINVERT );
dc.SetPen( wxPen( *wxBLACK, 2, wxSOLID ) );
dc.SetBrush( *wxTRANSPARENT_BRUSH );
AdjustDC(dc);
dc.DrawLine( x1, y1, x2, y2 );
dc.SetLogicalFunction( wxCOPY );
dc.SetPen( wxNullPen );
dc.SetBrush( wxNullBrush );
}
void wxTreeListHeaderWindow::OnMouse( wxMouseEvent &event )
{
// we want to work with logical coords
int x;
m_owner->CalcUnscrolledPosition(event.GetX(), 0, &x, NULL);
int y = event.GetY();
if (m_isDragging)
{
SendListEvent(wxEVT_COMMAND_LIST_COL_DRAGGING,
event.GetPosition());
// we don't draw the line beyond our window, but we allow dragging it
// there
int w = 0;
GetClientSize( &w, NULL );
m_owner->CalcUnscrolledPosition(w, 0, &w, NULL);
w -= 6;
// erase the line if it was drawn
if ( m_currentX < w )
DrawCurrent();
if (event.ButtonUp())
{
ReleaseMouse();
m_isDragging = FALSE;
m_dirty = TRUE;
SetColumnWidth( m_column, m_currentX - m_minX );
Refresh();
SendListEvent(wxEVT_COMMAND_LIST_COL_END_DRAG,
event.GetPosition());
}
else
{
if (x > m_minX + 7)
m_currentX = x;
else
m_currentX = m_minX + 7;
// draw in the new location
if ( m_currentX < w )
DrawCurrent();
}
}
else // not dragging
{
m_minX = 0;
bool hit_border = FALSE;
// end of the current column
int xpos = 0;
// find the column where this event occurred
int countCol = GetColumnCount();
for (int col = 0; col < countCol; col++)
{
if (!GetColumnShown (col)) continue;
xpos += GetColumnWidth (col);
m_column = col;
if ( (abs(x-xpos) < 3) && (y < 22) )
{
// near the column border
hit_border = TRUE;
break;
}
if ( x < xpos )
{
// inside the column
break;
}
m_minX = xpos;
}
if (event.LeftDown() || event.RightUp())
{
if (hit_border && event.LeftDown())
{
m_isDragging = TRUE;
m_currentX = x;
DrawCurrent();
CaptureMouse();
SendListEvent(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG,
event.GetPosition());
}
else // click on a column
{
SendListEvent( event.LeftDown()
? wxEVT_COMMAND_LIST_COL_CLICK
: wxEVT_COMMAND_LIST_COL_RIGHT_CLICK,
event.GetPosition());
}
}
else if (event.Moving())
{
bool setCursor;
if (hit_border)
{
setCursor = m_currentCursor == wxSTANDARD_CURSOR;
m_currentCursor = m_resizeCursor;
}
else
{
setCursor = m_currentCursor != wxSTANDARD_CURSOR;
m_currentCursor = wxSTANDARD_CURSOR;
}
if ( setCursor )
SetCursor(*m_currentCursor);
}
}
}
void wxTreeListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
{
m_owner->SetFocus();
}
void wxTreeListHeaderWindow::SendListEvent(wxEventType type, wxPoint pos)
{
wxWindow *parent = GetParent();
wxListEvent le( type, parent->GetId() );
le.SetEventObject( parent );
le.m_pointDrag = pos;
// the position should be relative to the parent window, not
// this one for compatibility with MSW and common sense: the
// user code doesn't know anything at all about this header
// window, so why should it get positions relative to it?
le.m_pointDrag.y -= GetSize().y;
le.m_col = m_column;
parent->GetEventHandler()->ProcessEvent( le );
}
void wxTreeListHeaderWindow::AddColumn(const wxTreeListColumnInfo& col)
{
m_columns.Add(col);
m_total_col_width += col.GetWidth();
//m_owner->GetHeaderWindow()->Refresh();
//m_dirty = TRUE;
m_owner->AdjustMyScrollbars();
m_owner->m_dirty = TRUE;
Refresh();
}
void wxTreeListHeaderWindow::SetColumnWidth(size_t column, size_t width)
{
if(column < GetColumnCount()) {
m_total_col_width -= m_columns[column].GetWidth();
m_columns[column].SetWidth(width);
m_total_col_width += width;
m_owner->AdjustMyScrollbars();
m_owner->m_dirty = TRUE;
//m_dirty = TRUE;
Refresh();
}
}
void wxTreeListHeaderWindow::InsertColumn(size_t before,
const wxTreeListColumnInfo& col)
{
wxCHECK_RET(before < GetColumnCount(), wxT("Invalid column index"));
m_columns.Insert(col, before);
m_total_col_width += col.GetWidth();
//m_dirty = TRUE;
//m_owner->GetHeaderWindow()->Refresh();
m_owner->AdjustMyScrollbars();
m_owner->m_dirty = TRUE;
Refresh();
}
void wxTreeListHeaderWindow::RemoveColumn(size_t column)
{
wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column"));
m_total_col_width -= m_columns[column].GetWidth();
m_columns.RemoveAt(column);
//m_dirty = TRUE;
m_owner->AdjustMyScrollbars();
m_owner->m_dirty = TRUE;
Refresh();
}
void wxTreeListHeaderWindow::SetColumn(size_t column,
const wxTreeListColumnInfo& info)
{
wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column"));
size_t w = m_columns[column].GetWidth();
m_columns[column] = info;
//m_owner->GetHeaderWindow()->Refresh();
//m_dirty = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -