diff --git a/include/wx/renderer.h b/include/wx/renderer.h index da22e391cb..b51af32176 100644 --- a/include/wx/renderer.h +++ b/include/wx/renderer.h @@ -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, diff --git a/samples/render/render.cpp b/samples/render/render.cpp index 9ec39010ae..dd1a4bc6df 100644 --- a/samples/render/render.cpp +++ b/samples/render/render.cpp @@ -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; diff --git a/src/generic/renderg.cpp b/src/generic/renderg.cpp index 8425f08953..35a9da4974 100644 --- a/src/generic/renderg.cpp +++ b/src/generic/renderg.cpp @@ -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); } diff --git a/src/msw/renderer.cpp b/src/msw/renderer.cpp index ceff9adb1b..6cfdb37fab 100644 --- a/src/msw/renderer.cpp +++ b/src/msw/renderer.cpp @@ -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); diff --git a/src/osx/carbon/renderer.cpp b/src/osx/carbon/renderer.cpp index 71e9535c53..4bffa8402e 100644 --- a/src/osx/carbon/renderer.cpp +++ b/src/osx/carbon/renderer.cpp @@ -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);