From: Francesco Montorsi Date: Mon, 9 Feb 2009 00:33:19 +0000 (+0000) Subject: save the current status text for each pane inside wxStatusBarPane: native controls... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/0cd159592e4d9c979aa5a626627cdd9158fcc34f save the current status text for each pane inside wxStatusBarPane: native controls now store the (eventually) ellipsized version of the string; remove code for managing the status strings currently inside the [native|generic] control; add ellipsization support under wxMSW; now that all SetFieldsCount() implementation rrely on wxStatusBarBase::SetFieldsCount document how it behaves when adding new panes. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58786 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/generic/statusbr.h b/include/wx/generic/statusbr.h index 473fa6823c..13d309423c 100644 --- a/include/wx/generic/statusbr.h +++ b/include/wx/generic/statusbr.h @@ -50,7 +50,6 @@ public: // Set status line text virtual void SetStatusText(const wxString& text, int number = 0); - virtual wxString GetStatusText(int number = 0) const; // Set status line widths virtual void SetStatusWidths(int n, const int widths_field[]); @@ -97,9 +96,6 @@ protected: // common part of all ctors void Init(); - // the array of the currently displayed strings - wxArrayString m_statusStrings; - // the last known height of the client rect int m_lastClientHeight; diff --git a/include/wx/msw/statusbar.h b/include/wx/msw/statusbar.h index 8828b640e2..55a1f16c83 100644 --- a/include/wx/msw/statusbar.h +++ b/include/wx/msw/statusbar.h @@ -14,6 +14,8 @@ #if wxUSE_NATIVE_STATUSBAR +class WXDLLIMPEXP_CORE wxClientDC; + class WXDLLIMPEXP_CORE wxStatusBar : public wxStatusBarBase { public: @@ -39,7 +41,6 @@ public: // each field of status line has it's own text virtual void SetStatusText(const wxString& text, int number = 0); - virtual wxString GetStatusText(int number = 0) const; // set status line fields' widths virtual void SetStatusWidths(int n, const int widths_field[]); @@ -57,17 +58,23 @@ public: virtual int GetBorderX() const; virtual int GetBorderY() const; + virtual bool SetFont(const wxFont& font); + virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); protected: void CopyFieldsWidth(const int widths[]); void SetFieldsWidth(); + void UpdateFieldText(int nField); // override some base class virtuals virtual wxSize DoGetBestSize() const; virtual void DoMoveWindow(int x, int y, int width, int height); + // used by UpdateFieldText + wxClientDC *m_pDC; + private: DECLARE_DYNAMIC_CLASS_NO_COPY(wxStatusBar) }; diff --git a/include/wx/osx/statusbr.h b/include/wx/osx/statusbr.h index 81ee10257c..dd39aea1d5 100644 --- a/include/wx/osx/statusbr.h +++ b/include/wx/osx/statusbr.h @@ -28,8 +28,9 @@ class WXDLLIMPEXP_CORE wxStatusBarMac : public wxStatusBarGeneric long style = wxST_SIZEGRIP, const wxString& name = wxStatusBarNameStr); - virtual void DrawFieldText(wxDC& dc, int i); - virtual void DrawField(wxDC& dc, int i); + virtual void DrawFieldText(wxDC& dc, const wxRect& rc, int i, int textHeight); + virtual void DrawField(wxDC& dc, int i, int textHeight); + virtual void SetStatusText(const wxString& text, int number = 0); // Implementation diff --git a/include/wx/statusbr.h b/include/wx/statusbr.h index 49ae99e24e..66ec068c96 100644 --- a/include/wx/statusbr.h +++ b/include/wx/statusbr.h @@ -39,14 +39,16 @@ class wxStatusBarPane { public: wxStatusBarPane(int style = wxSB_NORMAL, size_t width = 0) - : nStyle(style), nWidth(width) {} + : nStyle(style), nWidth(width) { arrStack.Add(wxEmptyString); } int nStyle; int nWidth; // the width maybe negative, indicating a variable-width field // this is the array of the stacked strings of this pane; note that this - // stack does not include the string currently displayed in this pane - // as it's stored in the native status bar control + // 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 + // (i.e. the string shown in the status bar) wxArrayString arrStack; }; @@ -74,8 +76,10 @@ public: // field text // ---------- - virtual void SetStatusText(const wxString& text, int number = 0) = 0; - virtual wxString GetStatusText(int number = 0) const = 0; + virtual void SetStatusText(const wxString& text, int number = 0) + { m_panes[number].arrStack.Last() = text; } + virtual wxString GetStatusText(int number = 0) const + { return m_panes[number].arrStack.Last(); } void PushStatusText(const wxString& text, int number = 0); void PopStatusText(int number = 0); diff --git a/include/wx/univ/statusbr.h b/include/wx/univ/statusbr.h index dca76ee74b..bb5d3435f5 100644 --- a/include/wx/univ/statusbr.h +++ b/include/wx/univ/statusbr.h @@ -46,7 +46,6 @@ public: // get/set the text of the given field virtual void SetStatusText(const wxString& text, int number = 0); - virtual wxString GetStatusText(int number = 0) const; // Get the position and size of the field's internal bounding rectangle virtual bool GetFieldRect(int i, wxRect& rect) const; @@ -96,7 +95,7 @@ protected: private: // the current status fields strings - wxArrayString m_statusText; + //wxArrayString m_statusText; // the absolute status fields widths wxArrayInt m_widthsAbs; diff --git a/interface/wx/statusbr.h b/interface/wx/statusbr.h index 339a3e5fc2..1f95231b01 100644 --- a/interface/wx/statusbr.h +++ b/interface/wx/statusbr.h @@ -121,7 +121,8 @@ public: Sets the number of fields, and optionally the field widths. @param number - The number of fields. + The number of fields. If this is greater than the previous number, + then new fields with empty strings will be added to the status bar. @param widths An array of n integers interpreted in the same way as in SetStatusWidths(). diff --git a/src/common/statbar.cpp b/src/common/statbar.cpp index 9ceccf1277..323ce920e0 100644 --- a/src/common/statbar.cpp +++ b/src/common/statbar.cpp @@ -194,12 +194,15 @@ void wxStatusBarBase::PushStatusText(const wxString& text, int number) // save current status text in the stack m_panes[number].arrStack.push_back(GetStatusText(number)); - // update current status text SetStatusText(text, number); + // update current status text (eventually also in the native control) } void wxStatusBarBase::PopStatusText(int number) { + wxASSERT_MSG(m_panes[number].arrStack.GetCount() == 1, + "can't pop any further string"); + wxString text = m_panes[number].arrStack.back(); m_panes[number].arrStack.pop_back(); // also remove it from the stack diff --git a/src/generic/statusbr.cpp b/src/generic/statusbr.cpp index e78c18d216..f4dfe9c0d4 100644 --- a/src/generic/statusbr.cpp +++ b/src/generic/statusbr.cpp @@ -119,21 +119,9 @@ void wxStatusBarGeneric::SetFieldsCount(int number, const int *widths) { wxASSERT_MSG( number >= 0, _T("negative number of fields in wxStatusBar?") ); - // enlarge the m_statusStrings array if needed: - for (size_t i = m_panes.GetCount(); i < (size_t)number; ++i) - m_statusStrings.Add( wxEmptyString ); - - // shrink the m_statusStrings array if needed: - for (int j = (int)m_panes.GetCount() - 1; j >= number; --j) - m_statusStrings.RemoveAt(j); - - // forget the old cached pixel widths - m_widthsAbs.Empty(); - + // this will result in a call to SetStatusWidths() and thus an update to our + // m_widthsAbs cache wxStatusBarBase::SetFieldsCount(number, widths); - - wxASSERT_MSG( m_panes.GetCount() == m_statusStrings.GetCount(), - _T("This really should never happen, can we do away with m_panes.GetCount() here?") ); } void wxStatusBarGeneric::SetStatusText(const wxString& text, int number) @@ -141,10 +129,10 @@ void wxStatusBarGeneric::SetStatusText(const wxString& text, int number) wxCHECK_RET( (number >= 0) && ((size_t)number < m_panes.GetCount()), _T("invalid status bar field index") ); - wxString oldText = m_statusStrings[number]; + wxString oldText = GetStatusText(number); if (oldText != text) { - m_statusStrings[number] = text; + wxStatusBarBase::SetStatusText(text, number); wxRect rect; GetFieldRect(number, rect); @@ -158,23 +146,17 @@ void wxStatusBarGeneric::SetStatusText(const wxString& text, int number) } } -wxString wxStatusBarGeneric::GetStatusText(int n) const -{ - wxCHECK_MSG( (n >= 0) && ((size_t)n < m_panes.GetCount()), wxEmptyString, - _T("invalid status bar field index") ); - - return m_statusStrings[n]; -} - void wxStatusBarGeneric::SetStatusWidths(int n, const int widths_field[]) { // only set status widths when n == number of statuswindows wxCHECK_RET( (size_t)n == m_panes.GetCount(), _T("status bar field count mismatch") ); - // forget the old cached pixel widths - m_widthsAbs.Empty(); - wxStatusBarBase::SetStatusWidths(n, widths_field); + + // update cache + int width; + GetClientSize(&width, &m_lastClientHeight); + m_widthsAbs = CalculateAbsWidths(width); } bool wxStatusBarGeneric::ShowsSizeGrip() const diff --git a/src/msw/statusbar.cpp b/src/msw/statusbar.cpp index 8b7092efe0..0dcc35899c 100644 --- a/src/msw/statusbar.cpp +++ b/src/msw/statusbar.cpp @@ -36,6 +36,9 @@ #include "wx/msw/uxtheme.h" #endif +// no idea for a default width, just choose something +#define DEFAULT_FIELD_WIDTH 25 + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -59,6 +62,7 @@ wxStatusBar::wxStatusBar() SetParent(NULL); m_hWnd = 0; m_windowId = 0; + m_pDC = NULL; } bool wxStatusBar::Create(wxWindow *parent, @@ -131,6 +135,9 @@ bool wxStatusBar::Create(wxWindow *parent, // work correctly, we need to wait until we return to the main loop PostSizeEventToParent(); + // cache the DC instance used by UpdateFieldText + m_pDC = new wxClientDC(this); + return true; } @@ -142,6 +149,15 @@ wxStatusBar::~wxStatusBar() PostSizeEventToParent(); } +bool wxStatusBar::SetFont(const wxFont& font) +{ + if (!wxWindow::SetFont(font)) + return false; + + m_pDC->SetFont(font); + return true; +} + void wxStatusBar::SetFieldsCount(int nFields, const int *widths) { // this is a Windows limitation @@ -198,6 +214,16 @@ void wxStatusBar::SetStatusText(const wxString& strText, int nField) return; } + wxStatusBarBase::SetStatusText(strText, nField); + + UpdateFieldText(nField); +} + +void wxStatusBar::UpdateFieldText(int nField) +{ + if (!m_pDC) + return; + // Get field style, if any int style; switch(m_panes[nField].nStyle) @@ -215,29 +241,30 @@ void wxStatusBar::SetStatusText(const wxString& strText, int nField) break; } + wxRect rc; + GetFieldRect(nField, rc); + + int margin; + if (nField == GetFieldsCount()-1) + margin = -6; // windows reports a smaller rect for the last field; enlarge it + else + margin = 4; + + // do we need to ellipsize this string? + wxString ellipsizedStr = + wxControl::Ellipsize(GetStatusText(nField), *m_pDC, + GetLayoutDirection() == wxLayout_RightToLeft ? wxELLIPSIZE_START : wxELLIPSIZE_END, + rc.GetWidth() - margin, // leave a small margin + wxELLIPSIZE_EXPAND_TAB); + // Pass both field number and style. MSDN library doesn't mention // that nField and style have to be 'ORed' - if ( !StatusBar_SetText(GetHwnd(), nField | style, strText.wx_str()) ) + if ( !StatusBar_SetText(GetHwnd(), nField | style, ellipsizedStr.wx_str()) ) { wxLogLastError(wxT("StatusBar_SetText")); } } -wxString wxStatusBar::GetStatusText(int nField) const -{ - wxCHECK_MSG( (nField >= 0) && ((size_t)nField < m_panes.GetCount()), wxEmptyString, - _T("invalid statusbar field index") ); - - wxString str; - int len = StatusBar_GetTextLen(GetHwnd(), nField); - if ( len > 0 ) - { - StatusBar_GetText(GetHwnd(), nField, wxStringBuffer(str, len)); - } - - return str; -} - int wxStatusBar::GetBorderX() const { int aBorders[3]; @@ -295,9 +322,6 @@ bool wxStatusBar::GetFieldRect(int i, wxRect& rect) const return true; } -// no idea for a default width, just choose something -#define DEFAULT_FIELD_WIDTH 25 - wxSize wxStatusBar::DoGetBestSize() const { int borders[3]; @@ -330,7 +354,6 @@ wxSize wxStatusBar::DoGetBestSize() const width = 2*DEFAULT_FIELD_WIDTH; } - // calculate height int height; wxGetCharSize(GetHWND(), NULL, &height, GetFont()); @@ -454,6 +477,14 @@ wxStatusBar::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) } #endif + if ( nMsg == WM_SIZE ) + { + for (int i=0; iGetExtraStyle() & wxFRAME_EX_METAL ) ypos++; dc.SetClippingRegion(rect.x, 0, rect.width, h); - dc.DrawText(text, xpos, ypos); - dc.DestroyClippingRegion(); } -void wxStatusBarMac::DrawField(wxDC& dc, int i) +void wxStatusBarMac::DrawField(wxDC& dc, int i, int textHeight) { - DrawFieldText(dc, i); + wxRect rect; + GetFieldRect(i, rect); + + DrawFieldText(dc, rect, i, textHeight); } void wxStatusBarMac::SetStatusText(const wxString& text, int number) { + // NOTE: seems this function is identic to wxStatusBarGeneric::SetStatusText; + // probably can be removed without problems (FM) + wxCHECK_RET( (number >= 0) && ((size_t)number < m_panes.GetCount()), wxT("invalid status bar field index") ); - if ( m_statusStrings[number] == text ) - return ; + if ( GetStatusText(number) == text ) + return; + + wxStatusBarGeneric::SetStatusText(text, number); - m_statusStrings[number] = text; wxRect rect; GetFieldRect(number, rect); + int w, h; GetSize( &w, &h ); + rect.y = 0; rect.height = h ; + Refresh( true, &rect ); Update(); } @@ -162,12 +170,15 @@ void wxStatusBarMac::OnPaint(wxPaintEvent& WXUNUSED(event)) dc.DrawLine(0, 0, w, 0); } - if ( GetFont().Ok() ) + if ( GetFont().IsOk() ) dc.SetFont(GetFont()); dc.SetBackgroundMode(wxTRANSPARENT); + // compute char height only once for all panes: + int textHeight = dc.GetCharHeight(); + for ( size_t i = 0; i < m_panes.GetCount(); i ++ ) - DrawField(dc, i); + DrawField(dc, i, textHeight); } void wxStatusBarMac::MacHiliteChanged() diff --git a/src/univ/statusbr.cpp b/src/univ/statusbr.cpp index 071237016b..6b70e2e7f6 100644 --- a/src/univ/statusbr.cpp +++ b/src/univ/statusbr.cpp @@ -134,7 +134,7 @@ void wxStatusBarUniv::DoDraw(wxControlRenderer *renderer) flags |= wxCONTROL_SIZEGRIP; } - m_renderer->DrawStatusField(dc, rect, m_statusText[n], flags, m_panes[n].nStyle); + m_renderer->DrawStatusField(dc, rect, GetStatusText(n), flags, m_panes[n].nStyle); } rect.x += rect.width + borderBetweenFields; @@ -159,24 +159,17 @@ void wxStatusBarUniv::SetStatusText(const wxString& text, int number) wxCHECK_RET( number >= 0 && (size_t)number < m_panes.GetCount(), _T("invalid status bar field index in SetStatusText()") ); - if ( text == m_statusText[number] ) + if ( text == GetStatusText(number) ) { // nothing changed return; } - m_statusText[number] = text; + wxStatusBarBase::SetStatusText(text, number); RefreshField(number); } -wxString wxStatusBarUniv::GetStatusText(int number) const -{ - wxCHECK_MSG( number >= 0 && (size_t)number < m_panes.GetCount(), wxEmptyString, - _T("invalid status bar field index") ); - - return m_statusText[number]; -} // ---------------------------------------------------------------------------- // fields count/widths @@ -184,7 +177,6 @@ wxString wxStatusBarUniv::GetStatusText(int number) const void wxStatusBarUniv::SetFieldsCount(int number, const int *widths) { - m_statusText.SetCount(number); wxStatusBarBase::SetFieldsCount(number, widths); m_widthsAbs.Empty();