Merge branch 'renderer'

Preserve wxDC attributes (pen, brush, colours) in wxRenderer functions.

Also fix Explorer listview theme name in wxMSW renderer.

See https://github.com/wxWidgets/wxWidgets/pull/2412
This commit is contained in:
Vadim Zeitlin
2021-07-06 12:50:35 +01:00
5 changed files with 66 additions and 53 deletions

View File

@@ -178,6 +178,13 @@ public:
// drawing functions // drawing functions
// ----------------- // -----------------
/*
Note that all these functions don't, and shouldn't, change any
parameters of wxDC passed to them, i.e. pens, brushes or colours.
Their implementation must use wxDCXXXChanger classes instead of
calling wxDC::SetXXX() directly to ensure this.
*/
// draw the header control button (used by wxListCtrl) Returns optimal // draw the header control button (used by wxListCtrl) Returns optimal
// width for the label contents. // width for the label contents.
virtual int DrawHeaderButton(wxWindow *win, virtual int DrawHeaderButton(wxWindow *win,

View File

@@ -25,7 +25,6 @@
#include "wx/frame.h" #include "wx/frame.h"
#include "wx/dc.h" #include "wx/dc.h"
#include "wx/dcclient.h" #include "wx/dcclient.h"
#include "wx/dcgraph.h"
#include "wx/panel.h" #include "wx/panel.h"
#include "wx/menu.h" #include "wx/menu.h"
#include "wx/textdlg.h" #include "wx/textdlg.h"
@@ -38,6 +37,7 @@
#include "wx/apptrait.h" #include "wx/apptrait.h"
#include "wx/artprov.h" #include "wx/artprov.h"
#include "wx/renderer.h" #include "wx/renderer.h"
#include "wx/dcgraph.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// resources // resources
@@ -68,6 +68,7 @@ public:
{ {
wxDCBrushChanger setBrush(dc, *wxBLUE_BRUSH); wxDCBrushChanger setBrush(dc, *wxBLUE_BRUSH);
wxDCTextColourChanger setFgCol(dc, *wxWHITE); wxDCTextColourChanger setFgCol(dc, *wxWHITE);
wxDCTextBgModeChanger setBgMode(dc, wxBRUSHSTYLE_TRANSPARENT);
dc.DrawRoundedRectangle(rect, 5); dc.DrawRoundedRectangle(rect, 5);
wxString label; wxString label;

View File

@@ -277,7 +277,7 @@ wxRendererGeneric::DrawShadedRect(wxDC& dc,
const wxPen& pen2) const wxPen& pen2)
{ {
// draw the rectangle // draw the rectangle
dc.SetPen(pen1); wxDCPenChanger setPen(dc, pen1);
dc.DrawLine(rect->GetLeft(), rect->GetTop(), dc.DrawLine(rect->GetLeft(), rect->GetTop(),
rect->GetLeft(), rect->GetBottom()); rect->GetLeft(), rect->GetBottom());
dc.DrawLine(rect->GetLeft() + 1, rect->GetTop(), dc.DrawLine(rect->GetLeft() + 1, rect->GetTop(),
@@ -309,8 +309,8 @@ wxRendererGeneric::DrawHeaderButton(wxWindow* win,
w = rect.width, w = rect.width,
h = rect.height; h = rect.height;
dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE))); wxDCBrushChanger setBrush(dc, wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)));
dc.SetPen(*wxTRANSPARENT_PEN); wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
dc.DrawRectangle(rect); dc.DrawRectangle(rect);
dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.SetBrush(*wxTRANSPARENT_BRUSH);
@@ -353,7 +353,7 @@ wxRendererGeneric::DrawHeaderButtonContents(wxWindow *win,
params->m_selectionColour : wxColour(0x66, 0x66, 0x66); params->m_selectionColour : wxColour(0x66, 0x66, 0x66);
wxPen pen(c, penwidth); wxPen pen(c, penwidth);
pen.SetCap(wxCAP_BUTT); pen.SetCap(wxCAP_BUTT);
dc.SetPen(pen); wxDCPenChanger setPen(dc, pen);
dc.DrawLine(rect.x, y, rect.x + rect.width, y); dc.DrawLine(rect.x, y, rect.x + rect.width, y);
} }
@@ -453,9 +453,9 @@ wxRendererGeneric::DrawHeaderButtonContents(wxWindow *win,
wxString label( params->m_labelText ); wxString label( params->m_labelText );
dc.SetFont(font); wxDCFontChanger setFont(dc, font);
dc.SetTextForeground(clr); wxDCTextColourChanger setTextFg(dc, clr);
dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); wxDCTextBgModeChanger setBgMode(dc, wxBRUSHSTYLE_TRANSPARENT);
int tw, th, td; int tw, th, td;
dc.GetTextExtent( label, &tw, &th, &td); dc.GetTextExtent( label, &tw, &th, &td);
@@ -541,7 +541,7 @@ wxRendererGeneric::DrawTreeItemButton(wxWindow * WXUNUSED(win),
// half of the length of the horz lines in "-" and "+" // half of the length of the horz lines in "-" and "+"
const wxCoord halfWidth = rect.width/2 - 2; const wxCoord halfWidth = rect.width/2 - 2;
dc.SetPen(*wxBLACK_PEN); wxDCPenChanger setPen(dc, *wxBLACK_PEN);
dc.DrawLine(xMiddle - halfWidth, yMiddle, dc.DrawLine(xMiddle - halfWidth, yMiddle,
xMiddle + halfWidth + 1, yMiddle); xMiddle + halfWidth + 1, yMiddle);
@@ -635,12 +635,12 @@ wxRendererGeneric::DrawSplitterSash(wxWindow *win,
offset = 1; offset = 1;
} }
dc.SetPen(*wxTRANSPARENT_PEN); wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
if ( win->HasFlag(wxSP_3DSASH) ) if ( win->HasFlag(wxSP_3DSASH) )
{ {
// Draw the 3D sash // Draw the 3D sash
dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE))); wxDCBrushChanger setBrush(dc, wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)));
dc.DrawRectangle(position + 2, 0, 3, h); dc.DrawRectangle(position + 2, 0, 3, h);
dc.SetPen(m_penLightGrey); dc.SetPen(m_penLightGrey);
@@ -658,7 +658,7 @@ wxRendererGeneric::DrawSplitterSash(wxWindow *win,
else else
{ {
// Draw a flat sash // Draw a flat sash
dc.SetBrush(wxBrush(win->GetBackgroundColour())); wxDCBrushChanger setBrush(dc, wxBrush(win->GetBackgroundColour()));
dc.DrawRectangle(position, 0, 3, h); dc.DrawRectangle(position, 0, 3, h);
} }
} }
@@ -697,8 +697,8 @@ wxRendererGeneric::DrawDropArrow(wxWindow *win,
wxPoint(rectMid + arrowHalf, arrowTopY), wxPoint(rectMid + arrowHalf, arrowTopY),
wxPoint(rectMid, arrowTopY + arrowHalf) wxPoint(rectMid, arrowTopY + arrowHalf)
}; };
dc.SetBrush(wxBrush(win->GetForegroundColour())); wxDCBrushChanger setBrush(dc, wxBrush(win->GetForegroundColour()));
dc.SetPen(wxPen(win->GetForegroundColour())); wxDCPenChanger setPen(dc, wxPen(win->GetForegroundColour()));
dc.DrawPolygon(WXSIZEOF(pt), pt, rect.x, rect.y); dc.DrawPolygon(WXSIZEOF(pt), pt, rect.x, rect.y);
} }
@@ -708,8 +708,8 @@ wxRendererGeneric::DrawCheckBox(wxWindow *WXUNUSED(win),
const wxRect& rect, const wxRect& rect,
int flags) int flags)
{ {
dc.SetPen(*(flags & wxCONTROL_DISABLED ? wxGREY_PEN : wxBLACK_PEN)); wxDCPenChanger setPen(dc, *(flags & wxCONTROL_DISABLED ? wxGREY_PEN : wxBLACK_PEN));
dc.SetBrush( *wxTRANSPARENT_BRUSH ); wxDCBrushChanger setBrush(dc, *wxTRANSPARENT_BRUSH);
dc.DrawRectangle(rect); dc.DrawRectangle(rect);
if ( flags & wxCONTROL_CHECKED ) if ( flags & wxCONTROL_CHECKED )
@@ -724,7 +724,7 @@ wxRendererGeneric::DrawCheckMark(wxWindow *WXUNUSED(win),
const wxRect& rect, const wxRect& rect,
int flags) int flags)
{ {
dc.SetPen(*(flags & wxCONTROL_DISABLED ? wxGREY_PEN : wxBLACK_PEN)); wxDCPenChanger setPen(dc, *(flags & wxCONTROL_DISABLED ? wxGREY_PEN : wxBLACK_PEN));
dc.DrawCheckMark(rect); dc.DrawCheckMark(rect);
} }
@@ -758,8 +758,8 @@ wxRendererGeneric::DrawPushButton(wxWindow *win,
wxColour bgCol = flags & wxCONTROL_DISABLED ? wxColour bgCol = flags & wxCONTROL_DISABLED ?
wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE) : wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE) :
win->GetBackgroundColour(); win->GetBackgroundColour();
dc.SetBrush(wxBrush(bgCol)); wxDCBrushChanger setBrush(dc, wxBrush(bgCol));
dc.SetPen(wxPen(bgCol)); wxDCPenChanger setPen(dc, wxPen(bgCol));
dc.DrawRectangle(rect); dc.DrawRectangle(rect);
} }
@@ -789,8 +789,8 @@ wxRendererGeneric::DrawCollapseButton(wxWindow *win,
pt[2] = wxPoint(arrowTopY, rectMid + arrowHalf); pt[2] = wxPoint(arrowTopY, rectMid + arrowHalf);
} }
dc.SetBrush(wxBrush(win->GetForegroundColour())); wxDCBrushChanger setBrush(dc, wxBrush(win->GetForegroundColour()));
dc.SetPen(wxPen(win->GetForegroundColour())); wxDCPenChanger setPen(dc, wxPen(win->GetForegroundColour()));
dc.DrawPolygon(WXSIZEOF(pt), pt, rect.x, rect.y); dc.DrawPolygon(WXSIZEOF(pt), pt, rect.x, rect.y);
} }
@@ -822,13 +822,11 @@ wxRendererGeneric::DrawItemSelectionRect(wxWindow * WXUNUSED(win),
brush = *wxTRANSPARENT_BRUSH; brush = *wxTRANSPARENT_BRUSH;
} }
dc.SetBrush(brush); wxDCBrushChanger setBrush(dc, brush);
bool drawFocusRect = (flags & wxCONTROL_CURRENT) && (flags & wxCONTROL_FOCUSED); bool drawFocusRect = (flags & wxCONTROL_CURRENT) && (flags & wxCONTROL_FOCUSED);
if ( drawFocusRect && !(flags & wxCONTROL_CELL) ) bool blackPen = drawFocusRect && !(flags & wxCONTROL_CELL);
dc.SetPen( *wxBLACK_PEN ); wxDCPenChanger setPen(dc, *(blackPen ? wxBLACK_PEN : wxTRANSPARENT_PEN));
else
dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle( rect ); dc.DrawRectangle( rect );
@@ -854,7 +852,7 @@ wxRendererGeneric::DrawFocusRect(wxWindow* WXUNUSED(win), wxDC& dc, const wxRect
x2 = rect.GetRight(), x2 = rect.GetRight(),
y2 = rect.GetBottom(); y2 = rect.GetBottom();
dc.SetPen(m_penBlack); wxDCPenChanger setPen(dc, m_penBlack);
#ifdef __WXMAC__ #ifdef __WXMAC__
dc.SetLogicalFunction(wxCOPY); dc.SetLogicalFunction(wxCOPY);
@@ -913,8 +911,8 @@ void wxRendererGeneric::DrawTextCtrl(wxWindow* WXUNUSED(win),
bdr = *wxBLACK; bdr = *wxBLACK;
} }
dc.SetPen(bdr); wxDCPenChanger setPen(dc, bdr);
dc.SetBrush(fill); wxDCBrushChanger setBrush(dc, fill);
dc.DrawRectangle(rect); dc.DrawRectangle(rect);
} }
@@ -971,8 +969,8 @@ void wxRendererGeneric::DrawGauge(wxWindow* win,
progRect.width = wxMulDivInt32(progRect.width, value, max); progRect.width = wxMulDivInt32(progRect.width, value, max);
} }
dc.SetBrush(colBar); wxDCBrushChanger setBrush(dc, colBar);
dc.SetPen(*wxTRANSPARENT_PEN); wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
dc.DrawRectangle(progRect); dc.DrawRectangle(progRect);
} }
@@ -1005,9 +1003,10 @@ wxRendererGeneric::DrawItemText(wxWindow* WXUNUSED(win),
// Draw text taking care not to change its colour if it had been set by the // Draw text taking care not to change its colour if it had been set by the
// caller for a normal item to allow having items in non-default colours. // caller for a normal item to allow having items in non-default colours.
wxDCTextColourChanger setTextFg(dc);
if ( textColour.IsOk() ) if ( textColour.IsOk() )
dc.SetTextForeground(textColour); setTextFg.Set(textColour);
dc.SetTextBackground(wxTransparentColour); wxDCTextBgColourChanger setTextBg(dc, wxTransparentColour);
dc.DrawLabel(paintText, rect, align); dc.DrawLabel(paintText, rect, align);
} }

