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.
This commit is contained in:
ali kettab 2023-11-26 01:38:40 +01:00 committed by Vadim Zeitlin
parent ed02e03585
commit 2c9fee3d6f
4 changed files with 76 additions and 19 deletions

View file

@ -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:

View file

@ -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.

View file

@ -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();

View file

@ -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