mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-17 17:02:51 +08:00
Use correct column attributes when drawing wxListCtrl
When a column is custom drawn, it wrongly used the wxItemAttr of the column being updated to redraw all columns. Fix this by requesting the column attributes of each column that is drawn. See #25633. Closes #25962.
This commit is contained in:
committed by
Vadim Zeitlin
parent
dc60fd3bcc
commit
3842352b21
@@ -379,6 +379,11 @@ public:
|
||||
WXWPARAM wParam,
|
||||
WXLPARAM lParam) override;
|
||||
|
||||
// This function is only used by the implementation and is not part of the
|
||||
// public API.
|
||||
wxItemAttr* MSWGetItemColumnAttr(long item, long column) const
|
||||
{ return DoGetItemColumnAttr(item, column); }
|
||||
|
||||
protected:
|
||||
// common part of all ctors
|
||||
void Init();
|
||||
|
||||
+48
-58
@@ -3258,9 +3258,7 @@ void HandleItemPostpaint(NMCUSTOMDRAW nmcd)
|
||||
// also called when using dark mode as we have to draw the selected item
|
||||
// ourselves when using it, and if we do this, we have to paint all the items
|
||||
// for consistency.
|
||||
//
|
||||
// pLVCD->clrText and clrTextBk should contain the colours to use
|
||||
void HandleItemPaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
|
||||
void HandleItemPaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD)
|
||||
{
|
||||
NMCUSTOMDRAW& nmcd = pLVCD->nmcd; // just a shortcut
|
||||
|
||||
@@ -3301,21 +3299,9 @@ void HandleItemPaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
|
||||
|
||||
HDC hdc = nmcd.hdc;
|
||||
RECT rc = GetCustomDrawnItemRect(nmcd);
|
||||
|
||||
COLORREF clrFullBG;
|
||||
if ( nmcd.uItemState & CDIS_SELECTED )
|
||||
{
|
||||
pLVCD->clrText = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
|
||||
pLVCD->clrTextBk = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
|
||||
|
||||
clrFullBG = pLVCD->clrTextBk;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrFullBG = wxColourToRGB(listctrl->GetBackgroundColour());
|
||||
}
|
||||
|
||||
COLORREF colTextOld = ::SetTextColor(hdc, pLVCD->clrText);
|
||||
COLORREF clrFullBG = wxColourToRGB((nmcd.uItemState & CDIS_SELECTED)
|
||||
? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)
|
||||
: listctrl->GetBackgroundColour());
|
||||
|
||||
// clear the entire row with the listctrl's bg colour
|
||||
// otherwise, it'd keep the hover color but only for the regions
|
||||
@@ -3340,57 +3326,55 @@ void HandleItemPaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
|
||||
RECT rcSubItem;
|
||||
wxCopyRectToRECT(rectSubItem, rcSubItem);
|
||||
|
||||
HandleSubItemPrepaint(listctrl, pLVCD, hfont, rcSubItem);
|
||||
}
|
||||
|
||||
::SetTextColor(hdc, colTextOld);
|
||||
|
||||
HandleItemPostpaint(nmcd);
|
||||
}
|
||||
|
||||
WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
|
||||
LPNMLVCUSTOMDRAW pLVCD,
|
||||
wxItemAttr *attr)
|
||||
{
|
||||
if ( wxMSWDarkMode::IsActive() )
|
||||
{
|
||||
// We need to always paint selected items ourselves as they come
|
||||
// out completely wrong in DarkMode_Explorer theme, see the comment
|
||||
// before MSWGetDarkModeSupport().
|
||||
wxItemAttr* attr = listctrl->MSWGetItemColumnAttr(item, col);
|
||||
wxFont font;
|
||||
|
||||
if ( attr && attr->HasFont() )
|
||||
{
|
||||
font = attr->GetFont();
|
||||
font.WXAdjustToPPI(listctrl->GetDPI());
|
||||
}
|
||||
HFONT hfont = font.IsOk() ? GetHfontOf(font) : nullptr;
|
||||
|
||||
pLVCD->clrText = attr && attr->HasTextColour()
|
||||
? wxColourToRGB(attr->GetTextColour())
|
||||
: wxColourToRGB(listctrl->GetTextColour());
|
||||
pLVCD->clrTextBk = attr && attr->HasBackgroundColour()
|
||||
? wxColourToRGB(attr->GetBackgroundColour())
|
||||
: wxColourToRGB(listctrl->GetBackgroundColour());
|
||||
if ( nmcd.uItemState & CDIS_SELECTED )
|
||||
{
|
||||
pLVCD->clrText = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
|
||||
pLVCD->clrTextBk = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
|
||||
}
|
||||
else
|
||||
{
|
||||
pLVCD->clrText = attr && attr->HasTextColour()
|
||||
? wxColourToRGB(attr->GetTextColour())
|
||||
: wxColourToRGB(listctrl->GetTextColour());
|
||||
pLVCD->clrTextBk = attr && attr->HasBackgroundColour()
|
||||
? wxColourToRGB(attr->GetBackgroundColour())
|
||||
: wxColourToRGB(listctrl->GetBackgroundColour());
|
||||
}
|
||||
|
||||
HandleItemPaint(listctrl, pLVCD, font.IsOk() ? GetHfontOf(font) : nullptr);
|
||||
COLORREF colTextOld = ::SetTextColor(hdc, pLVCD->clrText);
|
||||
|
||||
HandleSubItemPrepaint(listctrl, pLVCD, hfont, rcSubItem);
|
||||
|
||||
::SetTextColor(hdc, colTextOld);
|
||||
}
|
||||
|
||||
HandleItemPostpaint(nmcd);
|
||||
}
|
||||
|
||||
WXLPARAM HandleItemPrepaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD)
|
||||
{
|
||||
if ( wxMSWDarkMode::IsActive() )
|
||||
{
|
||||
HandleItemPaint(listctrl, pLVCD);
|
||||
return CDRF_SKIPDEFAULT;
|
||||
}
|
||||
|
||||
wxItemAttr* attr = listctrl->MSWGetItemColumnAttr(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem);
|
||||
if ( !attr )
|
||||
{
|
||||
// nothing to do for this item
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
||||
|
||||
|
||||
// set the colours to use for text drawing
|
||||
pLVCD->clrText = attr->HasTextColour()
|
||||
? wxColourToRGB(attr->GetTextColour())
|
||||
: wxColourToRGB(listctrl->GetTextColour());
|
||||
pLVCD->clrTextBk = attr->HasBackgroundColour()
|
||||
? wxColourToRGB(attr->GetBackgroundColour())
|
||||
: wxColourToRGB(listctrl->GetBackgroundColour());
|
||||
|
||||
// select the font if non default one is specified
|
||||
if ( attr->HasFont() )
|
||||
{
|
||||
@@ -3402,7 +3386,7 @@ WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
|
||||
// with recent comctl32.dll versions (5 and 6, it uses to work with
|
||||
// 4.something) so we have to draw the item entirely ourselves in
|
||||
// this case
|
||||
HandleItemPaint(listctrl, pLVCD, GetHfontOf(font));
|
||||
HandleItemPaint(listctrl, pLVCD);
|
||||
return CDRF_SKIPDEFAULT;
|
||||
}
|
||||
|
||||
@@ -3420,11 +3404,17 @@ WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
|
||||
// lucky as HandleItemPaint() doesn't result in the same appearance as with
|
||||
// the system theme, so we should avoid using it in this case to ensure
|
||||
// that all items appear consistently.
|
||||
if ( listctrl->IsSystemThemeDisabled() &&
|
||||
pLVCD->clrTextBk == ::GetSysColor(COLOR_BTNFACE) )
|
||||
if ( listctrl->IsSystemThemeDisabled() )
|
||||
{
|
||||
HandleItemPaint(listctrl, pLVCD, nullptr);
|
||||
return CDRF_SKIPDEFAULT;
|
||||
COLORREF bgCol = attr->HasBackgroundColour()
|
||||
? wxColourToRGB(attr->GetBackgroundColour())
|
||||
: wxColourToRGB(listctrl->GetBackgroundColour());
|
||||
|
||||
if ( bgCol == ::GetSysColor(COLOR_BTNFACE) )
|
||||
{
|
||||
HandleItemPaint(listctrl, pLVCD);
|
||||
return CDRF_SKIPDEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
return CDRF_DODEFAULT;
|
||||
@@ -3464,7 +3454,7 @@ WXLPARAM wxListCtrl::OnCustomDraw(WXLPARAM lParam)
|
||||
if ( column < 0 || column >= GetColumnCount() )
|
||||
break;
|
||||
|
||||
return HandleItemPrepaint(this, pLVCD, DoGetItemColumnAttr(item, column));
|
||||
return HandleItemPrepaint(this, pLVCD);
|
||||
}
|
||||
|
||||
return CDRF_DODEFAULT;
|
||||
|
||||
Reference in New Issue
Block a user