From 4c85ab7569677ff535c258c7f25ad428ba1ed406 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 24 Mar 2005 00:22:04 +0000 Subject: [PATCH] added wxRendererNative::DrawDropArrow (patch 1166596) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33010 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/renderer.tex | 14 ++++++- include/wx/renderer.h | 14 ++++++- src/generic/renderg.cpp | 39 +++++++++++++++---- src/gtk/renderer.cpp | 78 ++++++++++++++++++++++++++++++++++---- src/gtk1/renderer.cpp | 78 ++++++++++++++++++++++++++++++++++---- 5 files changed, 198 insertions(+), 25 deletions(-) diff --git a/docs/latex/wx/renderer.tex b/docs/latex/wx/renderer.tex index e65bb60e90..0f5a4111a2 100644 --- a/docs/latex/wx/renderer.tex +++ b/docs/latex/wx/renderer.tex @@ -98,7 +98,19 @@ Virtual destructor as for any base class. Draw a button like the one used by \helpref{wxComboBox}{wxcombobox} to show a drop down window. The usual appearance is a downwards pointing arrow. -\arg{flags} may have the \texttt{wxCONTROL\_PRESSED} bit set. +\arg{flags} may have the \texttt{wxCONTROL\_PRESSED} or \texttt{wxCONTROL\_CURRENT} bit set. + + +\membersection{wxRendererNative::DrawDropArrow}\label{wxrenderernativedrawdroparrow} + +\func{void}{DrawDropArrow}{\param{wxWindow *}{win}, \param{wxDC\& }{dc}, \param{const wxRect\& }{rect}, \param{int }{flags}} + +Draw a drop down arrow that is suitable for use outside a combo box. Arrow will have +transparent background. + +\arg{rect} is not entirely filled by the arrow. Instead, you should use bounding +rectangle of a drop down button which arrow matches the size you need. +\arg{flags} may have the \texttt{wxCONTROL\_PRESSED} or \texttt{wxCONTROL\_CURRENT} bit set. \membersection{wxRendererNative::DrawHeaderButton}\label{wxrenderernativedrawheaderbutton} diff --git a/include/wx/renderer.h b/include/wx/renderer.h index f8c8c14d8a..3f60878665 100644 --- a/include/wx/renderer.h +++ b/include/wx/renderer.h @@ -156,12 +156,19 @@ public: // draw a combobox dropdown button // - // flags may only use wxCONTROL_PRESSED + // flags may use wxCONTROL_PRESSED and wxCONTROL_CURRENT virtual void DrawComboBoxDropButton(wxWindow *win, wxDC& dc, const wxRect& rect, int flags = 0) = 0; + // draw a dropdown arrow + // + // flags may use wxCONTROL_PRESSED and wxCONTROL_CURRENT + virtual void DrawDropArrow(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0) = 0; // geometry functions // ------------------ @@ -259,6 +266,11 @@ public: int flags = 0) { m_rendererNative.DrawComboBoxDropButton(win, dc, rect, flags); } + virtual void DrawDropArrow(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0) + { m_rendererNative.DrawDropArrow(win, dc, rect, flags); } virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win) { return m_rendererNative.GetSplitterParams(win); } diff --git a/src/generic/renderg.cpp b/src/generic/renderg.cpp index 2a6c00da5f..4a9a929eb1 100644 --- a/src/generic/renderg.cpp +++ b/src/generic/renderg.cpp @@ -73,6 +73,10 @@ public: const wxRect& rect, int flags = 0); + virtual void DrawDropArrow(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0); virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win); @@ -343,28 +347,49 @@ wxRendererGeneric::DrawSplitterSash(wxWindow *win, } } +// ---------------------------------------------------------------------------- +// button drawing +// ---------------------------------------------------------------------------- + void wxRendererGeneric::DrawComboBoxDropButton(wxWindow *win, wxDC& dc, const wxRect& rect, int WXUNUSED(flags)) { - dc.SetBrush(wxBrush(win->GetBackgroundColour())); - dc.SetPen(wxPen(win->GetBackgroundColour())); - dc.DrawRectangle(rect); + // FIXME: Is it worth to do a better implementation? + // Generic wxComboDropButton should be drawn using + // combination of wxBitmapButton and DrawDropArrow + // anyway. + DrawDropArrow(win,dc,rect); +} + +void +wxRendererGeneric::DrawDropArrow(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int WXUNUSED(flags)) +{ + // This generic implementation should be good + // enough for Windows platforms (including XP). + + int arrowHalf = rect.width/5; + int rectMid = rect.width / 2; + int arrowTopY = (rect.height/2) - (arrowHalf/2); + + // This should always result in arrow with odd width. wxPoint pt[] = { - wxPoint(0,0), - wxPoint(rect.width, 0), - wxPoint(rect.width/2, rect.height - 2) + wxPoint(rectMid - arrowHalf, arrowTopY), + wxPoint(rectMid + arrowHalf, arrowTopY), + wxPoint(rectMid, arrowTopY + arrowHalf) }; dc.SetBrush(wxBrush(win->GetForegroundColour())); dc.SetPen(wxPen(win->GetForegroundColour())); dc.DrawPolygon(WXSIZEOF(pt), pt, rect.x, rect.y); } - // ---------------------------------------------------------------------------- // A module to allow cleanup of generic renderer. // ---------------------------------------------------------------------------- diff --git a/src/gtk/renderer.cpp b/src/gtk/renderer.cpp index baae5fe61b..8b545e1c39 100644 --- a/src/gtk/renderer.cpp +++ b/src/gtk/renderer.cpp @@ -79,6 +79,11 @@ public: const wxRect& rect, int flags = 0); + virtual void DrawDropArrow(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0); + virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win); private: @@ -394,20 +399,35 @@ wxRendererGTK::DrawSplitterSash(wxWindow *win, #endif // GTK+ 2.x/1.x } -void wxRendererGTK::DrawComboBoxDropButton(wxWindow *win, - wxDC& dc, - const wxRect& rect, - int flags) +void +wxRendererGTK::DrawDropArrow(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags) { GtkWidget *button = GetButtonWidget(); - // device context must inherit from wxWindowDC - // (so it must be wxClientDC, wxMemoryDC or wxPaintDC) + // If we give GTK_PIZZA(win->m_wxwindow)->bin_window as + // a window for gtk_paint_xxx function, then it won't + // work for wxMemoryDC. So that is why we assume wxDC + // is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC + // are derived from it) and use its m_window. wxWindowDC& wdc = (wxWindowDC&)dc; - // only doing debug-time checking here (it should probably be enough) + // only doing debug-time checking here (it should + // probably be enough) wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) ); + // draw arrow so that there is even space horizontally + // on both sides + int arrowX = rect.width/4 + 1; + int arrowWidth = rect.width - (arrowX*2); + + // scale arrow's height accoording to the width + int arrowHeight = rect.width/3; + int arrowY = (rect.height-arrowHeight)/2 + + ((rect.height-arrowHeight) & 1); + GtkStateType state; if ( flags & wxCONTROL_CURRENT ) @@ -429,7 +449,49 @@ void wxRendererGTK::DrawComboBoxDropButton(wxWindow *win, "arrow", GTK_ARROW_DOWN, FALSE, - rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2 + rect.x + arrowX, + rect.y + arrowY, + arrowWidth, + arrowHeight ); } +void +wxRendererGTK::DrawComboBoxDropButton(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags) +{ + GtkWidget *button = GetButtonWidget(); + + // for reason why we do this, see DrawDropArrow + wxWindowDC& wdc = (wxWindowDC&)dc; + wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) ); + + // draw button + GtkStateType state; + + if ( flags & wxCONTROL_CURRENT ) + state = GTK_STATE_PRELIGHT; + else if ( flags & wxCONTROL_DISABLED ) + state = GTK_STATE_INSENSITIVE; + else + state = GTK_STATE_NORMAL; + + gtk_paint_box + ( + button->style, + wdc.m_window, + state, + flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT, + NULL, + button, + "button", + rect.x, rect.y, rect.width, rect.height + ); + + // draw arrow on button + DrawDropArrow(win,dc,rect,flags); + +} + diff --git a/src/gtk1/renderer.cpp b/src/gtk1/renderer.cpp index baae5fe61b..8b545e1c39 100644 --- a/src/gtk1/renderer.cpp +++ b/src/gtk1/renderer.cpp @@ -79,6 +79,11 @@ public: const wxRect& rect, int flags = 0); + virtual void DrawDropArrow(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0); + virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win); private: @@ -394,20 +399,35 @@ wxRendererGTK::DrawSplitterSash(wxWindow *win, #endif // GTK+ 2.x/1.x } -void wxRendererGTK::DrawComboBoxDropButton(wxWindow *win, - wxDC& dc, - const wxRect& rect, - int flags) +void +wxRendererGTK::DrawDropArrow(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags) { GtkWidget *button = GetButtonWidget(); - // device context must inherit from wxWindowDC - // (so it must be wxClientDC, wxMemoryDC or wxPaintDC) + // If we give GTK_PIZZA(win->m_wxwindow)->bin_window as + // a window for gtk_paint_xxx function, then it won't + // work for wxMemoryDC. So that is why we assume wxDC + // is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC + // are derived from it) and use its m_window. wxWindowDC& wdc = (wxWindowDC&)dc; - // only doing debug-time checking here (it should probably be enough) + // only doing debug-time checking here (it should + // probably be enough) wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) ); + // draw arrow so that there is even space horizontally + // on both sides + int arrowX = rect.width/4 + 1; + int arrowWidth = rect.width - (arrowX*2); + + // scale arrow's height accoording to the width + int arrowHeight = rect.width/3; + int arrowY = (rect.height-arrowHeight)/2 + + ((rect.height-arrowHeight) & 1); + GtkStateType state; if ( flags & wxCONTROL_CURRENT ) @@ -429,7 +449,49 @@ void wxRendererGTK::DrawComboBoxDropButton(wxWindow *win, "arrow", GTK_ARROW_DOWN, FALSE, - rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2 + rect.x + arrowX, + rect.y + arrowY, + arrowWidth, + arrowHeight ); } +void +wxRendererGTK::DrawComboBoxDropButton(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags) +{ + GtkWidget *button = GetButtonWidget(); + + // for reason why we do this, see DrawDropArrow + wxWindowDC& wdc = (wxWindowDC&)dc; + wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) ); + + // draw button + GtkStateType state; + + if ( flags & wxCONTROL_CURRENT ) + state = GTK_STATE_PRELIGHT; + else if ( flags & wxCONTROL_DISABLED ) + state = GTK_STATE_INSENSITIVE; + else + state = GTK_STATE_NORMAL; + + gtk_paint_box + ( + button->style, + wdc.m_window, + state, + flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT, + NULL, + button, + "button", + rect.x, rect.y, rect.width, rect.height + ); + + // draw arrow on button + DrawDropArrow(win,dc,rect,flags); + +} + -- 2.45.2