diff --git a/include/wx/renderer.h b/include/wx/renderer.h index 173ae122f9..d854007e59 100644 --- a/include/wx/renderer.h +++ b/include/wx/renderer.h @@ -260,6 +260,17 @@ public: const wxRect& rect, int flags = 0) = 0; + // draw collapse button + // + // flags may use wxCONTROL_CHECKED, wxCONTROL_UNDETERMINED and wxCONTROL_CURRENT + virtual void DrawCollapseButton(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0) = 0; + + // Returns the default size of a collapse button + virtual wxSize GetCollapseButtonSize(wxWindow *win, wxDC& dc) = 0; + // draw rectangle indicating that an item in e.g. a list control // has been selected or focused // @@ -470,6 +481,15 @@ public: int flags = 0) { m_rendererNative.DrawPushButton( win, dc, rect, flags ); } + virtual void DrawCollapseButton(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0) + { m_rendererNative.DrawCollapseButton(win, dc, rect, flags); } + + virtual wxSize GetCollapseButtonSize(wxWindow *win, wxDC& dc) + { return m_rendererNative.GetCollapseButtonSize(win, dc); } + virtual void DrawItemSelectionRect(wxWindow *win, wxDC& dc, const wxRect& rect, diff --git a/interface/wx/renderer.h b/interface/wx/renderer.h index 37eb17b260..3ee7e7ae3f 100644 --- a/interface/wx/renderer.h +++ b/interface/wx/renderer.h @@ -37,7 +37,7 @@ enum /** Only for the menu items. */ wxCONTROL_ISSUBMENU = wxCONTROL_SPECIAL, - /** Only for the tree items. */ + /** Only for the tree items and collapse buttons. */ wxCONTROL_EXPANDED = wxCONTROL_SPECIAL, /** Only for the status bar panes. */ @@ -441,6 +441,24 @@ public: virtual void DrawPushButton(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0) = 0; + /** + Draw a collapse button. + + @a flags may have the @c wxCONTROL_EXPANDED or @c wxCONTROL_CURRENT + bit set, see @ref wxCONTROL_FLAGS. + + @since 3.1.0 + */ + virtual void DrawCollapseButton(wxWindow *win, wxDC& dc, + const wxRect& rect, int flags = 0) = 0; + + /** + Returns the size of a collapse button. + + @since 3.1.0 + */ + virtual wxSize GetCollapseButtonSize(wxWindow *win, wxDC& dc) = 0; + /** Draw the border for sash window: this border must be such that the sash drawn by DrawSplitterSash() blends into it well. diff --git a/samples/render/render.cpp b/samples/render/render.cpp index 82eb9db8df..a18ac4b274 100644 --- a/samples/render/render.cpp +++ b/samples/render/render.cpp @@ -246,6 +246,12 @@ private: wxRect(wxPoint(x2, y), sizeCheck), m_flags); y += lineHeight + sizeCheck.y; + dc.DrawText("DrawCollapseButton()", x1, y); + const wxSize sizeCollapse = renderer.GetCollapseButtonSize(this, dc); + renderer.DrawCollapseButton(this, dc, + wxRect(wxPoint(x2, y), sizeCollapse), m_flags); + y += lineHeight + sizeCollapse.y; + dc.DrawText("DrawTreeItemButton()", x1, y); renderer.DrawTreeItemButton(this, dc, wxRect(x2, y, 20, 20), m_flags); diff --git a/src/generic/renderg.cpp b/src/generic/renderg.cpp index 74578c9aed..96f3ac40d9 100644 --- a/src/generic/renderg.cpp +++ b/src/generic/renderg.cpp @@ -113,6 +113,13 @@ public: const wxRect& rect, int flags = 0) wxOVERRIDE; + virtual void DrawCollapseButton(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0); + + virtual wxSize GetCollapseButtonSize(wxWindow *win, wxDC& dc); + virtual void DrawItemSelectionRect(wxWindow *win, wxDC& dc, const wxRect& rect, @@ -686,6 +693,42 @@ wxRendererGeneric::DrawPushButton(wxWindow *win, dc.DrawRectangle(rect); } +void +wxRendererGeneric::DrawCollapseButton(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags) +{ + int arrowHalf = rect.width / 5; + int rectMid = rect.width / 2; + int arrowTopY = (rect.height / 2) - (arrowHalf / 2); + + wxPoint pt[3]; + if (flags & wxCONTROL_EXPANDED) + { + // This should always result in arrow with odd width. + pt[0] = wxPoint(rectMid - arrowHalf, arrowTopY); + pt[1] = wxPoint(rectMid + arrowHalf, arrowTopY); + pt[2] = wxPoint(rectMid, arrowTopY + arrowHalf); + } + else + { + // This should always result in arrow with odd height. + pt[0] = wxPoint(arrowTopY, rectMid - arrowHalf); + pt[1] = wxPoint(arrowTopY + arrowHalf, rectMid); + pt[2] = wxPoint(arrowTopY, rectMid + arrowHalf); + } + + dc.SetBrush(wxBrush(win->GetForegroundColour())); + dc.SetPen(wxPen(win->GetForegroundColour())); + dc.DrawPolygon(WXSIZEOF(pt), pt, rect.x, rect.y); +} + +wxSize wxRendererGeneric::GetCollapseButtonSize(wxWindow *WXUNUSED(win), wxDC& WXUNUSED(dc)) +{ + return wxSize(18, 18); +} + void wxRendererGeneric::DrawItemSelectionRect(wxWindow * win, wxDC& dc, diff --git a/src/msw/renderer.cpp b/src/msw/renderer.cpp index 2e9eb80a80..3511b9f0d2 100644 --- a/src/msw/renderer.cpp +++ b/src/msw/renderer.cpp @@ -114,6 +114,15 @@ #define DTT_TEXTCOLOR (1UL << 0) // crText has been specified #define DTT_STATEID (1UL << 8) // IStateId has been specified + + #define TDLG_EXPANDOBUTTON 13 + + #define TDLGEBS_NORMAL 1 + #define TDLGEBS_HOVER 2 + #define TDLGEBS_PRESSED 3 + #define TDLGEBS_EXPANDEDNORMAL 4 + #define TDLGEBS_EXPANDEDHOVER 5 + #define TDLGEBS_EXPANDEDPRESSED 6 #endif #if defined(__WXWINCE__) @@ -294,6 +303,13 @@ public: m_rendererNative.DrawPushButton(win, dc, rect, flags); } + virtual void DrawCollapseButton(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0); + + virtual wxSize GetCollapseButtonSize(wxWindow *win, wxDC& dc); + virtual void DrawItemSelectionRect(wxWindow *win, wxDC& dc, const wxRect& rect, @@ -858,6 +874,74 @@ wxRendererXP::DrawTitleBarBitmap(wxWindow *win, DoDrawButtonLike(hTheme, part, dc, rect, flags); } +void +wxRendererXP::DrawCollapseButton(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags) +{ + wxUxThemeHandle hTheme(win, L"TASKDIALOG"); + wxUxThemeEngine* const te = wxUxThemeEngine::Get(); + + int state; + if (flags & wxCONTROL_PRESSED) + state = TDLGEBS_PRESSED; + else if (flags & wxCONTROL_CURRENT) + state = TDLGEBS_HOVER; + else + state = TDLGEBS_NORMAL; + + if ( flags & wxCONTROL_EXPANDED ) + state += 3; + + if ( te->IsThemePartDefined(hTheme, TDLG_EXPANDOBUTTON, state) ) + { + if (flags & wxCONTROL_EXPANDED) + flags |= wxCONTROL_CHECKED; + + wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect); + + RECT r; + wxCopyRectToRECT(adjustedRect, r); + + te->DrawThemeBackground + ( + hTheme, + GetHdcOf(dc.GetTempHDC()), + TDLG_EXPANDOBUTTON, + state, + &r, + NULL + ); + } + else + m_rendererNative.DrawCollapseButton(win, dc, rect, flags); +} + +wxSize wxRendererXP::GetCollapseButtonSize(wxWindow *win, wxDC& dc) +{ + wxUxThemeHandle hTheme(win, L"TASKDIALOG"); + wxUxThemeEngine* const te = wxUxThemeEngine::Get(); + + // EXPANDOBUTTON scales ugly if not using the correct size, get size from theme + + if ( te->IsThemePartDefined(hTheme, TDLG_EXPANDOBUTTON, TDLGEBS_NORMAL) ) + { + SIZE s; + te->GetThemePartSize(hTheme, + GetHdcOf(dc.GetTempHDC()), + TDLG_EXPANDOBUTTON, + TDLGEBS_NORMAL, + NULL, + TS_TRUE, + &s); + + return wxSize(s.cx, s.cy); + } + else + return m_rendererNative.GetCollapseButtonSize(win, dc); +} + void wxRendererXP::DrawItemSelectionRect(wxWindow *win, wxDC& dc,