Reconnect events to the widget after recreating it in the sample

This ensures that the expected events are given even after the widget is
recreated due to a change of some controls on its page (and not because
it's recreated by one of the menu commands in the parent frame).

We also don't need to connect to these events from WidgetsFrame any
longer (and, in fact, doing it would be wrong as we'd connect twice),
which simplifies its code.
This commit is contained in:
Vadim Zeitlin 2024-02-18 19:02:38 +01:00
parent 828b7ee844
commit a8b4753d1d
32 changed files with 105 additions and 25 deletions

View file

@ -145,6 +145,8 @@ void ActivityIndicatorWidgetsPage::RecreateWidget()
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
GetAttrs().m_defaultFlags); GetAttrs().m_defaultFlags);
NotifyWidgetRecreation(m_indicator);
m_sizerIndicator->AddStretchSpacer(); m_sizerIndicator->AddStretchSpacer();
m_sizerIndicator->Add(m_indicator, wxSizerFlags().Centre()); m_sizerIndicator->Add(m_indicator, wxSizerFlags().Centre());
m_sizerIndicator->AddStretchSpacer(); m_sizerIndicator->AddStretchSpacer();

View file

@ -478,6 +478,8 @@ void BitmapComboBoxWidgetsPage::CreateCombo()
m_combobox->SetPopupMaxHeight(600); m_combobox->SetPopupMaxHeight(600);
#endif #endif
NotifyWidgetRecreation(m_combobox);
unsigned int count = items.GetCount(); unsigned int count = items.GetCount();
for ( unsigned int n = 0; n < count; n++ ) for ( unsigned int n = 0; n < count; n++ )
{ {

View file

@ -562,6 +562,8 @@ void ButtonWidgetsPage::CreateButton()
m_sizerNote->Show(m_chkCommandLink->GetValue()); m_sizerNote->Show(m_chkCommandLink->GetValue());
#endif #endif
NotifyWidgetRecreation(m_button);
if ( !showsBitmap && m_chkTextAndBitmap->GetValue() ) if ( !showsBitmap && m_chkTextAndBitmap->GetValue() )
{ {
showsBitmap = true; showsBitmap = true;

View file

@ -276,6 +276,8 @@ void CheckBoxWidgetsPage::CreateCheckbox()
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
flags); flags);
NotifyWidgetRecreation(m_checkbox);
m_sizerCheckbox->Add(0, 0, 1, wxCENTRE); m_sizerCheckbox->Add(0, 0, 1, wxCENTRE);
m_sizerCheckbox->Add(m_checkbox, 1, wxCENTRE); m_sizerCheckbox->Add(m_checkbox, 1, wxCENTRE);
m_sizerCheckbox->Add(0, 0, 1, wxCENTRE); m_sizerCheckbox->Add(0, 0, 1, wxCENTRE);

View file

@ -303,6 +303,8 @@ void ChoiceWidgetsPage::CreateChoice()
0, nullptr, 0, nullptr,
flags); flags);
NotifyWidgetRecreation(m_choice);
m_choice->Set(items); m_choice->Set(items);
m_sizerChoice->Add(m_choice, 0, wxGROW | wxALL, 5); m_sizerChoice->Add(m_choice, 0, wxGROW | wxALL, 5);
m_sizerChoice->Layout(); m_sizerChoice->Layout();

View file

@ -191,6 +191,8 @@ void ColourPickerWidgetsPage::CreatePicker()
m_clrPicker = new wxColourPickerCtrl(this, PickerPage_Colour, *wxRED, m_clrPicker = new wxColourPickerCtrl(this, PickerPage_Colour, *wxRED,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
style); style);
NotifyWidgetRecreation(m_clrPicker);
} }
void ColourPickerWidgetsPage::RecreatePicker() void ColourPickerWidgetsPage::RecreatePicker()

View file

@ -476,6 +476,8 @@ void ComboboxWidgetsPage::CreateCombo()
delete m_combobox; delete m_combobox;
m_combobox = newCb; m_combobox = newCb;
m_combobox->SetId(ComboPage_Combo); m_combobox->SetId(ComboPage_Combo);
NotifyWidgetRecreation(m_combobox);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View file

