From c94bdf2a19b4a3f5d958f491814a383ac7ef4ffb Mon Sep 17 00:00:00 2001 From: Francesco Montorsi Date: Tue, 21 Apr 2009 11:10:44 +0000 Subject: [PATCH] implement tooltips for wxStatusBar panes whose contents were ellipsized; introduce wxST_SHOW_TIPS and wxST_DEFAULT_STYLE styles git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60265 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/defs.h | 5 --- include/wx/frame.h | 6 +-- include/wx/generic/statusbr.h | 9 +++- include/wx/msw/statusbar.h | 4 +- include/wx/osx/statusbr.h | 4 +- include/wx/palmos/statusbr.h | 4 +- include/wx/statusbr.h | 29 +++++++++++-- include/wx/univ/statusbr.h | 4 +- interface/wx/statusbr.h | 28 ++++++++++--- src/generic/statusbr.cpp | 78 ++++++++++++++++++++++++++++++----- 10 files changed, 135 insertions(+), 36 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index f815b86986..1205d7880c 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -1769,11 +1769,6 @@ enum wxBorder #define wxTC_MULTILINE 0x0200 /* == wxNB_MULTILINE */ #define wxTC_OWNERDRAW 0x0400 -/* - * wxStatusBar95 flags - */ -#define wxST_SIZEGRIP 0x0010 - /* * wxStaticBitmap flags */ diff --git a/include/wx/frame.h b/include/wx/frame.h index 1d1ab9655f..3599be5b66 100644 --- a/include/wx/frame.h +++ b/include/wx/frame.h @@ -17,6 +17,7 @@ // ---------------------------------------------------------------------------- #include "wx/toplevel.h" // the base class +#include "wx/statusbr.h" // the default names for various classs extern WXDLLIMPEXP_DATA_CORE(const char) wxStatusLineNameStr[]; @@ -103,10 +104,9 @@ public: #if wxUSE_STATUSBAR // create the main status bar by calling OnCreateStatusBar() virtual wxStatusBar* CreateStatusBar(int number = 1, - long style = wxST_SIZEGRIP|wxFULL_REPAINT_ON_RESIZE, + long style = wxST_DEFAULT_STYLE, wxWindowID winid = 0, - const wxString& name = - wxStatusLineNameStr); + const wxString& name = wxStatusLineNameStr); // return a new status bar virtual wxStatusBar *OnCreateStatusBar(int number, long style, diff --git a/include/wx/generic/statusbr.h b/include/wx/generic/statusbr.h index 13d309423c..5f08365329 100644 --- a/include/wx/generic/statusbr.h +++ b/include/wx/generic/statusbr.h @@ -30,7 +30,7 @@ public: wxStatusBarGeneric() { Init(); } wxStatusBarGeneric(wxWindow *parent, wxWindowID winid = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxStatusBarNameStr) { Init(); @@ -41,7 +41,7 @@ public: virtual ~wxStatusBarGeneric(); bool Create(wxWindow *parent, wxWindowID winid = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxStatusBarNameStr); // Create status line @@ -64,6 +64,10 @@ public: virtual int GetBorderY() const { return m_borderY; } + // implementation only (not part of wxStatusBar public API): + + int GetFieldFromPoint(const wxPoint& point) const; + protected: // event handlers void OnPaint(wxPaintEvent& event); @@ -104,6 +108,7 @@ protected: int m_borderX; int m_borderY; + wxPen m_mediumShadowPen; wxPen m_hilightPen; diff --git a/include/wx/msw/statusbar.h b/include/wx/msw/statusbar.h index 4b4677c0f3..4a2218d01a 100644 --- a/include/wx/msw/statusbar.h +++ b/include/wx/msw/statusbar.h @@ -23,7 +23,7 @@ public: wxStatusBar(); wxStatusBar(wxWindow *parent, wxWindowID id = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxStatusBarNameStr) { m_pDC = NULL; @@ -32,7 +32,7 @@ public: bool Create(wxWindow *parent, wxWindowID id = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxStatusBarNameStr); virtual ~wxStatusBar(); diff --git a/include/wx/osx/statusbr.h b/include/wx/osx/statusbr.h index dd39aea1d5..070ce3b31e 100644 --- a/include/wx/osx/statusbr.h +++ b/include/wx/osx/statusbr.h @@ -19,13 +19,13 @@ class WXDLLIMPEXP_CORE wxStatusBarMac : public wxStatusBarGeneric wxStatusBarMac(); wxStatusBarMac(wxWindow *parent, wxWindowID id = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxStatusBarNameStr); virtual ~wxStatusBarMac(); bool Create(wxWindow *parent, wxWindowID id = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxStatusBarNameStr); virtual void DrawFieldText(wxDC& dc, const wxRect& rc, int i, int textHeight); diff --git a/include/wx/palmos/statusbr.h b/include/wx/palmos/statusbr.h index 977723ce85..07da2297f9 100644 --- a/include/wx/palmos/statusbr.h +++ b/include/wx/palmos/statusbr.h @@ -21,7 +21,7 @@ public: wxStatusBarPalm(); wxStatusBarPalm(wxWindow *parent, wxWindowID id = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxEmptyString) { (void)Create(parent, id, style, name); @@ -29,7 +29,7 @@ public: bool Create(wxWindow *parent, wxWindowID id = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxEmptyString); virtual ~wxStatusBarPalm(); diff --git a/include/wx/statusbr.h b/include/wx/statusbr.h index 3dd21052a1..216bdecd3d 100644 --- a/include/wx/statusbr.h +++ b/include/wx/statusbr.h @@ -26,6 +26,12 @@ extern WXDLLIMPEXP_DATA_CORE(const char) wxStatusBarNameStr[]; // wxStatusBar constants // ---------------------------------------------------------------------------- +// wxStatusBar styles +#define wxST_SIZEGRIP 0x0010 +#define wxST_SHOW_TIPS 0x0020 + +#define wxST_DEFAULT_STYLE (wxST_SIZEGRIP|wxST_SHOW_TIPS|wxFULL_REPAINT_ON_RESIZE) + // style flags for fields #define wxSB_NORMAL 0x0000 #define wxSB_FLAT 0x0001 @@ -42,7 +48,8 @@ class WXDLLIMPEXP_CORE wxStatusBarPane public: wxStatusBarPane(int style = wxSB_NORMAL, size_t width = 0) - : m_nStyle(style), m_nWidth(width) { m_arrStack.Add(wxEmptyString); } + : m_nStyle(style), m_nWidth(width) + { m_arrStack.Add(wxEmptyString); m_bEllipsized=false; } int GetWidth() const { return m_nWidth; } @@ -52,7 +59,12 @@ public: const wxArrayString& GetStack() const { return m_arrStack; } - // use wxStatusBar setter functions to modify a wxStatusBarPane + // implementation-only getter: + bool IsEllipsized() const + { return m_bEllipsized; } + + // NOTE: there are no setters in wxStatusBarPane; + // use wxStatusBar functions to modify a wxStatusBarPane protected: int m_nStyle; @@ -61,9 +73,12 @@ protected: // this is the array of the stacked strings of this pane; note that this // stack does include also the string currently displayed in this pane // as the version stored in the native status bar control is possibly - // ellipsized; note that arrStack.Last() is the top of the stack + // ellipsized; note that m_arrStack.Last() is the top of the stack // (i.e. the string shown in the status bar) wxArrayString m_arrStack; + + // was the m_arrStack.Last() string shown in the status bar control ellipsized? + bool m_bEllipsized; }; WX_DECLARE_OBJARRAY(wxStatusBarPane, wxStatusBarPaneArray); @@ -138,6 +153,9 @@ public: // get the dimensions of the horizontal and vertical borders virtual int GetBorderX() const = 0; virtual int GetBorderY() const = 0; + + wxSize GetBorders() const + { return wxSize(GetBorderX(), GetBorderY()); } // miscellaneous // ------------- @@ -158,6 +176,11 @@ protected: // calculate the real field widths for the given total available size wxArrayInt CalculateAbsWidths(wxCoord widthTotal) const; + + // an internal utility used to keep track of which panes have labels + // which were last rendered as ellipsized... + void SetEllipsizedFlag(int n, bool ellipsized) + { m_panes[n].m_bEllipsized = ellipsized; } // the array with the pane infos: wxStatusBarPaneArray m_panes; diff --git a/include/wx/univ/statusbr.h b/include/wx/univ/statusbr.h index bb5d3435f5..e4e1cfe8a9 100644 --- a/include/wx/univ/statusbr.h +++ b/include/wx/univ/statusbr.h @@ -27,7 +27,7 @@ public: wxStatusBarUniv(wxWindow *parent, wxWindowID id = wxID_ANY, - long style = 0, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxPanelNameStr) { Init(); @@ -37,7 +37,7 @@ public: bool Create(wxWindow *parent, wxWindowID id = wxID_ANY, - long style = 0, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxPanelNameStr); // set field count/widths diff --git a/interface/wx/statusbr.h b/interface/wx/statusbr.h index d97648ead8..f91767c5e2 100644 --- a/interface/wx/statusbr.h +++ b/interface/wx/statusbr.h @@ -23,12 +23,12 @@ public: Constructs the pane with the given @a style and @a width. */ wxStatusBarPane(int style = wxSB_NORMAL, size_t width = 0); - + /** Returns the pane width; it maybe negative, indicating a variable-width field. */ int GetWidth() const; - + /** Returns the pane style. */ @@ -52,10 +52,19 @@ public: A status bar is a narrow window that can be placed along the bottom of a frame to give small amounts of status information. It can contain one or more fields, one or more of which can be variable length according to the size of the window. + + Note that in wxStatusBar context, the terms @e pane and @e field are synonyms. @beginStyleTable @style{wxST_SIZEGRIP} - Displays a gripper at the right-hand side of the status bar. + Displays a gripper at the right-hand side of the status bar which can be used + to resize the parent window. + @style{wxST_SHOW_TIPS} + Displays tooltips for those panes whose status text has been ellipsized because + the status text doesn't fit the pane width. + Note that this style has effect only on wxGTK (with GTK+ >= 2.12) currently. + @style{wxST_DEFAULT_STYLE} + The default style: includes @c wxST_SIZEGRIP|wxST_SHOW_TIPS|wxFULL_REPAINT_ON_RESIZE. @endStyleTable @remarks @@ -93,7 +102,7 @@ public: @see Create() */ wxStatusBar(wxWindow* parent, wxWindowID id = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxStatusBarNameStr); /** @@ -106,7 +115,7 @@ public: See wxStatusBar() for details. */ bool Create(wxWindow* parent, wxWindowID id = wxID_ANY, - long style = wxST_SIZEGRIP, + long style = wxST_DEFAULT_STYLE, const wxString& name = wxStatusBarNameStr); /** @@ -133,6 +142,15 @@ public: */ const wxStatusBarPane& GetField(int n) const; + /** + Returns the horizontal and vertical borders used when rendering the field + text inside the field area. + + Note that the rect returned by GetFieldRect() already accounts for the + presence of horizontal and vertical border returned by this function. + */ + wxSize GetBorders() const; + /** Returns the string associated with a status bar field. diff --git a/src/generic/statusbr.cpp b/src/generic/statusbr.cpp index 1264843946..2af087cb6b 100644 --- a/src/generic/statusbr.cpp +++ b/src/generic/statusbr.cpp @@ -2,7 +2,7 @@ // Name: src/generic/statusbr.cpp // Purpose: wxStatusBarGeneric class implementation // Author: Julian Smart -// Modified by: +// Modified by: Francesco Montorsi // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart @@ -29,6 +29,7 @@ #ifdef __WXGTK20__ #include + #include "wx/gtk/private.h" #endif // we only have to do it here when we use wxStatusBarGeneric in addition to the @@ -48,6 +49,33 @@ // Margin between the field text and the field rect #define wxFIELD_TEXT_MARGIN 2 +// ---------------------------------------------------------------------------- +// GTK+ signal handler +// ---------------------------------------------------------------------------- + +#if defined( __WXGTK20__ ) && GTK_CHECK_VERSION(2,12,0) +extern "C" { +static +gboolean statusbar_query_tooltip(GtkWidget *widget, + gint x, + gint y, + gboolean keyboard_mode, + GtkTooltip *tooltip, + wxStatusBar* statbar) +{ + int n = statbar->GetFieldFromPoint(wxPoint(x,y)); + if (n == wxNOT_FOUND) + return FALSE; + + // should we show the tooltip for the n-th pane of the statusbar? + if (!statbar->GetField(n).IsEllipsized()) + return FALSE; // no, it's not useful + + gtk_tooltip_set_text(tooltip, wxGTK_CONV_SYS(statbar->GetStatusText(n))); + return TRUE; +} +} +#endif // ---------------------------------------------------------------------------- // wxStatusBarGeneric @@ -95,6 +123,15 @@ bool wxStatusBarGeneric::Create(wxWindow *parent, SetSize(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, height); SetFieldsCount(1); + +#if defined( __WXGTK20__ ) && GTK_CHECK_VERSION(2,12,0) + if (HasFlag(wxST_SHOW_TIPS) && !gtk_check_version(2,12,0)) + { + g_object_set(m_widget, "has-tooltip", TRUE, NULL); + g_signal_connect(m_widget, "query-tooltip", + G_CALLBACK(statusbar_query_tooltip), this); + } +#endif return true; } @@ -208,6 +245,10 @@ void wxStatusBarGeneric::DrawFieldText(wxDC& dc, const wxRect& rect, int i, int wxELLIPSIZE_EXPAND_TAB); // Ellipsize() will do something only if necessary + // update the ellipsization status for this pane; this is used to decide + // whether a tooltip should be shown or not for this pane + SetEllipsizedFlag(i, text != GetStatusText(i)); + #if defined( __WXGTK__ ) || defined(__WXMAC__) xpos++; ypos++; @@ -229,11 +270,8 @@ void wxStatusBarGeneric::DrawField(wxDC& dc, int i, int textHeight) if (style != wxSB_FLAT) { // Draw border - // For wxSB_NORMAL: - // Have grey background, plus 3-d border - - // One black rectangle. - // Inside this, left and top sides - dark grey. Bottom and right - - // white. + // For wxSB_NORMAL: paint a grey background, plus 3-d border (one black rectangle) + // Inside this, left and top sides (dark grey). Bottom and right (white). // Reverse it for wxSB_RAISED dc.SetPen((style == wxSB_RAISED) ? m_mediumShadowPen : m_hilightPen); @@ -264,14 +302,13 @@ void wxStatusBarGeneric::DrawField(wxDC& dc, int i, int textHeight) dc.DrawLine(rect.x, rect.y, rect.x + rect.width, rect.y); dc.DrawLine(rect.x, rect.y + rect.height, - rect.x, rect.y); + rect.x, rect.y); #endif } DrawFieldText(dc, rect, i, textHeight); } -// Get the position and size of the field's internal bounding rectangle bool wxStatusBarGeneric::GetFieldRect(int n, wxRect& rect) const { wxCHECK_MSG( (n >= 0) && ((size_t)n < m_panes.GetCount()), false, @@ -292,7 +329,29 @@ bool wxStatusBarGeneric::GetFieldRect(int n, wxRect& rect) const return true; } -// Initialize colours +int wxStatusBarGeneric::GetFieldFromPoint(const wxPoint& pt) const +{ + if (m_widthsAbs.IsEmpty()) + return wxNOT_FOUND; + + // NOTE: we explicitely don't take in count the borders since they are only + // useful when rendering the status text, not for hit-test computations + + if (pt.y <= 0 || pt.y >= m_lastClientHeight) + return wxNOT_FOUND; + + int x = 0; + for ( size_t i = 0; i < m_panes.GetCount(); i++ ) + { + if (pt.x > x && pt.x < x+m_widthsAbs[i]) + return i; + + x += m_widthsAbs[i]; + } + + return wxNOT_FOUND; +} + void wxStatusBarGeneric::InitColours() { #if defined(__WXPM__) @@ -366,7 +425,6 @@ void wxStatusBarGeneric::OnPaint(wxPaintEvent& WXUNUSED(event) ) DrawField(dc, i, textHeight); } -// Responds to colour changes, and passes event on to children. void wxStatusBarGeneric::OnSysColourChanged(wxSysColourChangedEvent& event) { InitColours(); -- 2.45.2