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
// -----------------
/*
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
// width for the label contents.
virtual int DrawHeaderButton(wxWindow *win,

View File

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

View File

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

View File

@@ -380,8 +380,8 @@ void wxRendererMSWBase::DrawItemSelectionRect(wxWindow *win,
brush = *wxTRANSPARENT_BRUSH;
}
dc.SetBrush(brush);
dc.SetPen(*wxTRANSPARENT_PEN);
wxDCBrushChanger setBrush(dc, brush);
wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
dc.DrawRectangle( rect );
if ((flags & wxCONTROL_FOCUSED) && (flags & wxCONTROL_CURRENT))
@@ -1011,7 +1011,7 @@ wxRendererXP::DrawItemSelectionRect(wxWindow *win,
const wxRect& rect,
int flags)
{
wxUxThemeHandle hTheme(win, L"LISTVIEW");
wxUxThemeHandle hTheme(win, L"EXPLORER::LISTVIEW");
const int itemState = GetListItemState(flags);
@@ -1038,7 +1038,7 @@ void wxRendererXP::DrawItemText(wxWindow* win,
int flags,
wxEllipsizeMode ellipsizeMode)
{
wxUxThemeHandle hTheme(win, L"LISTVIEW");
wxUxThemeHandle hTheme(win, L"EXPLORER::LISTVIEW");
const int itemState = GetListItemState(flags);
@@ -1165,8 +1165,8 @@ void wxRendererXP::DrawTextCtrl(wxWindow* win,
etsState, TMT_BORDERCOLOR, &cref);
bdr = wxRGBToColour(cref);
dc.SetPen( bdr );
dc.SetBrush( fill );
wxDCPenChanger setPen(dc, bdr);
wxDCBrushChanger setBrush(dc, fill);
dc.DrawRectangle(rect);
}
@@ -1266,8 +1266,8 @@ wxRendererXP::DrawSplitterSash(wxWindow *win,
{
if ( !win->HasFlag(wxSP_NO_XP_THEME) )
{
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
wxDCBrushChanger setBrush(dc, wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
if ( orient == wxVERTICAL )
{
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 h = rect.height;
dc.SetBrush( *wxTRANSPARENT_BRUSH );
wxDCBrushChanger setBrush(dc, *wxTRANSPARENT_BRUSH);
HIRect headerRect = CGRectMake( x, y, w, h );
if ( !wxHasCGContext(win, dc) )
@@ -267,7 +267,7 @@ void wxRendererMac::DrawTreeItemButton( wxWindow *win,
const wxCoord w = rect.width;
const wxCoord h = rect.height;
dc.SetBrush( *wxTRANSPARENT_BRUSH );
wxDCBrushChanger setBrush(dc, *wxTRANSPARENT_BRUSH);
HIRect headerRect = CGRectMake( x, y, w, h );
if ( !wxHasCGContext(win, dc) )
@@ -415,8 +415,8 @@ wxRendererMac::DrawItemSelectionRect(wxWindow * WXUNUSED(win),
: kThemeBrushSecondaryHighlightColor ) );
wxBrush selBrush( col );
dc.SetPen( *wxTRANSPARENT_PEN );
dc.SetBrush( selBrush );
wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
wxDCBrushChanger setBrush(dc, selBrush);
dc.DrawRectangle( rect );
}
@@ -435,7 +435,7 @@ wxRendererMac::DrawMacThemeButton(wxWindow *win,
const wxCoord w = rect.width;
const wxCoord h = rect.height;
dc.SetBrush( *wxTRANSPARENT_BRUSH );
wxDCBrushChanger setBrush(dc, *wxTRANSPARENT_BRUSH);
HIRect headerRect = CGRectMake( x, y, w, h );
if ( !wxHasCGContext(win, dc) )
@@ -681,10 +681,12 @@ void wxRendererMac::DrawTextCtrl(wxWindow* win, wxDC& dc,
const wxCoord w = rect.width;
const wxCoord h = rect.height;
dc.SetBrush( *wxWHITE_BRUSH );
dc.SetPen( *wxTRANSPARENT_PEN );
wxDCBrushChanger setBrush(dc, *wxWHITE_BRUSH);
wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
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 );
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
// XCode 6+ welcome screen
bool drawCircle;
wxColour circleBorderCol, circleInteriorCol;
if ( flags & wxCONTROL_PRESSED )
{
drawCircle = true;
glyphColor = wxColour(104, 104, 104);
dc.SetPen(wxPen(wxColour(70, 70, 71), 1));
dc.SetBrush(wxColour(78, 78, 78));
circleBorderCol = wxColour(70, 70, 71);
circleInteriorCol = wxColour(78, 78, 78);
}
else if ( flags & wxCONTROL_CURRENT )
{
drawCircle = true;
glyphColor = *wxWHITE;
dc.SetPen(wxPen(wxColour(163, 165, 166), 1));
dc.SetBrush(wxColour(182, 184, 187));
circleBorderCol = wxColour(163, 165, 166);
circleInteriorCol = wxColour(182, 184, 187);
}
else
{
@@ -755,13 +758,16 @@ void wxRendererMac::DrawTitleBarBitmap(wxWindow *win,
if ( drawCircle )
{
wxDCPenChanger setPen(dc, circleBorderCol);
wxDCBrushChanger setBrush(dc, circleInteriorCol);
wxRect circleRect(rect);
circleRect.Deflate(2);
dc.DrawEllipse(circleRect);
}
dc.SetPen(wxPen(glyphColor, 1));
wxDCPenChanger setPen(dc, glyphColor);
wxRect centerRect(rect);
centerRect.Deflate(5);