@ -285,6 +285,8 @@ void DatePickerWidgetsPage::CreateDatePicker()
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
style); style);
NotifyWidgetRecreation(m_datePicker);
m_sizerDatePicker->Add(0, 0, 1, wxCENTRE); m_sizerDatePicker->Add(0, 0, 1, wxCENTRE);
m_sizerDatePicker->Add(m_datePicker, 1, wxCENTRE); m_sizerDatePicker->Add(m_datePicker, 1, wxCENTRE);
m_sizerDatePicker->Add(0, 0, 1, wxCENTRE); m_sizerDatePicker->Add(0, 0, 1, wxCENTRE);

View file

@ -302,6 +302,8 @@ void DirCtrlWidgetsPage::CreateDirCtrl(bool defaultPath)
delete m_dirCtrl; delete m_dirCtrl;
m_dirCtrl = dirCtrl; m_dirCtrl = dirCtrl;
NotifyWidgetRecreation(m_dirCtrl);
// relayout the sizer // relayout the sizer
GetSizer()->Layout(); GetSizer()->Layout();
} }

View file

@ -209,6 +209,8 @@ void DirPickerWidgetsPage::CreatePicker()
wxGetHomeDir(), "Hello!", wxGetHomeDir(), "Hello!",
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
style); style);
NotifyWidgetRecreation(m_dirPicker);
} }
void DirPickerWidgetsPage::RecreatePicker() void DirPickerWidgetsPage::RecreatePicker()

View file

@ -198,6 +198,8 @@ void EditableListboxWidgetsPage::CreateLbox()
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
flags); flags);
NotifyWidgetRecreation(m_lbox);
m_lbox->SetStrings(items); m_lbox->SetStrings(items);
m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5); m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5);
m_sizerLbox->Layout(); m_sizerLbox->Layout();

View file

@ -275,6 +275,8 @@ void FileCtrlWidgetsPage::CreateFileCtrl()
delete m_fileCtrl; delete m_fileCtrl;
m_fileCtrl = fileCtrl; m_fileCtrl = fileCtrl;
NotifyWidgetRecreation(m_fileCtrl);
// relayout the sizer // relayout the sizer
GetSizer()->Layout(); GetSizer()->Layout();
} }

View file

@ -248,6 +248,8 @@ void FilePickerWidgetsPage::CreatePicker()
"Hello!", "*", "Hello!", "*",
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
style); style);
NotifyWidgetRecreation(m_filePicker);
} }
void FilePickerWidgetsPage::RecreatePicker() void FilePickerWidgetsPage::RecreatePicker()

View file

@ -186,6 +186,8 @@ void FontPickerWidgetsPage::CreatePicker()
*wxSWISS_FONT, *wxSWISS_FONT,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
style); style);
NotifyWidgetRecreation(m_fontPicker);
} }
void FontPickerWidgetsPage::RecreatePicker() void FontPickerWidgetsPage::RecreatePicker()

View file

@ -307,6 +307,9 @@ void GaugeWidgetsPage::CreateGauge()
m_gauge = new wxGauge(this, GaugePage_Gauge, m_range, m_gauge = new wxGauge(this, GaugePage_Gauge, m_range,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
flags); flags);
NotifyWidgetRecreation(m_gauge);
m_gauge->SetValue(val); m_gauge->SetValue(val);
if ( flags & wxGA_VERTICAL ) if ( flags & wxGA_VERTICAL )

View file

@ -200,6 +200,8 @@ void HeaderCtrlWidgetsPage::RecreateWidget()
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
flags); flags);
NotifyWidgetRecreation(m_header);
m_header->Bind(wxEVT_HEADER_RESIZING, &HeaderCtrlWidgetsPage::OnResizing, this); m_header->Bind(wxEVT_HEADER_RESIZING, &HeaderCtrlWidgetsPage::OnResizing, this);
m_header->Bind(wxEVT_HEADER_BEGIN_RESIZE, &HeaderCtrlWidgetsPage::OnBeginResize, this); m_header->Bind(wxEVT_HEADER_BEGIN_RESIZE, &HeaderCtrlWidgetsPage::OnBeginResize, this);
m_header->Bind(wxEVT_HEADER_END_RESIZE, &HeaderCtrlWidgetsPage::OnEndResize, this); m_header->Bind(wxEVT_HEADER_END_RESIZE, &HeaderCtrlWidgetsPage::OnEndResize, this);