View File

@@ -380,8 +380,8 @@ void wxRendererMSWBase::DrawItemSelectionRect(wxWindow *win,
brush = *wxTRANSPARENT_BRUSH; brush = *wxTRANSPARENT_BRUSH;
} }
dc.SetBrush(brush); wxDCBrushChanger setBrush(dc, brush);
dc.SetPen(*wxTRANSPARENT_PEN); wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
dc.DrawRectangle( rect ); dc.DrawRectangle( rect );
if ((flags & wxCONTROL_FOCUSED) && (flags & wxCONTROL_CURRENT)) if ((flags & wxCONTROL_FOCUSED) && (flags & wxCONTROL_CURRENT))
@@ -1011,7 +1011,7 @@ wxRendererXP::DrawItemSelectionRect(wxWindow *win,
const wxRect& rect, const wxRect& rect,
int flags) int flags)
{ {
wxUxThemeHandle hTheme(win, L"LISTVIEW"); wxUxThemeHandle hTheme(win, L"EXPLORER::LISTVIEW");
const int itemState = GetListItemState(flags); const int itemState = GetListItemState(flags);
@@ -1038,7 +1038,7 @@ void wxRendererXP::DrawItemText(wxWindow* win,
int flags, int flags,
wxEllipsizeMode ellipsizeMode) wxEllipsizeMode ellipsizeMode)
{ {
wxUxThemeHandle hTheme(win, L"LISTVIEW"); wxUxThemeHandle hTheme(win, L"EXPLORER::LISTVIEW");
const int itemState = GetListItemState(flags); const int itemState = GetListItemState(flags);
@@ -1165,8 +1165,8 @@ void wxRendererXP::DrawTextCtrl(wxWindow* win,
etsState, TMT_BORDERCOLOR, &cref); etsState, TMT_BORDERCOLOR, &cref);
bdr = wxRGBToColour(cref); bdr = wxRGBToColour(cref);
dc.SetPen( bdr ); wxDCPenChanger setPen(dc, bdr);
dc.SetBrush( fill ); wxDCBrushChanger setBrush(dc, fill);
dc.DrawRectangle(rect); dc.DrawRectangle(rect);
} }
@@ -1266,8 +1266,8 @@ wxRendererXP::DrawSplitterSash(wxWindow *win,
{ {
if ( !win->HasFlag(wxSP_NO_XP_THEME) ) if ( !win->HasFlag(wxSP_NO_XP_THEME) )
{ {
dc.SetPen(*wxTRANSPARENT_PEN); wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE))); wxDCBrushChanger setBrush(dc, wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
if ( orient == wxVERTICAL ) if ( orient == wxVERTICAL )
{ {
dc.DrawRectangle(position, 0, SASH_WIDTH, size.y); dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);

View File

@@ -178,7 +178,7 @@ int wxRendererMac::DrawHeaderButton( wxWindow *win,
const wxCoord w = rect.width; const wxCoord w = rect.width;
const wxCoord h = rect.height; const wxCoord h = rect.height;
dc.SetBrush( *wxTRANSPARENT_BRUSH ); wxDCBrushChanger setBrush(dc, *wxTRANSPARENT_BRUSH);
HIRect headerRect = CGRectMake( x, y, w, h ); HIRect headerRect = CGRectMake( x, y, w, h );
if ( !wxHasCGContext(win, dc) ) if ( !wxHasCGContext(win, dc) )
@@ -267,7 +267,7 @@ void wxRendererMac::DrawTreeItemButton( wxWindow *win,
const wxCoord w = rect.width; const wxCoord w = rect.width;
const wxCoord h = rect.height; const wxCoord h = rect.height;
dc.SetBrush( *wxTRANSPARENT_BRUSH ); wxDCBrushChanger setBrush(dc, *wxTRANSPARENT_BRUSH);
HIRect headerRect = CGRectMake( x, y, w, h ); HIRect headerRect = CGRectMake( x, y, w, h );
if ( !wxHasCGContext(win, dc) ) if ( !wxHasCGContext(win, dc) )
@@ -415,8 +415,8 @@ wxRendererMac::DrawItemSelectionRect(wxWindow * WXUNUSED(win),
: kThemeBrushSecondaryHighlightColor ) ); : kThemeBrushSecondaryHighlightColor ) );
wxBrush selBrush( col ); wxBrush selBrush( col );
dc.SetPen( *wxTRANSPARENT_PEN ); wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
dc.SetBrush( selBrush ); wxDCBrushChanger setBrush(dc, selBrush);
dc.DrawRectangle( rect ); dc.DrawRectangle( rect );
} }
@@ -435,7 +435,7 @@ wxRendererMac::DrawMacThemeButton(wxWindow *win,
const wxCoord w = rect.width; const wxCoord w = rect.width;
const wxCoord h = rect.height; const wxCoord h = rect.height;
dc.SetBrush( *wxTRANSPARENT_BRUSH ); wxDCBrushChanger setBrush(dc, *wxTRANSPARENT_BRUSH);
HIRect headerRect = CGRectMake( x, y, w, h ); HIRect headerRect = CGRectMake( x, y, w, h );
if ( !wxHasCGContext(win, dc) ) if ( !wxHasCGContext(win, dc) )
@@ -681,10 +681,12 @@ void wxRendererMac::DrawTextCtrl(wxWindow* win, wxDC& dc,
const wxCoord w = rect.width; const wxCoord w = rect.width;
const wxCoord h = rect.height; const wxCoord h = rect.height;
dc.SetBrush( *wxWHITE_BRUSH ); wxDCBrushChanger setBrush(dc, *wxWHITE_BRUSH);
dc.SetPen( *wxTRANSPARENT_PEN ); wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
dc.DrawRectangle(rect); dc.DrawRectangle(rect);
// Note that calling SetBrush() here is fine as we already have
// wxDCBrushChanger above, so the original brush will get restored.
dc.SetBrush( *wxTRANSPARENT_BRUSH ); dc.SetBrush( *wxTRANSPARENT_BRUSH );
HIRect hiRect = CGRectMake( x, y, w, h ); HIRect hiRect = CGRectMake( x, y, w, h );
@@ -733,19 +735,20 @@ void wxRendererMac::DrawTitleBarBitmap(wxWindow *win,
// The following hard coded RGB values are based the close button in // The following hard coded RGB values are based the close button in
// XCode 6+ welcome screen // XCode 6+ welcome screen
bool drawCircle; bool drawCircle;
wxColour circleBorderCol, circleInteriorCol;
if ( flags & wxCONTROL_PRESSED ) if ( flags & wxCONTROL_PRESSED )
{ {
drawCircle = true; drawCircle = true;
glyphColor = wxColour(104, 104, 104); glyphColor = wxColour(104, 104, 104);
dc.SetPen(wxPen(wxColour(70, 70, 71), 1)); circleBorderCol = wxColour(70, 70, 71);
dc.SetBrush(wxColour(78, 78, 78)); circleInteriorCol = wxColour(78, 78, 78);
} }
else if ( flags & wxCONTROL_CURRENT ) else if ( flags & wxCONTROL_CURRENT )
{ {
drawCircle = true; drawCircle = true;
glyphColor = *wxWHITE; glyphColor = *wxWHITE;
dc.SetPen(wxPen(wxColour(163, 165, 166), 1)); circleBorderCol = wxColour(163, 165, 166);
dc.SetBrush(wxColour(182, 184, 187)); circleInteriorCol = wxColour(182, 184, 187);
} }
else else
{ {
@@ -755,13 +758,16 @@ void wxRendererMac::DrawTitleBarBitmap(wxWindow *win,
if ( drawCircle ) if ( drawCircle )
{ {
wxDCPenChanger setPen(dc, circleBorderCol);
wxDCBrushChanger setBrush(dc, circleInteriorCol);
wxRect circleRect(rect); wxRect circleRect(rect);
circleRect.Deflate(2); circleRect.Deflate(2);
dc.DrawEllipse(circleRect); dc.DrawEllipse(circleRect);
} }
dc.SetPen(wxPen(glyphColor, 1)); wxDCPenChanger setPen(dc, glyphColor);
wxRect centerRect(rect); wxRect centerRect(rect);
centerRect.Deflate(5); centerRect.Deflate(5);