listctrl.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,239 行 · 第 1/5 页
CPP
2,239 行
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
wxCHECK_RET( node, _T("invalid column index in SetItem") );
wxListItemData *item = node->GetData();
item->SetItem( info );
}
void wxListLineData::GetItem( int index, wxListItem &info )
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
if (node)
{
wxListItemData *item = node->GetData();
item->GetItem( info );
}
}
wxString wxListLineData::GetText(int index) const
{
wxString s;
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
if (node)
{
wxListItemData *item = node->GetData();
s = item->GetText();
}
return s;
}
void wxListLineData::SetText( int index, const wxString s )
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
if (node)
{
wxListItemData *item = node->GetData();
item->SetText( s );
}
}
void wxListLineData::SetImage( int index, int image )
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
wxCHECK_RET( node, _T("invalid column index in SetImage()") );
wxListItemData *item = node->GetData();
item->SetImage(image);
}
int wxListLineData::GetImage( int index ) const
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
wxCHECK_MSG( node, -1, _T("invalid column index in GetImage()") );
wxListItemData *item = node->GetData();
return item->GetImage();
}
wxListItemAttr *wxListLineData::GetAttr() const
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_MSG( node, NULL, _T("invalid column index in GetAttr()") );
wxListItemData *item = node->GetData();
return item->GetAttr();
}
void wxListLineData::SetAttr(wxListItemAttr *attr)
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_RET( node, _T("invalid column index in SetAttr()") );
wxListItemData *item = node->GetData();
item->SetAttr(attr);
}
bool wxListLineData::SetAttributes(wxDC *dc,
const wxListItemAttr *attr,
bool highlighted)
{
wxWindow *listctrl = m_owner->GetParent();
// fg colour
// don't use foreground colour for drawing highlighted items - this might
// make them completely invisible (and there is no way to do bit
// arithmetics on wxColour, unfortunately)
wxColour colText;
if ( highlighted )
{
colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
}
else
{
if ( attr && attr->HasTextColour() )
{
colText = attr->GetTextColour();
}
else
{
colText = listctrl->GetForegroundColour();
}
}
dc->SetTextForeground(colText);
// font
wxFont font;
if ( attr && attr->HasFont() )
{
font = attr->GetFont();
}
else
{
font = listctrl->GetFont();
}
dc->SetFont(font);
// bg colour
bool hasBgCol = attr && attr->HasBackgroundColour();
if ( highlighted || hasBgCol )
{
if ( highlighted )
{
dc->SetBrush( *m_owner->GetHighlightBrush() );
}
else
{
dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID));
}
dc->SetPen( *wxTRANSPARENT_PEN );
return true;
}
return false;
}
void wxListLineData::Draw( wxDC *dc )
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_RET( node, _T("no subitems at all??") );
bool highlighted = IsHighlighted();
wxListItemAttr *attr = GetAttr();
if ( SetAttributes(dc, attr, highlighted) )
{
dc->DrawRectangle( m_gi->m_rectHighlight );
}
// just for debugging to better see where the items are
#if 0
dc->SetPen(*wxRED_PEN);
dc->SetBrush(*wxTRANSPARENT_BRUSH);
dc->DrawRectangle( m_gi->m_rectAll );
dc->SetPen(*wxGREEN_PEN);
dc->DrawRectangle( m_gi->m_rectIcon );
#endif // 0
wxListItemData *item = node->GetData();
if (item->HasImage())
{
// centre the image inside our rectangle, this looks nicer when items
// ae aligned in a row
const wxRect& rectIcon = m_gi->m_rectIcon;
m_owner->DrawImage(item->GetImage(), dc, rectIcon.x, rectIcon.y);
}
if (item->HasText())
{
const wxRect& rectLabel = m_gi->m_rectLabel;
wxDCClipper clipper(*dc, rectLabel);
dc->DrawText(item->GetText(), rectLabel.x, rectLabel.y);
}
}
void wxListLineData::DrawInReportMode( wxDC *dc,
const wxRect& rect,
const wxRect& rectHL,
bool highlighted )
{
// TODO: later we should support setting different attributes for
// different columns - to do it, just add "col" argument to
// GetAttr() and move these lines into the loop below
wxListItemAttr *attr = GetAttr();
if ( SetAttributes(dc, attr, highlighted) )
{
dc->DrawRectangle( rectHL );
}
wxCoord x = rect.x + HEADER_OFFSET_X,
y = rect.y + (LINE_SPACING + EXTRA_HEIGHT) / 2;
size_t col = 0;
for ( wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
node;
node = node->GetNext(), col++ )
{
wxListItemData *item = node->GetData();
int width = m_owner->GetColumnWidth(col);
int xOld = x;
x += width;
if ( item->HasImage() )
{
int ix, iy;
m_owner->DrawImage( item->GetImage(), dc, xOld, y );
m_owner->GetImageSize( item->GetImage(), ix, iy );
ix += IMAGE_MARGIN_IN_REPORT_MODE;
xOld += ix;
width -= ix;
}
wxDCClipper clipper(*dc, xOld, y, width - 8, rect.height);
if ( item->HasText() )
{
DrawTextFormatted(dc, item->GetText(), col, xOld, y, width - 8);
}
}
}
void wxListLineData::DrawTextFormatted(wxDC *dc,
const wxString &text,
int col,
int x,
int y,
int width)
{
wxString drawntext, ellipsis;
wxCoord w, h, base_w;
wxListItem item;
// determine if the string can fit inside the current width
dc->GetTextExtent(text, &w, &h);
if (w <= width)
{
// it can, draw it using the items alignment
m_owner->GetColumn(col, item);
switch ( item.GetAlign() )
{
default:
wxFAIL_MSG( _T("unknown list item format") );
// fall through
case wxLIST_FORMAT_LEFT:
// nothing to do
break;
case wxLIST_FORMAT_RIGHT:
x += width - w;
break;
case wxLIST_FORMAT_CENTER:
x += (width - w) / 2;
break;
}
dc->DrawText(text, x, y);
}
else // otherwise, truncate and add an ellipsis if possible
{
// determine the base width
ellipsis = wxString(wxT("..."));
dc->GetTextExtent(ellipsis, &base_w, &h);
// continue until we have enough space or only one character left
wxCoord w_c, h_c;
size_t len = text.Length();
drawntext = text.Left(len);
while (len > 1)
{
dc->GetTextExtent(drawntext.Last(), &w_c, &h_c);
drawntext.RemoveLast();
len--;
w -= w_c;
if (w + base_w <= width)
break;
}
// if still not enough space, remove ellipsis characters
while (ellipsis.Length() > 0 && w + base_w > width)
{
ellipsis = ellipsis.Left(ellipsis.Length() - 1);
dc->GetTextExtent(ellipsis, &base_w, &h);
}
// now draw the text
dc->DrawText(drawntext, x, y);
dc->DrawText(ellipsis, x + w, y);
}
}
bool wxListLineData::Highlight( bool on )
{
wxCHECK_MSG( !IsVirtual(), false, _T("unexpected call to Highlight") );
if ( on == m_highlighted )
return false;
m_highlighted = on;
return true;
}
void wxListLineData::ReverseHighlight( void )
{
Highlight(!IsHighlighted());
}
//-----------------------------------------------------------------------------
// wxListHeaderWindow
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow,wxWindow)
BEGIN_EVENT_TABLE(wxListHeaderWindow,wxWindow)
EVT_PAINT (wxListHeaderWindow::OnPaint)
EVT_MOUSE_EVENTS (wxListHeaderWindow::OnMouse)
EVT_SET_FOCUS (wxListHeaderWindow::OnSetFocus)
END_EVENT_TABLE()
void wxListHeaderWindow::Init()
{
m_currentCursor = (wxCursor *) NULL;
m_isDragging = false;
m_dirty = false;
}
wxListHeaderWindow::wxListHeaderWindow()
{
Init();
m_owner = (wxListMainWindow *) NULL;
m_resizeCursor = (wxCursor *) NULL;
}
wxListHeaderWindow::wxListHeaderWindow( wxWindow *win,
wxWindowID id,
wxListMainWindow *owner,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString &name )
: wxWindow( win, id, pos, size, style, name )
{
Init();
m_owner = owner;
m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE );
#if _USE_VISATTR
wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes();
SetOwnForegroundColour( attr.colFg );
SetOwnBackgroundColour( attr.colBg );
if (!m_hasFont)
SetOwnFont( attr.font );
#else
SetOwnForegroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
SetOwnBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
if (!m_hasFont)
SetOwnFont( wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT ));
#endif
}
wxListHeaderWindow::~wxListHeaderWindow()
{
delete m_resizeCursor;
}
#ifdef __WXUNIVERSAL__
#include "wx/univ/renderer.h"
#include "wx/univ/theme.h"
#endif
// shift the DC origin to match the position of the main window horz
// scrollbar: this allows us to always use logical coords
void wxListHeaderWindow::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 wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{
wxPaintDC dc( this );
PrepareDC( dc );
AdjustDC( dc );
dc.BeginDrawing();
dc.SetFont( GetFont() );
// width and height of the entire header window
int w, h;
GetClientSize( &w, &h );
m_owner->CalcUnscrolledPosition(w, 0, &w, NULL);
dc.SetBackgroundMode(wxTRANSPARENT);
dc.SetTextForeground(GetForegroundColour());
int x = HEADER_OFFSET_X;
int numColumns = m_owner->GetColumnCount();
wxListItem item;
for ( int i = 0; i < numColumns && x < w; i++ )
{
m_owner->GetColumn( i, item );
int wCol = item.m_width;
// the width of the rect to draw: make it smaller to fit entirely
// inside the column rect
#ifdef __WXMAC__
int cw = wCol ;
int ch = h ;
#else
int cw = wCol - 2;
int ch = h-2 ;
#endif
wxRendererNative::Get().DrawHeaderButton
(
this,
dc,
wxRect(x, HEADER_OFFSET_Y, cw, ch),
m_parent->IsEnabled() ? 0
: (int)wxCONTROL_DISABLED
);
// see if we have enough space for the column label
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?