From 2c9fee3d6fe4a55f6a8b3528a5f9c18dabc7530c Mon Sep 17 00:00:00 2001 From: ali kettab Date: Sun, 26 Nov 2023 01:38:40 +0100 Subject: [PATCH] Add wxStatusBar::AddFieldControl() to simplify adding controls This allows user codes to simply designate where their controls should appear in the status bar without the need to handle wxEVT_SIZE themselves. They can still handle the event if the default positioning does not meet their needs, but the new API is simpler and can be implemented for wxQt. Closes #24092. --- include/wx/statusbr.h | 20 +++++++++++++++++++ interface/wx/statusbr.h | 16 ++++++++++++++++ samples/statbar/statbar.cpp | 21 ++------------------ src/common/statbar.cpp | 38 +++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 19 deletions(-) diff --git a/include/wx/statusbr.h b/include/wx/statusbr.h index f27a225dcb..8a4506a8d4 100644 --- a/include/wx/statusbr.h +++ b/include/wx/statusbr.h @@ -17,6 +17,7 @@ #include "wx/control.h" #include "wx/list.h" #include "wx/dynarray.h" +#include "wx/weakref.h" extern WXDLLIMPEXP_DATA_CORE(const char) wxStatusBarNameStr[]; @@ -84,6 +85,11 @@ public: // really restored anything bool PopText(); + // set/get the control (child of the wxStatusBar) that will be shown in + // this pane. + void SetFieldControl(wxWindow* win) { m_control = win; } + wxWindow* GetFieldControl() const { return m_control; } + private: int m_nStyle; int m_nWidth; // may be negative, indicating a variable-width field @@ -97,6 +103,9 @@ private: // is the currently shown value shown with ellipsis in the status bar? bool m_bEllipsized; + + // remember the control that will be shown in this pane. Updated by SetFieldControl(). + wxWindowRef m_control; }; // This is preserved for compatibility, but is not supposed to be used by the @@ -173,6 +182,14 @@ public: wxSize GetBorders() const { return wxSize(GetBorderX(), GetBorderY()); } + // controls + // -------- + + // Add a control (child of the wxStatusBar) to be shown at the specified + // field position #n. Note that you must delete the control to remove it + // from the status bar, as simply passing _nullptr_ will not do that. + bool AddFieldControl(int n, wxWindow* win); + // miscellaneous // ------------- @@ -192,6 +209,9 @@ protected: // display virtual void DoUpdateStatusText(int number) = 0; + // Position the added controls (added by AddFieldControl()), if any, in + // their corresponding destination. + void OnSize(wxSizeEvent& event); // wxWindow overrides: diff --git a/interface/wx/statusbr.h b/interface/wx/statusbr.h index 2d25722607..0e93b92a3f 100644 --- a/interface/wx/statusbr.h +++ b/interface/wx/statusbr.h @@ -248,6 +248,22 @@ public: */ virtual void SetFieldsCount(int number = 1, const int* widths = nullptr); + /** + Add a control (child of the wxStatusBar) to be shown at the specified + field position in the status bar. + + @param i + The field index where the control will be shown. + @param win + The control in question. Must be a child of the wxStatusBar itself. + + @note You must delete the control to remove it from the status bar, as + simply passing @NULL will not do that. + + @since 3.3.0 + */ + bool AddFieldControl(int i, wxWindow* win); + /** Sets the minimal possible height for the status bar. diff --git a/samples/statbar/statbar.cpp b/samples/statbar/statbar.cpp index 0887f1b027..b9ccd6f933 100644 --- a/samples/statbar/statbar.cpp +++ b/samples/statbar/statbar.cpp @@ -223,7 +223,6 @@ enum StatusBar_SetStyleShowTips }; -static const int BITMAP_SIZE_X = 32; // ---------------------------------------------------------------------------- // event tables and other macros for wxWidgets @@ -925,7 +924,7 @@ MyStatusBar::MyStatusBar(wxWindow *parent, long style) int widths[Field_Max]; widths[Field_Text] = -1; // growable widths[Field_Checkbox] = 150; - widths[Field_Bitmap] = BITMAP_SIZE_X; + widths[Field_Bitmap] = -1; // growable widths[Field_NumLockIndicator] = sizeNumLock.x; widths[Field_Clock] = 100; widths[Field_CapsLockIndicator] = dc.GetTextExtent(capslockIndicators[1]).x; @@ -936,6 +935,7 @@ MyStatusBar::MyStatusBar(wxWindow *parent, long style) #if wxUSE_CHECKBOX m_checkbox = new wxCheckBox(this, StatusBar_Checkbox, "&Toggle clock"); m_checkbox->SetValue(true); + AddFieldControl(Field_Checkbox, m_checkbox); #endif m_statbmp = new wxStaticBitmap(this, wxID_ANY, wxIcon(green_xpm)); @@ -966,24 +966,7 @@ MyStatusBar::~MyStatusBar() void MyStatusBar::OnSize(wxSizeEvent& event) { -#if wxUSE_CHECKBOX - if ( !m_checkbox ) - return; -#endif - wxRect rect; - if (!GetFieldRect(Field_Checkbox, rect)) - { - event.Skip(); - return; - } - -#if wxUSE_CHECKBOX - wxRect rectCheck = rect; - rectCheck.Deflate(2); - m_checkbox->SetSize(rectCheck); -#endif - GetFieldRect(Field_Bitmap, rect); wxSize size = m_statbmp->GetSize(); diff --git a/src/common/statbar.cpp b/src/common/statbar.cpp index 358e9fe133..04ade7fb08 100644 --- a/src/common/statbar.cpp +++ b/src/common/statbar.cpp @@ -112,6 +112,8 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow); wxStatusBarBase::wxStatusBarBase() { m_bSameWidthForAllPanes = true; + + Bind(wxEVT_SIZE, &wxStatusBarBase::OnSize, this); } wxStatusBarBase::~wxStatusBarBase() @@ -297,4 +299,40 @@ void wxStatusBarBase::PopStatusText(int number) DoUpdateStatusText(number); } +// ---------------------------------------------------------------------------- +// controls +// ---------------------------------------------------------------------------- +bool wxStatusBarBase::AddFieldControl(int n, wxWindow* win) +{ + wxCHECK_MSG( (unsigned)n < m_panes.size(), false, + "invalid status bar field index" ); + wxCHECK_MSG( !m_panes[n].GetFieldControl(), false, + "another control is already added in this field" ); + + m_panes[n].SetFieldControl(win); + + return true; +} + +void wxStatusBarBase::OnSize(wxSizeEvent& event) +{ + event.Skip(); + + if ( GetChildren().empty() ) + return; + + for ( int i = 0; i < (int)m_panes.size(); ++i ) + { + wxWindow* const win = m_panes[i].GetFieldControl(); + if ( win ) + { + wxRect rect; + if ( GetFieldRect(i, rect) ) + { + win->SetSize(rect); + } + } + } +} + #endif // wxUSE_STATUSBAR