View file

@ -288,6 +288,8 @@ void HyperlinkWidgetsPage::CreateHyperlink()
delete m_hyperlink; delete m_hyperlink;
m_hyperlink = hyp; m_hyperlink = hyp;
NotifyWidgetRecreation(m_hyperlink);
// relayout the sizer // relayout the sizer
GetSizer()->Layout(); GetSizer()->Layout();
} }

View file

@ -506,6 +506,8 @@ void ListboxWidgetsPage::CreateLbox()
flags); flags);
} }
NotifyWidgetRecreation(m_lbox);
m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5); m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5);
m_sizerLbox->Layout(); m_sizerLbox->Layout();
} }

View file

@ -308,6 +308,8 @@ void NativeWidgetsPage::RecreateWidget()
delete m_nativeWindow; delete m_nativeWindow;
m_nativeWindow = new NativeWindow(this); m_nativeWindow = new NativeWindow(this);
NotifyWidgetRecreation(m_nativeWindow);
m_sizerCtrl->Clear(); m_sizerCtrl->Clear();
if ( m_chkExpand->IsChecked() ) if ( m_chkExpand->IsChecked() )
{ {

View file

@ -365,6 +365,8 @@ void BookWidgetsPage::RecreateBook()
m_book = CreateBook(flags); m_book = CreateBook(flags);
NotifyWidgetRecreation(m_book);
CreateImageList(); CreateImageList();
if ( oldBook ) if ( oldBook )

View file

@ -527,6 +527,8 @@ void ODComboboxWidgetsPage::CreateCombo()
0, nullptr, 0, nullptr,
flags); flags);
NotifyWidgetRecreation(m_combobox);
unsigned int count = items.GetCount(); unsigned int count = items.GetCount();
for ( unsigned int n = 0; n < count; n++ ) for ( unsigned int n = 0; n < count; n++ )
{ {

View file

@ -358,6 +358,8 @@ void RadioWidgetsPage::CreateRadio()
majorDim, majorDim,
flags); flags);
NotifyWidgetRecreation(m_radio);
if ( sel >= 0 && (size_t)sel < count ) if ( sel >= 0 && (size_t)sel < count )
{ {
m_radio->SetSelection(sel); m_radio->SetSelection(sel);

View file

@ -178,6 +178,8 @@ void SearchCtrlWidgetsPage::CreateControl()
m_srchCtrl = new wxSearchCtrl(this, -1, wxEmptyString, wxDefaultPosition, m_srchCtrl = new wxSearchCtrl(this, -1, wxEmptyString, wxDefaultPosition,
FromDIP(wxSize(150, -1)), style); FromDIP(wxSize(150, -1)), style);
NotifyWidgetRecreation(m_srchCtrl);
} }
void SearchCtrlWidgetsPage::RecreateWidget() void SearchCtrlWidgetsPage::RecreateWidget()

View file

