mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-17 17:02:51 +08:00
Improve drawing wxListCtrl gird lines in dark mode
The grid lines are erased when custom drawing the sub-items, so the grid lines need to be redrawn after drawing the item. OnPaint() is not called after every custom draw (e.g. just hovering over a row will cause a custom draw but no paint), so it has to be drawn in the custom paint handler. Add a common function for drawing grid lines and reuse it on OnPaint().
This commit is contained in:
+55
-52
@@ -3254,6 +3254,44 @@ void HandleItemPostpaint(NMCUSTOMDRAW nmcd)
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGridLines(wxListCtrl* listctrl, int item, int gap = 0)
|
||||
{
|
||||
const bool drawHRules = listctrl->HasFlag(wxLC_HRULES);
|
||||
const bool drawVRules = listctrl->HasFlag(wxLC_VRULES);
|
||||
if ( !(drawHRules || drawVRules) )
|
||||
return;
|
||||
|
||||
wxWindowDC wdc(listctrl);
|
||||
HDC hdc = GetHdcOf(wdc.GetTempHDC());
|
||||
|
||||
RECT rc;
|
||||
wxGetListCtrlItemRect(GetHwndOf(listctrl), item, LVIR_BOUNDS, rc);
|
||||
|
||||
const wxColour penColour(wxSystemSettings::GetColour(wxMSWDarkMode::IsActive()
|
||||
? wxSYS_COLOUR_GRAYTEXT
|
||||
: wxSYS_COLOUR_3DLIGHT));
|
||||
COLORREF clrGrid = wxColourToRGB(penColour);
|
||||
|
||||
if ( drawHRules )
|
||||
{
|
||||
wxDrawHVLine(hdc, rc.left, rc.bottom, rc.right, rc.bottom, clrGrid, 1);
|
||||
}
|
||||
|
||||
if ( drawVRules )
|
||||
{
|
||||
for ( auto col : listctrl->GetColumnsOrder() )
|
||||
{
|
||||
wxRect rectSubItem;
|
||||
if ( !listctrl->GetSubItemRect(item, col, rectSubItem, wxLIST_RECT_BOUNDS) )
|
||||
continue;
|
||||
|
||||
// add 1 to match the header lines
|
||||
const int x = rectSubItem.GetRight() + 1;
|
||||
wxDrawHVLine(hdc, x, rc.top - gap, x, rc.bottom, clrGrid, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function is normally called only if we use custom colours, but it's
|
||||
// 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
|
||||
@@ -3357,6 +3395,8 @@ void HandleItemPaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD)
|
||||
::SetTextColor(hdc, colTextOld);
|
||||
}
|
||||
|
||||
DrawGridLines(listctrl, item);
|
||||
|
||||
HandleItemPostpaint(nmcd);
|
||||
}
|
||||
|
||||
@@ -3524,30 +3564,15 @@ void wxListCtrl::OnPaint(wxPaintEvent& event)
|
||||
dc.SetBrush(GetBackgroundColour());
|
||||
dc.DrawRectangle(lastRect.GetRight(), 0, clientSize.x - lastRect.GetRight(), lastRect.GetBottom());
|
||||
dc.DrawRectangle(0, lastRect.GetBottom(), clientSize.x, clientSize.y - lastRect.GetBottom());
|
||||
}
|
||||
|
||||
if ( !needToDraw )
|
||||
return;
|
||||
}
|
||||
|
||||
const wxColour penColour(wxSystemSettings::GetColour(wxMSWDarkMode::IsActive()
|
||||
? wxSYS_COLOUR_GRAYTEXT
|
||||
: wxSYS_COLOUR_3DLIGHT));
|
||||
wxPen pen(penColour);
|
||||
dc.SetPen(pen);
|
||||
dc.SetBrush(* wxTRANSPARENT_BRUSH);
|
||||
static const bool useDrawFix = wxApp::GetComCtl32Version() < 600;
|
||||
static const int gap = useDrawFix ? 2 : 0;
|
||||
|
||||
if (drawHRules)
|
||||
{
|
||||
wxRect itemRect;
|
||||
for ( long i = top; i <= bottom; i++ )
|
||||
{
|
||||
if (GetItemRect(i, itemRect))
|
||||
{
|
||||
const int cy = itemRect.GetBottom();
|
||||
dc.DrawLine(0, cy, clientSize.x, cy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (drawVRules)
|
||||
if ( drawVRules && useDrawFix )
|
||||
{
|
||||
wxRect topItemRect, bottomItemRect;
|
||||
GetItemRect(top, topItemRect);
|
||||
@@ -3575,40 +3600,18 @@ void wxListCtrl::OnPaint(wxPaintEvent& event)
|
||||
EVT_LIST_COL_DRAGGING and also set useDrawFix to false and gap
|
||||
to 2 (not 0).
|
||||
*/
|
||||
wxDCPenChanger changePen(dc, *wxTRANSPARENT_PEN);
|
||||
wxDCBrushChanger changeBrush(dc, GetBackgroundColour());
|
||||
|
||||
static const bool useDrawFix = wxApp::GetComCtl32Version() < 600;
|
||||
|
||||
static const int gap = useDrawFix ? 2 : 0;
|
||||
|
||||
if (useDrawFix)
|
||||
{
|
||||
wxDCPenChanger changePen(dc, *wxTRANSPARENT_PEN);
|
||||
wxDCBrushChanger changeBrush(dc, GetBackgroundColour());
|
||||
|
||||
dc.DrawRectangle(0, topItemRect.GetY() - gap,
|
||||
clientSize.GetWidth(), gap);
|
||||
}
|
||||
|
||||
const int numCols = GetColumnCount();
|
||||
wxVector<int> indexArray(numCols);
|
||||
if ( !ListView_GetColumnOrderArray(GetHwnd(),
|
||||
numCols,
|
||||
&indexArray[0]) )
|
||||
{
|
||||
wxFAIL_MSG( wxT("invalid column index array in OnPaint()") );
|
||||
return;
|
||||
}
|
||||
|
||||
int x = bottomItemRect.GetX();
|
||||
for (int col = 0; col < numCols; col++)
|
||||
{
|
||||
int colWidth = GetColumnWidth(indexArray[col]);
|
||||
x += colWidth ;
|
||||
dc.DrawLine(x-1, topItemRect.GetY() - gap,
|
||||
x-1, bottomItemRect.GetBottom());
|
||||
}
|
||||
dc.DrawRectangle(0, topItemRect.GetY() - gap,
|
||||
clientSize.GetWidth(), gap);
|
||||
}
|
||||
}
|
||||
|
||||
for ( long i = top; i <= bottom; i++ )
|
||||
{
|
||||
DrawGridLines(this, i, gap);
|
||||
}
|
||||
}
|
||||
|
||||
void wxListCtrl::OnCharHook(wxKeyEvent& event)
|
||||
|
||||
Reference in New Issue
Block a user