From 1f361cddbfcff9c54eef6b8c447d2b93ee2825f5 Mon Sep 17 00:00:00 2001 From: Mattia Barbon Date: Thu, 2 May 2002 20:07:10 +0000 Subject: [PATCH] Implemented wxStatusBar::Push/PopStatusText. Implemented wxFrame::Push/PopSTatusText ( just forward to the status bar ). Implemented wxFrame::DoGiveHelp, to show menu/toolbar help in the status bar. Added Get/SetStatusBarPane to get/set the status bar pane the menu/toolbar help will be show in git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15339 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/frame.h | 12 +++++ include/wx/statusbr.h | 20 ++++++++ src/common/framecmn.cpp | 40 ++++++++++++--- src/common/statbar.cpp | 108 +++++++++++++++++++++++++++++++++++++++ src/common/tbarbase.cpp | 21 ++------ src/generic/statusbr.cpp | 30 ++--------- src/msw/frame.cpp | 8 +-- 7 files changed, 182 insertions(+), 57 deletions(-) diff --git a/include/wx/frame.h b/include/wx/frame.h index ac7e48f61c..dfd1df99d6 100644 --- a/include/wx/frame.h +++ b/include/wx/frame.h @@ -108,6 +108,8 @@ public: // forward these to status bar virtual void SetStatusText(const wxString &text, int number = 0); virtual void SetStatusWidths(int n, const int widths_field[]); + void PushStatusText(const wxString &text, int number = 0); + void PopStatusText(int number = 0); #endif // wxUSE_STATUSBAR // toolbar functions @@ -151,6 +153,10 @@ public: { return FALSE; } #endif // no wxTopLevelWindowNative + // show help text (typically in the statusbar); show is FALSE + // if you are hiding the help, TRUE otherwise + virtual void DoGiveHelp(const wxString& text, bool show); + protected: // the frame main menu/status/tool bars // ------------------------------------ @@ -189,6 +195,12 @@ protected: wxStatusBar *m_frameStatusBar; #endif // wxUSE_STATUSBAR + // set the status bar pane the help will be shown in + void SetStatusBarPane(int n) { m_statusBarPane = n; } + int GetStatusBarPane() const { return m_statusBarPane; } + + int m_statusBarPane; + #if wxUSE_TOOLBAR // override to update status bar position (or anything else) when // something changes diff --git a/include/wx/statusbr.h b/include/wx/statusbr.h index adc1bf5946..103e8479f7 100644 --- a/include/wx/statusbr.h +++ b/include/wx/statusbr.h @@ -20,6 +20,10 @@ #if wxUSE_STATUSBAR +#include "wx/list.h" + +WX_DECLARE_LIST(wxString, wxListString); + // ---------------------------------------------------------------------------- // wxStatusBar: a window near the bottom of the frame used for status info // ---------------------------------------------------------------------------- @@ -45,6 +49,9 @@ public: virtual void SetStatusText(const wxString& text, int number = 0) = 0; virtual wxString GetStatusText(int number = 0) const = 0; + void PushStatusText(const wxString& text, int number = 0); + void PopStatusText(int number = 0); + // fields widths // ------------- @@ -82,15 +89,28 @@ protected: // reset the widths void ReinitWidths() { FreeWidths(); InitWidths(); } + // same, for text stacks + void InitStacks(); + void FreeStacks(); + void ReinitStacks() { FreeStacks(); InitStacks(); } + // calculate the real field widths for the given total available size wxArrayInt CalculateAbsWidths(wxCoord widthTotal) const; + // use these functions to access the stacks of field strings + wxListString *GetStatusStack(int i) const; + wxListString *GetOrCreateStatusStack(int i); + // the current number of fields int m_nFields; // the widths of the fields in pixels if !NULL, all fields have the same // width otherwise int *m_statusWidths; + + // stacks of previous values for PushStatusText/PopStatusText + // this is created on demand, use GetStatusStack/GetOrCreateStatusStack + wxListString **m_statusTextStacks; }; // ---------------------------------------------------------------------------- diff --git a/src/common/framecmn.cpp b/src/common/framecmn.cpp index 77d1c1e1c4..8ab73139d8 100644 --- a/src/common/framecmn.cpp +++ b/src/common/framecmn.cpp @@ -76,6 +76,8 @@ wxFrameBase::wxFrameBase() #if wxUSE_STATUSBAR m_frameStatusBar = NULL; #endif // wxUSE_STATUSBAR + + m_statusBarPane = 0; } wxFrameBase::~wxFrameBase() @@ -277,16 +279,40 @@ void wxFrameBase::SetStatusWidths(int n, const int widths_field[] ) PositionStatusBar(); } -bool wxFrameBase::ShowMenuHelp(wxStatusBar *statbar, int menuId) +void wxFrameBase::PushStatusText(const wxString& text, int number) { -#if wxUSE_MENUS - if ( !statbar ) - return FALSE; + wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") ); + + m_frameStatusBar->PushStatusText(text, number); +} +void wxFrameBase::PopStatusText(int number) +{ + wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") ); + + m_frameStatusBar->PopStatusText(number); +} + +void wxFrameBase::DoGiveHelp(const wxString& text, bool show) +{ +#if wxUSE_STATUSBAR + if ( m_statusBarPane < 0 ) return; + wxStatusBar* statbar = GetStatusBar(); + if ( !statbar ) return; + + wxString help = show ? text : wxString(); + statbar->SetStatusText( help, m_statusBarPane ); +#endif // wxUSE_STATUSBAR +} + +bool wxFrameBase::ShowMenuHelp(wxStatusBar *WXUNUSED(statbar), int menuId) +{ +#if wxUSE_MENUS // if no help string found, we will clear the status bar text wxString helpString; + bool show = menuId != wxID_SEPARATOR && menuId != -2 /* wxID_TITLE */; - if ( menuId != wxID_SEPARATOR && menuId != -2 /* wxID_TITLE */ ) + if ( show ) { wxMenuBar *menuBar = GetMenuBar(); if ( menuBar ) @@ -299,9 +325,7 @@ bool wxFrameBase::ShowMenuHelp(wxStatusBar *statbar, int menuId) } } - // set status text even if the string is empty - this will at least - // remove the string from the item which was previously selected - statbar->SetStatusText(helpString); + DoGiveHelp(helpString, show); return !helpString.IsEmpty(); #else // !wxUSE_MENUS diff --git a/src/common/statbar.cpp b/src/common/statbar.cpp index fbea039979..944b7979c1 100644 --- a/src/common/statbar.cpp +++ b/src/common/statbar.cpp @@ -34,6 +34,9 @@ #if wxUSE_STATUSBAR +#include "wx/listimpl.cpp" +WX_DEFINE_LIST(wxListString); + // ============================================================================ // wxStatusBarBase implementation // ============================================================================ @@ -49,11 +52,13 @@ wxStatusBarBase::wxStatusBarBase() m_nFields = 0; InitWidths(); + InitStacks(); } wxStatusBarBase::~wxStatusBarBase() { FreeWidths(); + FreeStacks(); } // ---------------------------------------------------------------------------- @@ -82,6 +87,31 @@ void wxStatusBarBase::SetFieldsCount(int number, const int *widths) if ( number != m_nFields ) { + // copy stacks if present + if(m_statusTextStacks) + { + wxListString **newStacks = new wxListString*[number]; + size_t i, j, max = wxMin(number, m_nFields); + + // copy old stacks + for(i = 0; i < max; ++i) + newStacks[i] = m_statusTextStacks[i]; + // free old stacks in excess + for(j = i; j < (size_t)m_nFields; ++j) + { + if(m_statusTextStacks[j]) + { + m_statusTextStacks[j]->Clear(); + delete m_statusTextStacks[j]; + } + } + // initialize new stacks to NULL + for(j = i; j < (size_t)number; ++j) + newStacks[j] = 0; + + m_statusTextStacks = newStacks; + } + m_nFields = number; ReinitWidths(); @@ -186,5 +216,83 @@ wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const return widths; } +// ---------------------------------------------------------------------------- +// text stacks handling +// ---------------------------------------------------------------------------- + +void wxStatusBarBase::InitStacks() +{ + m_statusTextStacks = NULL; +} + +void wxStatusBarBase::FreeStacks() +{ + if(!m_statusTextStacks) return; + size_t i; + + for(i = 0; i < (size_t)m_nFields; ++i) + { + if(m_statusTextStacks[i]) + { + m_statusTextStacks[i]->Clear(); + delete m_statusTextStacks[i]; + } + } + + delete[] m_statusTextStacks; +} + +// ---------------------------------------------------------------------------- +// text stacks +// ---------------------------------------------------------------------------- + +void wxStatusBarBase::PushStatusText(const wxString& text, int number) +{ + wxListString* st = GetOrCreateStatusStack(number); + st->Insert(new wxString(GetStatusText(number))); + SetStatusText(text, number); +} + +void wxStatusBarBase::PopStatusText(int number) +{ + wxListString *st = GetStatusStack(number); + wxCHECK_RET( st, _T("Unbalanced PushStatusText/PopStatusText") ); + wxListString::Node *top = st->GetFirst(); + + SetStatusText(*top->GetData(), number); + st->DeleteNode(top); + if(st->GetCount() == 0) + { + delete st; + m_statusTextStacks[number] = 0; + } +} + +wxListString *wxStatusBarBase::GetStatusStack(int i) const +{ + if(!m_statusTextStacks) + return 0; + return m_statusTextStacks[i]; +} + +wxListString *wxStatusBarBase::GetOrCreateStatusStack(int i) +{ + if(!m_statusTextStacks) + { + m_statusTextStacks = new wxListString*[m_nFields]; + + size_t j; + for(j = 0; j < (size_t)m_nFields; ++j) m_statusTextStacks[j] = 0; + } + + if(!m_statusTextStacks[i]) + { + m_statusTextStacks[i] = new wxListString(); + m_statusTextStacks[i]->DeleteContents(TRUE); + } + + return m_statusTextStacks[i]; +} + #endif // wxUSE_STATUSBAR diff --git a/src/common/tbarbase.cpp b/src/common/tbarbase.cpp index a68b275b1a..14b0bd80e2 100644 --- a/src/common/tbarbase.cpp +++ b/src/common/tbarbase.cpp @@ -507,26 +507,15 @@ void wxToolBarBase::OnMouseEnter(int id) event.SetEventObject(this); event.SetInt(id); - (void)GetEventHandler()->ProcessEvent(event); - wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); - if ( !frame ) - return; - - wxString helpstring; - - if ( id != -1 ) + if( frame ) { - wxToolBarToolBase *tool = FindById(id); - if ( tool ) - helpstring = tool->GetLongHelp(); + wxToolBarToolBase* tool = id == -1 ? (wxToolBarToolBase*)0 : FindById(id); + wxString help = tool ? tool->GetLongHelp() : wxString(); + frame->DoGiveHelp( help, id != -1 ); } - // set the status text anyhow, even if the string is empty: this ensures - // that it is cleared when the mouse leaves the toolbar or enters a tool - // without help - if (frame->GetStatusBar()) - frame->SetStatusText(helpstring); + (void)GetEventHandler()->ProcessEvent(event); } // ---------------------------------------------------------------------------- diff --git a/src/generic/statusbr.cpp b/src/generic/statusbr.cpp index 2256846c67..a7c9f6387c 100644 --- a/src/generic/statusbr.cpp +++ b/src/generic/statusbr.cpp @@ -53,9 +53,7 @@ END_EVENT_TABLE() wxStatusBarGeneric::wxStatusBarGeneric() { - m_statusWidths = (int *) NULL; m_statusStrings = (wxString *) NULL; - m_nFields = 0; m_borderX = wxTHICK_LINE_BORDER; m_borderY = wxTHICK_LINE_BORDER; } @@ -75,9 +73,7 @@ bool wxStatusBarGeneric::Create(wxWindow *parent, long style, const wxString& name) { - m_statusWidths = (int *) NULL; m_statusStrings = (wxString *) NULL; - m_nFields = 0; m_borderX = wxTHICK_LINE_BORDER; m_borderY = wxTHICK_LINE_BORDER; @@ -151,36 +147,18 @@ void wxStatusBarGeneric::SetStatusWidths(int n, const int widths_field[]) // delete the old widths in any case - this function may be used to reset // the widths to the default (all equal) - delete [] m_statusWidths; + // MBN: this is incompatible with at least wxMSW and wxMAC and not + // documented, but let's keep it for now + ReinitWidths(); if ( !widths_field ) { // not an error, see the comment above - m_statusWidths = (int *)NULL; Refresh(); return; } - int i; - - // VZ: this doesn't do anything as is_variable is unused later -#if 0 - // when one window (minimum) is variable (width <= 0) - bool is_variable = FALSE; - for (i = 0; i < m_nFields; i++) - { - if (widths_field[i] <= 0) - is_variable = TRUE; - } -#endif // 0 - - // set widths - m_statusWidths = new int[n]; - for (i = 0; i < m_nFields; i++) - { - m_statusWidths[i] = widths_field[i]; - } - Refresh(); + wxStatusBarBase::SetStatusWidths(n, widths_field); } void wxStatusBarGeneric::OnPaint(wxPaintEvent& WXUNUSED(event) ) diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 57c0235fbe..99f1e9c763 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -746,17 +746,11 @@ bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu) #endif else { -#if wxUSE_STATUSBAR // don't give hints for separators (doesn't make sense) nor for the // items opening popup menus (they don't have them anyhow) but do clear // the status line - otherwise, we would be left with the help message // for the previous item which doesn't apply any more - wxStatusBar *statbar = GetStatusBar(); - if ( statbar ) - { - statbar->SetStatusText(wxEmptyString); - } -#endif // wxUSE_STATUSBAR + DoGiveHelp(wxEmptyString, FALSE); return FALSE; } -- 2.45.2