@ -517,6 +517,8 @@ void SliderWidgetsPage::CreateSlider()
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
flags); flags);
NotifyWidgetRecreation(m_slider);
if ( m_slider->HasFlag(wxSL_VERTICAL) ) if ( m_slider->HasFlag(wxSL_VERTICAL) )
{ {
m_sizerSlider->AddStretchSpacer(1); m_sizerSlider->AddStretchSpacer(1);

View file

@ -416,6 +416,8 @@ void SpinBtnWidgetsPage::CreateSpin()
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
flags); flags);
NotifyWidgetRecreation(m_spinbtn);
m_spinbtn->SetValue(val); m_spinbtn->SetValue(val);
m_spinbtn->SetRange(m_min, m_max); m_spinbtn->SetRange(m_min, m_max);
@ -425,12 +427,16 @@ void SpinBtnWidgetsPage::CreateSpin()
flags | textFlags, flags | textFlags,
m_min, m_max, val); m_min, m_max, val);
NotifyWidgetRecreation(m_spinctrl);
m_spinctrldbl = new wxSpinCtrlDouble(this, SpinBtnPage_SpinCtrlDouble, m_spinctrldbl = new wxSpinCtrlDouble(this, SpinBtnPage_SpinCtrlDouble,
wxString::Format("%d", val), wxString::Format("%d", val),
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
flags | textFlags, flags | textFlags,
m_min, m_max, val, 0.1); m_min, m_max, val, 0.1);
NotifyWidgetRecreation(m_spinctrldbl);
// Add spacers, labels and spin controls to the sizer. // Add spacers, labels and spin controls to the sizer.
m_sizerSpin->Add(0, 0, 1); m_sizerSpin->Add(0, 0, 1);
m_sizerSpin->Add(new wxStaticText(this, wxID_ANY, "wxSpinButton"), m_sizerSpin->Add(new wxStaticText(this, wxID_ANY, "wxSpinButton"),

View file

@ -161,6 +161,8 @@ void StatBmpWidgetsPage::RecreateWidget()
style); style);
} }
NotifyWidgetRecreation(m_statbmp);
wxStaticBitmapBase::ScaleMode scaleMode = (wxStaticBitmapBase::ScaleMode) m_scaleRadio->GetSelection(); wxStaticBitmapBase::ScaleMode scaleMode = (wxStaticBitmapBase::ScaleMode) m_scaleRadio->GetSelection();
m_statbmp->SetScaleMode(scaleMode); m_statbmp->SetScaleMode(scaleMode);
if ( m_statbmp->GetScaleMode() != scaleMode ) if ( m_statbmp->GetScaleMode() != scaleMode )

View file

@ -525,9 +525,13 @@ void StaticWidgetsPage::CreateStatic()
#endif // wxUSE_MARKUP #endif // wxUSE_MARKUP
} }
NotifyWidgetRecreation(m_statText);
m_statText->SetToolTip("Tooltip for a label inside the box"); m_statText->SetToolTip("Tooltip for a label inside the box");
#if wxUSE_MARKUP #if wxUSE_MARKUP
NotifyWidgetRecreation(m_statMarkup);
m_statMarkup->SetLabelMarkup(m_textLabelWithMarkup->GetValue()); m_statMarkup->SetLabelMarkup(m_textLabelWithMarkup->GetValue());
if ( m_chkGreen->GetValue() ) if ( m_chkGreen->GetValue() )
@ -538,6 +542,8 @@ void StaticWidgetsPage::CreateStatic()
m_statLine = new wxStaticLine(staticBox, wxID_ANY, m_statLine = new wxStaticLine(staticBox, wxID_ANY,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
isVert ? wxLI_VERTICAL : wxLI_HORIZONTAL); isVert ? wxLI_VERTICAL : wxLI_HORIZONTAL);
NotifyWidgetRecreation(m_statLine);
#endif // wxUSE_STATLINE #endif // wxUSE_STATLINE
m_sizerStatBox->Add(m_statText, 0, wxGROW); m_sizerStatBox->Add(m_statText, 0, wxGROW);

View file

@ -787,6 +787,8 @@ void TextWidgetsPage::CreateText()
m_text = new WidgetsTextCtrl(m_sizerText->GetStaticBox(), TextPage_Textctrl, valueOld, flags); m_text = new WidgetsTextCtrl(m_sizerText->GetStaticBox(), TextPage_Textctrl, valueOld, flags);
NotifyWidgetRecreation(m_text);
#if 0 #if 0
if ( m_chkFilename->GetValue() ) if ( m_chkFilename->GetValue() )
; ;

View file

@ -198,6 +198,8 @@ void TimePickerWidgetsPage::CreateTimePicker()
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
style); style);
NotifyWidgetRecreation(m_timePicker);
m_sizerTimePicker->Add(0, 0, 1, wxCENTRE); m_sizerTimePicker->Add(0, 0, 1, wxCENTRE);
m_sizerTimePicker->Add(m_timePicker, 1, wxCENTRE); m_sizerTimePicker->Add(m_timePicker, 1, wxCENTRE);
m_sizerTimePicker->Add(0, 0, 1, wxCENTRE); m_sizerTimePicker->Add(0, 0, 1, wxCENTRE);

View file

