Fix drawing of items with custom background in wxGenericListCtrl.

This was broken by the changes of r64879 which erroneously used
wxRendererNative::DrawItemSelectionRect() even for the non-selected items.

Now only use DrawItemSelectionRect() for the selected items to make them
appear natively while drawing the non-selected items with custom background
colour ourselves.

Also refactor the code to avoid (the not quite and hence especially
pernicious) duplication between wxListLineData::Draw() and DrawInReportMode():
rename SetAttributes() to ApplyAttributes() and draw the item background in
this function now instead of doing it in both Draw() and DrawInReportMode().

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65541 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2010-09-14 13:18:48 +00:00
parent 4be95bef8c
commit ed84dc74d9
2 changed files with 52 additions and 67 deletions

View File

@@ -275,9 +275,10 @@ public:
} }
// draw the line on the given DC in icon/list mode // draw the line on the given DC in icon/list mode
void Draw( wxDC *dc ); void Draw( wxDC *dc, bool current );
// the same in report mode // the same in report mode: it needs more parameters as we don't store
// everything in the item in report mode
void DrawInReportMode( wxDC *dc, void DrawInReportMode( wxDC *dc,
const wxRect& rect, const wxRect& rect,
const wxRect& rectHL, const wxRect& rectHL,
@@ -291,11 +292,12 @@ private:
// get the mode (i.e. style) of the list control // get the mode (i.e. style) of the list control
inline int GetMode() const; inline int GetMode() const;
// prepare the DC for drawing with these item's attributes, return true if // Apply this item attributes to the given DC: set the text font and colour
// we need to draw the items background to highlight it, false otherwise // and also erase the background appropriately.
bool SetAttributes(wxDC *dc, void ApplyAttributes(wxDC *dc,
const wxListItemAttr *attr, const wxRect& rectHL,
bool highlight); bool highlighted,
bool current);
// draw the text on the DC with the correct justification; also add an // draw the text on the DC with the correct justification; also add an
// ellipsis if the text is too large to fit in the current width // ellipsis if the text is too large to fit in the current width

View File

@@ -667,11 +667,20 @@ void wxListLineData::SetAttr(wxListItemAttr *attr)
item->SetAttr(attr); item->SetAttr(attr);
} }
bool wxListLineData::SetAttributes(wxDC *dc, void wxListLineData::ApplyAttributes(wxDC *dc,
const wxListItemAttr *attr, const wxRect& rectHL,
bool highlighted) bool highlighted,
bool current)
{ {
wxWindow *listctrl = m_owner->GetParent(); const wxListItemAttr * const attr = GetAttr();
wxWindow * const listctrl = m_owner->GetParent();
const bool hasFocus = listctrl->HasFocus()
#if defined(__WXMAC__) && !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON
&& IsControlActive( (ControlRef)listctrl->GetHandle() )
#endif
;
// fg colour // fg colour
@@ -680,20 +689,16 @@ bool wxListLineData::SetAttributes(wxDC *dc,
// arithmetics on wxColour, unfortunately) // arithmetics on wxColour, unfortunately)
wxColour colText; wxColour colText;
if ( highlighted ) if ( highlighted )
#ifdef __WXMAC__
{ {
if (m_owner->HasFocus() #ifdef __WXMAC__
#if !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON if ( hasFocus )
&& IsControlActive( (ControlRef)m_owner->GetHandle() )
#endif
)
colText = *wxWHITE; colText = *wxWHITE;
else else
colText = *wxBLACK; colText = *wxBLACK;
}
#else #else
colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
#endif #endif
}
else if ( attr && attr->HasTextColour() ) else if ( attr && attr->HasTextColour() )
colText = attr->GetTextColour(); colText = attr->GetTextColour();
else else
@@ -710,45 +715,25 @@ bool wxListLineData::SetAttributes(wxDC *dc,
dc->SetFont(font); dc->SetFont(font);
// bg colour // background
bool hasBgCol = attr && attr->HasBackgroundColour();
if ( highlighted || hasBgCol )
{
if ( highlighted ) if ( highlighted )
dc->SetBrush( *m_owner->GetHighlightBrush() );
else
dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
dc->SetPen( *wxTRANSPARENT_PEN );
return true;
}
return false;
}
void wxListLineData::Draw( wxDC *dc )
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_RET( node, wxT("no subitems at all??") );
bool highlighted = IsHighlighted();
wxListItemAttr *attr = GetAttr();
if ( SetAttributes(dc, attr, highlighted) )
{ {
int flags = 0; // Use the renderer method to ensure that the selected items use the
if (highlighted) // native look.
flags |= wxCONTROL_SELECTED; int flags = wxCONTROL_SELECTED;
if (m_owner->HasFocus() if ( hasFocus )
#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON
&& IsControlActive( (ControlRef)m_owner->GetHandle() )
#endif
)
flags |= wxCONTROL_FOCUSED; flags |= wxCONTROL_FOCUSED;
if (current)
flags |= wxCONTROL_CURRENT;
wxRendererNative::Get(). wxRendererNative::Get().
DrawItemSelectionRect( m_owner, *dc, m_gi->m_rectHighlight, flags ); DrawItemSelectionRect( m_owner, *dc, rectHL, flags );
}
else if ( attr && attr->HasBackgroundColour() )
{
// Draw the background using the items custom background colour.
dc->SetBrush(attr->GetBackgroundColour());
dc->SetPen(*wxTRANSPARENT_PEN);
dc->DrawRectangle(rectHL);
} }
// just for debugging to better see where the items are // just for debugging to better see where the items are
@@ -759,6 +744,14 @@ void wxListLineData::Draw( wxDC *dc )
dc->SetPen(*wxGREEN_PEN); dc->SetPen(*wxGREEN_PEN);
dc->DrawRectangle( m_gi->m_rectIcon ); dc->DrawRectangle( m_gi->m_rectIcon );
#endif #endif
}
void wxListLineData::Draw(wxDC *dc, bool current)
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_RET( node, wxT("no subitems at all??") );
ApplyAttributes(dc, m_gi->m_rectHighlight, IsHighlighted(), current);
wxListItemData *item = node->GetData(); wxListItemData *item = node->GetData();
if (item->HasImage()) if (item->HasImage())
@@ -788,18 +781,8 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
// TODO: later we should support setting different attributes for // TODO: later we should support setting different attributes for
// different columns - to do it, just add "col" argument to // different columns - to do it, just add "col" argument to
// GetAttr() and move these lines into the loop below // GetAttr() and move these lines into the loop below
wxListItemAttr *attr = GetAttr();
if ( SetAttributes(dc, attr, highlighted) ) ApplyAttributes(dc, rectHL, highlighted, current);
{
int flags = 0;
if (highlighted)
flags |= wxCONTROL_SELECTED;
if (m_owner->HasFocus())
flags |= wxCONTROL_FOCUSED;
if (current)
flags |= wxCONTROL_CURRENT;
wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, rectHL, flags );
}
wxCoord x = rect.x + HEADER_OFFSET_X, wxCoord x = rect.x + HEADER_OFFSET_X,
yMid = rect.y + rect.height/2; yMid = rect.y + rect.height/2;
@@ -2110,7 +2093,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
size_t count = GetItemCount(); size_t count = GetItemCount();
for ( size_t i = 0; i < count; i++ ) for ( size_t i = 0; i < count; i++ )
{ {
GetLine(i)->Draw( &dc ); GetLine(i)->Draw( &dc, i == m_current );
} }
} }