From: Vadim Zeitlin Date: Tue, 14 Sep 2010 13:18:48 +0000 (+0000) Subject: Fix drawing of items with custom background in wxGenericListCtrl. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/ed84dc74d9bd041c9c446cb87e598c2c4df0fa2f 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 --- diff --git a/include/wx/generic/private/listctrl.h b/include/wx/generic/private/listctrl.h index cacf1bdcb5..4965aafbfb 100644 --- a/include/wx/generic/private/listctrl.h +++ b/include/wx/generic/private/listctrl.h @@ -275,9 +275,10 @@ public: } // 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, const wxRect& rect, const wxRect& rectHL, @@ -291,11 +292,12 @@ private: // get the mode (i.e. style) of the list control inline int GetMode() const; - // prepare the DC for drawing with these item's attributes, return true if - // we need to draw the items background to highlight it, false otherwise - bool SetAttributes(wxDC *dc, - const wxListItemAttr *attr, - bool highlight); + // Apply this item attributes to the given DC: set the text font and colour + // and also erase the background appropriately. + void ApplyAttributes(wxDC *dc, + const wxRect& rectHL, + bool highlighted, + bool current); // 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 diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index c9915b198e..008ee79078 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -667,11 +667,20 @@ void wxListLineData::SetAttr(wxListItemAttr *attr) item->SetAttr(attr); } -bool wxListLineData::SetAttributes(wxDC *dc, - const wxListItemAttr *attr, - bool highlighted) +void wxListLineData::ApplyAttributes(wxDC *dc, + const wxRect& rectHL, + 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 @@ -680,20 +689,16 @@ bool wxListLineData::SetAttributes(wxDC *dc, // arithmetics on wxColour, unfortunately) wxColour colText; if ( highlighted ) -#ifdef __WXMAC__ { - if (m_owner->HasFocus() -#if !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON - && IsControlActive( (ControlRef)m_owner->GetHandle() ) -#endif - ) +#ifdef __WXMAC__ + if ( hasFocus ) colText = *wxWHITE; else colText = *wxBLACK; - } #else colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); #endif + } else if ( attr && attr->HasTextColour() ) colText = attr->GetTextColour(); else @@ -710,45 +715,25 @@ bool wxListLineData::SetAttributes(wxDC *dc, 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(), 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) ) + // background + if ( highlighted ) { - int flags = 0; - if (highlighted) - flags |= wxCONTROL_SELECTED; - if (m_owner->HasFocus() -#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON - && IsControlActive( (ControlRef)m_owner->GetHandle() ) -#endif - ) + // Use the renderer method to ensure that the selected items use the + // native look. + int flags = wxCONTROL_SELECTED; + if ( hasFocus ) flags |= wxCONTROL_FOCUSED; + if (current) + flags |= wxCONTROL_CURRENT; 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 @@ -759,6 +744,14 @@ void wxListLineData::Draw( wxDC *dc ) dc->SetPen(*wxGREEN_PEN); dc->DrawRectangle( m_gi->m_rectIcon ); #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(); if (item->HasImage()) @@ -788,18 +781,8 @@ void wxListLineData::DrawInReportMode( wxDC *dc, // 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) ) - { - 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 ); - } + + ApplyAttributes(dc, rectHL, highlighted, current); wxCoord x = rect.x + HEADER_OFFSET_X, yMid = rect.y + rect.height/2; @@ -2110,7 +2093,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) size_t count = GetItemCount(); for ( size_t i = 0; i < count; i++ ) { - GetLine(i)->Draw( &dc ); + GetLine(i)->Draw( &dc, i == m_current ); } }