@ -461,6 +461,9 @@ void ToggleWidgetsPage::CreateToggle()
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
flags); flags);
} }
NotifyWidgetRecreation(m_toggle);
m_toggle->SetValue(value); m_toggle->SetValue(value);
#ifdef wxHAS_BITMAPTOGGLEBUTTON #ifdef wxHAS_BITMAPTOGGLEBUTTON

View file

@ -257,8 +257,6 @@ protected:
WidgetsPage *CurrentPage(); WidgetsPage *CurrentPage();
private: private:
void ConnectToWidgetEvents();
// the panel containing everything // the panel containing everything
wxPanel *m_panel; wxPanel *m_panel;
@ -773,23 +771,6 @@ WidgetsPage *WidgetsFrame::CurrentPage()
return wxStaticCast(page, WidgetsPage); return wxStaticCast(page, WidgetsPage);
} }
void WidgetsFrame::ConnectToWidgetEvents()
{
auto& app = wxGetApp();
const Widgets& widgets = CurrentPage()->GetWidgets();
for ( Widgets::const_iterator it = widgets.begin();
it != widgets.end();
++it )
{
wxWindow* const w = *it;
wxCHECK_RET(w, "null widget");
app.ConnectToWidgetEvents(w);
}
}
WidgetsFrame::~WidgetsFrame() WidgetsFrame::~WidgetsFrame()
{ {
#if USE_LOG #if USE_LOG
@ -847,7 +828,18 @@ void WidgetsFrame::OnPageChanged(WidgetsBookCtrlEvent& event)
curPage->SetScrollRate(10, 10); curPage->SetScrollRate(10, 10);
curPage->FitInside(); curPage->FitInside();
ConnectToWidgetEvents(); auto& app = wxGetApp();
for ( const auto w : CurrentPage()->GetWidgets() )
{
app.ConnectToWidgetEvents(w);
}
// From now on, we're interested in these notifications as we'll need
// to reconnect to the widget events if it's recreated (unfortunately
// we can't rely getting them on creation as some page don't generate
// them -- but neither can we rely on not getting them as some pages do
// generate them, hence the use of m_notifyRecreate flag).
curPage->EnableRecreationNotifications();
} }
// re-apply the attributes to the widget(s) // re-apply the attributes to the widget(s)
@ -1016,11 +1008,6 @@ void WidgetsFrame::OnSetBorder(wxCommandEvent& event)
WidgetsPage *page = CurrentPage(); WidgetsPage *page = CurrentPage();
page->RecreateWidget(); page->RecreateWidget();
ConnectToWidgetEvents();
// re-apply the attributes to the widget(s)
page->SetUpWidget();
} }
void WidgetsFrame::OnSetVariant(wxCommandEvent& event) void WidgetsFrame::OnSetVariant(wxCommandEvent& event)
@ -1482,6 +1469,19 @@ wxCheckBox *WidgetsPage::CreateCheckBoxAndAddToSizer(wxSizer *sizer,
return checkbox; return checkbox;
} }
void WidgetsPage::NotifyWidgetRecreation(wxWindow* widget)
{
if ( !m_notifyRecreate )
{
// We're in the process of initialization, don't notify yet.
return;
}
SetUpWidget();
wxGetApp().ConnectToWidgetEvents(widget);
}
/* static */ /* static */
bool WidgetsPage::IsUsingLogWindow() bool WidgetsPage::IsUsingLogWindow()
{ {

View file

@ -149,6 +149,13 @@ public:
// this is currently used only to take into account the border flags // this is currently used only to take into account the border flags
virtual void RecreateWidget() = 0; virtual void RecreateWidget() = 0;
// notify the main window about the widget recreation if it didn't happen
// due to a call to RecreateWidget()
void NotifyWidgetRecreation(wxWindow* widget);
// enable notifications about the widget recreation disabled initially
void EnableRecreationNotifications() { m_notifyRecreate = true; }
// apply current attributes to the widget(s) // apply current attributes to the widget(s)
void SetUpWidget(); void SetUpWidget();
@ -191,6 +198,9 @@ protected:
public: public:
// the head of the linked list containinginfo about all pages // the head of the linked list containinginfo about all pages
static WidgetsPageInfo *ms_widgetPages; static WidgetsPageInfo *ms_widgetPages;
private:
bool m_notifyRecreate = false;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------