From 6d78998725b53eea209c0fa845b5a25fe5b512d2 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Thu, 16 Aug 2007 12:15:15 +0000 Subject: [PATCH] Added DrawFocusRect to wxRenderer git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48125 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/renderer.tex | 9 ++++++ include/wx/renderer.h | 8 +++++ include/wx/univ/renderer.h | 6 ---- include/wx/univ/stdrend.h | 3 +- src/generic/renderg.cpp | 61 +++++++++++++++++++++++++++++++------- src/gtk/renderer.cpp | 30 +++++++++++++++++-- src/msw/renderer.cpp | 9 ++++++ src/univ/stdrend.cpp | 6 ++-- src/univ/themes/gtk.cpp | 4 +-- src/univ/themes/mono.cpp | 4 +-- src/univ/themes/win32.cpp | 2 +- 11 files changed, 114 insertions(+), 28 deletions(-) diff --git a/docs/latex/wx/renderer.tex b/docs/latex/wx/renderer.tex index c4ba821569..88f6923d74 100644 --- a/docs/latex/wx/renderer.tex +++ b/docs/latex/wx/renderer.tex @@ -136,6 +136,15 @@ 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::DrawFocusRect}\label{wxrenderernativedrawfocusrect} + +\func{void}{DrawFocusRect}{\param{wxWindow* }{win}, \param{wxDC\& }{dc}, \param{const wxRect\& }{rect}, \param{int }{flags = 0}} + +Draw a focus rectangle using the specified rectangle. +\helpref{wxListCtrl}{wxlistctrl}. The only supported flags is +\texttt{wxCONTROL\_SELECTED} for items which are selected. + + \membersection{wxRendererNative::DrawHeaderButton}\label{wxrenderernativedrawheaderbutton} \func{int}{DrawHeaderButton}{\param{wxWindow* }{win}, \param{wxDC\& }{dc}, \param{const wxRect\& }{rect}, \param{int }{flags = 0}, \param{wxHeaderSortIconType }{sortArrow = wxHDR\_SORT\_ICON\_NONE}, \param{wxHeaderButtonParams* }{params = NULL}} diff --git a/include/wx/renderer.h b/include/wx/renderer.h index 14ffb00d94..2097782e73 100644 --- a/include/wx/renderer.h +++ b/include/wx/renderer.h @@ -247,6 +247,11 @@ public: const wxRect& rect, int flags = 0) = 0; + // draw the focus rectangle around the label contained in the given rect + // + // only wxCONTROL_SELECTED makes sense in flags here + virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0) = 0; + // geometry functions // ------------------ @@ -380,6 +385,9 @@ public: int flags = 0 ) { m_rendererNative.DrawItemSelectionRect( win, dc, rect, flags ); } + virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0) + { m_rendererNative.DrawFocusRect( win, dc, rect, flags ); } + virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win) { return m_rendererNative.GetSplitterParams(win); } diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index 940b3bc286..ef7aa4236a 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -90,12 +90,6 @@ public: const wxRect& rect, int flags) = 0; - - // draw the focus rectangle around the label contained in the given rect - // - // only wxCONTROL_SELECTED makes sense in flags here - virtual void DrawFocusRect(wxDC& dc, const wxRect& rect, int flags = 0) = 0; - // draw the label inside the given rectangle with the specified alignment // and optionally emphasize the character with the given index virtual void DrawLabel(wxDC& dc, diff --git a/include/wx/univ/stdrend.h b/include/wx/univ/stdrend.h index 8a07e5ccf5..a6be61336d 100644 --- a/include/wx/univ/stdrend.h +++ b/include/wx/univ/stdrend.h @@ -38,7 +38,8 @@ public: int flags); - virtual void DrawFocusRect(wxDC& dc, const wxRect& rect, int flags = 0); + virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0); + virtual void DrawLabel(wxDC& dc, const wxString& label, const wxRect& rect, diff --git a/src/generic/renderg.cpp b/src/generic/renderg.cpp index 38348c5543..5ff309e88a 100644 --- a/src/generic/renderg.cpp +++ b/src/generic/renderg.cpp @@ -104,6 +104,8 @@ public: const wxRect& rect, int flags = 0); + virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0); + virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win); virtual wxRendererVersion GetVersion() const @@ -222,7 +224,7 @@ wxRendererGeneric::DrawHeaderButton(wxWindow* win, dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE))); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(rect); - + dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.SetPen(m_penBlack); @@ -252,7 +254,7 @@ wxRendererGeneric::DrawHeaderButtonContents(wxWindow *win, wxHeaderButtonParams* params) { int labelWidth = 0; - + // Mark this item as selected. For the generic version we'll just draw an // underline if ( flags & wxCONTROL_SELECTED ) @@ -281,7 +283,7 @@ wxRendererGeneric::DrawHeaderButtonContents(wxWindow *win, ar.y += (rect.height - ar.height)/2; ar.x = ar.x + rect.width - 3*ar.width/2; arrowSpace = 3*ar.width/2; // space to preserve when drawing the label - + wxPoint triPt[3]; if ( sortArrow & wxHDR_SORT_ICON_UP ) { @@ -306,19 +308,19 @@ wxRendererGeneric::DrawHeaderButtonContents(wxWindow *win, params->m_arrowColour : wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW); dc.SetPen(wxPen(c)); dc.SetBrush(wxBrush(c)); - dc.DrawPolygon( 3, triPt, ar.x, ar.y); + dc.DrawPolygon( 3, triPt, ar.x, ar.y); } labelWidth += arrowSpace; - + const int margin = 5; // number of pixels to reserve on either side of the label int bmpWidth = 0; int txtEnd = 0; - + if ( params && params->m_labelBitmap.Ok() ) bmpWidth = params->m_labelBitmap.GetWidth() + 2; labelWidth += bmpWidth + 2*margin; - + // Draw a label if one is given if ( params && !params->m_labelText.empty() ) { @@ -328,7 +330,7 @@ wxRendererGeneric::DrawHeaderButtonContents(wxWindow *win, params->m_labelColour : win->GetForegroundColour(); wxString label( params->m_labelText ); - + dc.SetFont(font); dc.SetTextForeground(clr); dc.SetBackgroundMode(wxTRANSPARENT); @@ -337,10 +339,10 @@ wxRendererGeneric::DrawHeaderButtonContents(wxWindow *win, dc.GetTextExtent( label, &tw, &th, &td); labelWidth += tw; y = rect.y + wxMax(0, (rect.height - (th+td)) / 2); - + // truncate and add an ellipsis (...) if the text is too wide. int targetWidth = rect.width - arrowSpace - bmpWidth - 2*margin; - if ( tw > targetWidth ) + if ( tw > targetWidth ) { int ellipsisWidth; dc.GetTextExtent( wxT("..."), &ellipsisWidth, NULL); @@ -351,7 +353,7 @@ wxRendererGeneric::DrawHeaderButtonContents(wxWindow *win, label.append( wxT("...") ); tw += ellipsisWidth; } - + switch (params->m_labelAlignment) { default: @@ -661,6 +663,43 @@ wxRendererGeneric::DrawItemSelectionRect(wxWindow * WXUNUSED(win), dc.DrawRectangle( rect ); } +void +wxRendererGeneric::DrawFocusRect(wxWindow* WXUNUSED(win), wxDC& dc, const wxRect& rect, int WXUNUSED(flags)) +{ + // draw the pixels manually because the "dots" in wxPen with wxDOT style + // may be short traits and not really dots + // + // note that to behave in the same manner as DrawRect(), we must exclude + // the bottom and right borders from the rectangle + wxCoord x1 = rect.GetLeft(), + y1 = rect.GetTop(), + x2 = rect.GetRight(), + y2 = rect.GetBottom(); + + dc.SetPen(m_penBlack); + + // this seems to be closer than what Windows does than wxINVERT although + // I'm still not sure if it's correct + dc.SetLogicalFunction(wxAND_REVERSE); + + wxCoord z; + for ( z = x1 + 1; z < x2; z += 2 ) + dc.DrawPoint(z, rect.GetTop()); + + wxCoord shift = z == x2 ? 0 : 1; + for ( z = y1 + shift; z < y2; z += 2 ) + dc.DrawPoint(x2, z); + + shift = z == y2 ? 0 : 1; + for ( z = x2 - shift; z > x1; z -= 2 ) + dc.DrawPoint(z, y2); + + shift = z == x1 ? 0 : 1; + for ( z = y2 - shift; z > y1; z -= 2 ) + dc.DrawPoint(x1, z); + + dc.SetLogicalFunction(wxCOPY); +} // ---------------------------------------------------------------------------- // A module to allow cleanup of generic renderer. diff --git a/src/gtk/renderer.cpp b/src/gtk/renderer.cpp index 7323cb5c04..1eec14354d 100644 --- a/src/gtk/renderer.cpp +++ b/src/gtk/renderer.cpp @@ -92,6 +92,8 @@ public: const wxRect& rect, int flags = 0); + virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0); + virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win); private: @@ -188,7 +190,7 @@ GtkWidget * wxRendererGTK::GetHeaderButtonWidget() { static GtkWidget *s_button = NULL; - + if ( !s_button ) { // Get the dummy tree widget, give it a column, and then use the @@ -216,7 +218,7 @@ wxRendererGTK::DrawHeaderButton(wxWindow *win, { GtkWidget *button = GetHeaderButtonWidget(); - + GdkWindow* gdk_window = dc.GetGDKWindow(); wxASSERT_MSG( gdk_window, wxT("cannot use wxRendererNative on wxDC of this type") ); @@ -577,3 +579,27 @@ wxRendererGTK::DrawItemSelectionRect(wxWindow *win, rect.height ); } } + +void wxRendererGTK::DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags) +{ + GdkWindow* gdk_window = dc.GetGDKWindow(); + wxASSERT_MSG( gdk_window, + wxT("cannot use wxRendererNative on wxDC of this type") ); + + GtkStateType state; + if (flags & wxCONTROL_SELECTED) + state = GTK_STATE_SELECTED; + else + state = GTK_STATE_NORMAL; + + gtk_paint_focus( win->m_widget->style, + gdk_window, + state, + NULL, + win->m_wxwindow, + NULL, + dc.LogicalToDeviceX(rect.x), + dc.LogicalToDeviceY(rect.y), + rect.width, + rect.height ); +} diff --git a/src/msw/renderer.cpp b/src/msw/renderer.cpp index 7961dc3184..403fec6579 100644 --- a/src/msw/renderer.cpp +++ b/src/msw/renderer.cpp @@ -115,6 +115,7 @@ public: const wxRect& rect, int flags = 0); + virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0); private: DECLARE_NO_COPY_CLASS(wxRendererMSW) }; @@ -276,6 +277,14 @@ wxRendererMSW::DrawPushButton(wxWindow * WXUNUSED(win), ::DrawFrameControl(GetHdcOf(dc), &rc, DFC_BUTTON, style); } +void wxRendererMSW::DrawFocusRect(wxWindow* WXUNUSED(win), wxDC& dc, const wxRect& rect, int WXUNUSED(flags)) +{ + RECT rc; + wxCopyRectToRECT(rect, rc); + + ::DrawFocusRect(GetHdcOf(dc), &rc); +} + // ============================================================================ // wxRendererXP implementation // ============================================================================ diff --git a/src/univ/stdrend.cpp b/src/univ/stdrend.cpp index ea50847d70..f392add9cc 100644 --- a/src/univ/stdrend.cpp +++ b/src/univ/stdrend.cpp @@ -199,7 +199,7 @@ void wxStdRenderer::DrawButtonSurface(wxDC& dc, // ---------------------------------------------------------------------------- void -wxStdRenderer::DrawFocusRect(wxDC& dc, const wxRect& rect, int WXUNUSED(flags)) +wxStdRenderer::DrawFocusRect(wxWindow* WXUNUSED(win), wxDC& dc, const wxRect& rect, int WXUNUSED(flags)) { // draw the pixels manually because the "dots" in wxPen with wxDOT style // may be short traits and not really dots @@ -290,7 +290,7 @@ void wxStdRenderer::DrawButtonLabel(wxDC& dc, { rectLabel.Inflate(-1); - DrawFocusRect(dc, rectLabel); + DrawFocusRect(NULL, dc, rectLabel); } } @@ -632,7 +632,7 @@ void wxStdRenderer::DrawItem(wxDC& dc, if ( flags & wxCONTROL_FOCUSED ) { - DrawFocusRect(dc, rect, flags); + DrawFocusRect(NULL, dc, rect, flags); } } diff --git a/src/univ/themes/gtk.cpp b/src/univ/themes/gtk.cpp index 447a359305..1ccb81c552 100644 --- a/src/univ/themes/gtk.cpp +++ b/src/univ/themes/gtk.cpp @@ -85,7 +85,7 @@ public: wxGTKRenderer(const wxColourScheme *scheme); // wxRenderer methods - virtual void DrawFocusRect(wxDC& dc, const wxRect& rect, int flags = 0); + virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0); virtual void DrawTextBorder(wxDC& dc, wxBorder border, const wxRect& rect, @@ -814,7 +814,7 @@ void wxGTKRenderer::DrawSunkenBorder(wxDC& dc, wxRect *rect) } void -wxGTKRenderer::DrawFocusRect(wxDC& dc, const wxRect& rect, int WXUNUSED(flags)) +wxGTKRenderer::DrawFocusRect(wxWindow* WXUNUSED(win), wxDC& dc, const wxRect& rect, int WXUNUSED(flags)) { dc.SetBrush(*wxTRANSPARENT_BRUSH); wxRect rectFocus = rect; diff --git a/src/univ/themes/mono.cpp b/src/univ/themes/mono.cpp index 3c6ef714ba..4fd27cea1e 100644 --- a/src/univ/themes/mono.cpp +++ b/src/univ/themes/mono.cpp @@ -62,7 +62,7 @@ public: int indexAccel = -1, wxRect *rectBounds = NULL); - virtual void DrawFocusRect(wxDC& dc, const wxRect& rect, int flags = 0); + virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0); virtual void DrawButtonBorder(wxDC& dc, const wxRect& rect, @@ -702,7 +702,7 @@ wxMonoRenderer::DrawVerticalLine(wxDC& dc, wxCoord x, wxCoord y1, wxCoord y2) dc.DrawLine(x, y1, x, y2 + 1); } -void wxMonoRenderer::DrawFocusRect(wxDC& dc, const wxRect& rect, int flags) +void wxMonoRenderer::DrawFocusRect(wxWindow* WXUNUSED(win), wxDC& dc, const wxRect& rect, int flags) { // no need to draw the focus rect for selected items, it would be invisible // anyhow diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index 853c080d57..40475959a0 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -2053,7 +2053,7 @@ void wxWin32Renderer::DrawSliderShaft(wxDC& dc, */ if (flags & wxCONTROL_FOCUSED) { - DrawFocusRect(dc, rectOrig); + DrawFocusRect(NULL, dc, rectOrig); } wxRect rect = GetSliderShaftRect(rectOrig, lenThumb, orient, style); -- 2.47.2