From 65e124bb645427e135590a7379512d1b9ac1229d Mon Sep 17 00:00:00 2001 From: Ian McInerney Date: Thu, 20 Aug 2020 23:10:42 +0100 Subject: [PATCH 1/4] Add a flag to wxUpdateUIEvent to tell if the item supports the check action Not all items support check being set in an UpdateUIEvent handler, so it is nice to provide an API to find out if the item supports it. Fixes #13369 --- include/wx/event.h | 9 ++++++++- interface/wx/event.h | 7 +++++++ src/aui/auibar.cpp | 3 +++ src/common/menucmn.cpp | 1 + src/common/tbarbase.cpp | 1 + src/common/wincmn.cpp | 1 + src/osx/menu_osx.cpp | 5 +++++ src/ribbon/buttonbar.cpp | 1 + src/ribbon/toolbar.cpp | 1 + 9 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/wx/event.h b/include/wx/event.h index f4477868b1..6f0128c76d 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -2891,10 +2891,12 @@ public: m_setEnabled = m_setShown = m_setText = - m_setChecked = false; + m_setChecked = + m_isCheckable = false; } wxUpdateUIEvent(const wxUpdateUIEvent& event) : wxCommandEvent(event), + m_isCheckable(event.m_isCheckable), m_checked(event.m_checked), m_enabled(event.m_enabled), m_shown(event.m_shown), @@ -2919,6 +2921,10 @@ public: void Show(bool show) { m_shown = show; m_setShown = true; } void SetText(const wxString& text) { m_text = text; m_setText = true; } + // Set a flag saying if the object being updated supports the check action + bool IsCheckable() const { return m_isCheckable; } + void SetIsCheckable(bool aCheckable) { m_isCheckable = aCheckable; } + // Sets the interval between updates in milliseconds. // Set to -1 to disable updates, or to 0 to update as frequently as possible. static void SetUpdateInterval(long updateInterval) { sm_updateInterval = updateInterval; } @@ -2944,6 +2950,7 @@ public: virtual wxEvent *Clone() const wxOVERRIDE { return new wxUpdateUIEvent(*this); } protected: + bool m_isCheckable; bool m_checked; bool m_enabled; bool m_shown; diff --git a/interface/wx/event.h b/interface/wx/event.h index ff18c94bb1..d2683e5970 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -2374,6 +2374,13 @@ public: */ bool GetEnabled() const; + /** + Returns @true if the UI element can be checked. + + @since 3.1.5 + */ + bool IsCheckable() const; + /** Static function returning a value specifying how wxWidgets will send update events: to all windows, or only to those which specify that they will process diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index f97bf53adb..83f022371e 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -2200,6 +2200,9 @@ void wxAuiToolBar::DoIdleUpdate() wxUpdateUIEvent evt(item.m_toolId); evt.SetEventObject(this); + if ( item.m_kind == wxITEM_CHECK || item.m_kind == wxITEM_RADIO ) + evt.SetIsCheckable(true); + if (handler->ProcessEvent(evt)) { if (evt.GetSetEnabled()) diff --git a/src/common/menucmn.cpp b/src/common/menucmn.cpp index 73e0568c50..da51fc32b1 100644 --- a/src/common/menucmn.cpp +++ b/src/common/menucmn.cpp @@ -616,6 +616,7 @@ void wxMenuBase::UpdateUI(wxEvtHandler* source) wxWindowID itemid = item->GetId(); wxUpdateUIEvent event(itemid); event.SetEventObject( this ); + event.SetIsCheckable(item->IsCheckable()); if ( source->ProcessEvent(event) ) { diff --git a/src/common/tbarbase.cpp b/src/common/tbarbase.cpp index 3c2a6e99a7..285a5ddb8f 100644 --- a/src/common/tbarbase.cpp +++ b/src/common/tbarbase.cpp @@ -738,6 +738,7 @@ void wxToolBarBase::UpdateWindowUI(long flags) wxUpdateUIEvent event(toolid); event.SetEventObject(this); + event.SetIsCheckable(tool->CanBeToggled()); if ( evtHandler->ProcessEvent(event) ) { diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 9b2e522920..2aca66e556 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -2817,6 +2817,7 @@ void wxWindowBase::UpdateWindowUI(long flags) { wxUpdateUIEvent event(GetId()); event.SetEventObject(this); + event.SetIsCheckable(true); if ( GetEventHandler()->ProcessEvent(event) ) { diff --git a/src/osx/menu_osx.cpp b/src/osx/menu_osx.cpp index 712f2a95d9..3c8552ffa4 100644 --- a/src/osx/menu_osx.cpp +++ b/src/osx/menu_osx.cpp @@ -324,6 +324,11 @@ bool wxMenu::HandleCommandUpdateStatus( wxMenuItem* item, wxWindow* senderWindow wxUpdateUIEvent event(menuid); event.SetEventObject( this ); + if ( item ) + event.SetIsCheckable(item->IsCheckable()); + else + event.SetIsCheckable(true); + bool processed = DoProcessEvent(this, event, GetWindow()); if ( !processed && senderWindow != NULL) diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 7e631d88a0..52751002fa 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -905,6 +905,7 @@ void wxRibbonButtonBar::UpdateWindowUI(long flags) wxUpdateUIEvent event(id); event.SetEventObject(this); + event.SetIsCheckable(true); if ( ProcessWindowEvent(event) ) { diff --git a/src/ribbon/toolbar.cpp b/src/ribbon/toolbar.cpp index ec6c2e0054..dffc8147c4 100644 --- a/src/ribbon/toolbar.cpp +++ b/src/ribbon/toolbar.cpp @@ -1178,6 +1178,7 @@ void wxRibbonToolBar::UpdateWindowUI(long flags) wxUpdateUIEvent event(id); event.SetEventObject(this); + event.SetIsCheckable(true); if ( ProcessWindowEvent(event) ) { From afbb334a263c6a9e73abe0dec5ad185b94cc9b15 Mon Sep 17 00:00:00 2001 From: Ian McInerney Date: Fri, 21 Aug 2020 23:15:38 +0100 Subject: [PATCH 2/4] Make IsCheckable true by default and switch to explicitly disallowing it Also add a new accessor to wxAuiToolBarItem to make it easier to determine when a tool can be checked. --- include/wx/aui/auibar.h | 5 +++++ include/wx/event.h | 12 ++++++------ interface/wx/aui/auibar.h | 7 +++++++ src/aui/auibar.cpp | 4 ++-- src/common/menucmn.cpp | 4 +++- src/common/tbarbase.cpp | 4 +++- src/common/wincmn.cpp | 1 - src/osx/menu_osx.cpp | 6 ++---- src/ribbon/buttonbar.cpp | 1 - src/ribbon/toolbar.cpp | 1 - 10 files changed, 28 insertions(+), 17 deletions(-) diff --git a/include/wx/aui/auibar.h b/include/wx/aui/auibar.h index 6b612b545a..2e2f3e3a52 100644 --- a/include/wx/aui/auibar.h +++ b/include/wx/aui/auibar.h @@ -211,6 +211,11 @@ public: void SetAlignment(int l) { m_alignment = l; } int GetAlignment() const { return m_alignment; } + bool CanBeToggled() const + { + return m_kind == wxITEM_CHECK || m_kind == wxITEM_RADIO; + } + private: wxWindow* m_window; // item's associated window diff --git a/include/wx/event.h b/include/wx/event.h index 6f0128c76d..5042ada638 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -2891,12 +2891,11 @@ public: m_setEnabled = m_setShown = m_setText = - m_setChecked = - m_isCheckable = false; + m_setChecked = false; + m_isCheckable = true; } wxUpdateUIEvent(const wxUpdateUIEvent& event) : wxCommandEvent(event), - m_isCheckable(event.m_isCheckable), m_checked(event.m_checked), m_enabled(event.m_enabled), m_shown(event.m_shown), @@ -2904,6 +2903,7 @@ public: m_setShown(event.m_setShown), m_setText(event.m_setText), m_setChecked(event.m_setChecked), + m_isCheckable(event.m_isCheckable), m_text(event.m_text) { } @@ -2921,9 +2921,9 @@ public: void Show(bool show) { m_shown = show; m_setShown = true; } void SetText(const wxString& text) { m_text = text; m_setText = true; } - // Set a flag saying if the object being updated supports the check action + // A flag saying if the item can be checked. True by default. bool IsCheckable() const { return m_isCheckable; } - void SetIsCheckable(bool aCheckable) { m_isCheckable = aCheckable; } + void DisallowCheck() { m_isCheckable = false; } // Sets the interval between updates in milliseconds. // Set to -1 to disable updates, or to 0 to update as frequently as possible. @@ -2950,7 +2950,6 @@ public: virtual wxEvent *Clone() const wxOVERRIDE { return new wxUpdateUIEvent(*this); } protected: - bool m_isCheckable; bool m_checked; bool m_enabled; bool m_shown; @@ -2958,6 +2957,7 @@ protected: bool m_setShown; bool m_setText; bool m_setChecked; + bool m_isCheckable; wxString m_text; #if wxUSE_LONGLONG static wxLongLong sm_lastUpdate; diff --git a/interface/wx/aui/auibar.h b/interface/wx/aui/auibar.h index 2c118bd19b..5d2e640272 100644 --- a/interface/wx/aui/auibar.h +++ b/interface/wx/aui/auibar.h @@ -407,6 +407,13 @@ public: */ int GetAlignment() const; + + /** + Returns whether the toolbar item can be toggled. + + @since 3.1.5 + */ + bool CanBeToggled() const; }; /** diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 83f022371e..6956e652cd 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -2200,8 +2200,8 @@ void wxAuiToolBar::DoIdleUpdate() wxUpdateUIEvent evt(item.m_toolId); evt.SetEventObject(this); - if ( item.m_kind == wxITEM_CHECK || item.m_kind == wxITEM_RADIO ) - evt.SetIsCheckable(true); + if ( !item.CanBeToggled() ) + evt.DisallowCheck(); if (handler->ProcessEvent(evt)) { diff --git a/src/common/menucmn.cpp b/src/common/menucmn.cpp index da51fc32b1..f70e85e002 100644 --- a/src/common/menucmn.cpp +++ b/src/common/menucmn.cpp @@ -616,7 +616,9 @@ void wxMenuBase::UpdateUI(wxEvtHandler* source) wxWindowID itemid = item->GetId(); wxUpdateUIEvent event(itemid); event.SetEventObject( this ); - event.SetIsCheckable(item->IsCheckable()); + + if ( !item->IsCheckable() ) + event.DisallowCheck(); if ( source->ProcessEvent(event) ) { diff --git a/src/common/tbarbase.cpp b/src/common/tbarbase.cpp index 285a5ddb8f..c44dfdf175 100644 --- a/src/common/tbarbase.cpp +++ b/src/common/tbarbase.cpp @@ -738,7 +738,9 @@ void wxToolBarBase::UpdateWindowUI(long flags) wxUpdateUIEvent event(toolid); event.SetEventObject(this); - event.SetIsCheckable(tool->CanBeToggled()); + + if ( !tool->CanBeToggled() ) + event.DisallowCheck(); if ( evtHandler->ProcessEvent(event) ) { diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 2aca66e556..9b2e522920 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -2817,7 +2817,6 @@ void wxWindowBase::UpdateWindowUI(long flags) { wxUpdateUIEvent event(GetId()); event.SetEventObject(this); - event.SetIsCheckable(true); if ( GetEventHandler()->ProcessEvent(event) ) { diff --git a/src/osx/menu_osx.cpp b/src/osx/menu_osx.cpp index 3c8552ffa4..df85dc2c89 100644 --- a/src/osx/menu_osx.cpp +++ b/src/osx/menu_osx.cpp @@ -324,10 +324,8 @@ bool wxMenu::HandleCommandUpdateStatus( wxMenuItem* item, wxWindow* senderWindow wxUpdateUIEvent event(menuid); event.SetEventObject( this ); - if ( item ) - event.SetIsCheckable(item->IsCheckable()); - else - event.SetIsCheckable(true); + if ( !item || !item->IsCheckable() ) + event.DisallowCheck(); bool processed = DoProcessEvent(this, event, GetWindow()); diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 52751002fa..7e631d88a0 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -905,7 +905,6 @@ void wxRibbonButtonBar::UpdateWindowUI(long flags) wxUpdateUIEvent event(id); event.SetEventObject(this); - event.SetIsCheckable(true); if ( ProcessWindowEvent(event) ) { diff --git a/src/ribbon/toolbar.cpp b/src/ribbon/toolbar.cpp index dffc8147c4..ec6c2e0054 100644 --- a/src/ribbon/toolbar.cpp +++ b/src/ribbon/toolbar.cpp @@ -1178,7 +1178,6 @@ void wxRibbonToolBar::UpdateWindowUI(long flags) wxUpdateUIEvent event(id); event.SetEventObject(this); - event.SetIsCheckable(true); if ( ProcessWindowEvent(event) ) { From c0bfaf4104fc09ac0dfac069ce783d55ef48bca7 Mon Sep 17 00:00:00 2001 From: Ian McInerney Date: Fri, 21 Aug 2020 23:29:08 +0100 Subject: [PATCH 3/4] Use new CanBeToggled function inside wxAuiToolBar where appropriate --- src/aui/auibar.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 6956e652cd..eacb77e7be 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -1546,7 +1546,7 @@ void wxAuiToolBar::ToggleTool(int tool_id, bool state) { wxAuiToolBarItem* tool = FindTool(tool_id); - if (tool && (tool->m_kind == wxITEM_CHECK || tool->m_kind == wxITEM_RADIO)) + if ( tool && tool->CanBeToggled() ) { if (tool->m_kind == wxITEM_RADIO) { @@ -1587,13 +1587,8 @@ bool wxAuiToolBar::GetToolToggled(int tool_id) const { wxAuiToolBarItem* tool = FindTool(tool_id); - if (tool) - { - if ( (tool->m_kind != wxITEM_CHECK) && (tool->m_kind != wxITEM_RADIO) ) - return false; - + if ( tool && tool->CanBeToggled() ) return (tool->m_state & wxAUI_BUTTON_STATE_CHECKED) ? true : false; - } return false; } From 7be693212c3cfb2434b25a89a3a8c8dc6ea94b95 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 2 Sep 2020 19:33:39 +0200 Subject: [PATCH 4/4] Improve documentation of wxUpdateUIEvent::IsCheckable() Explain when this method can be useful. --- interface/wx/event.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/interface/wx/event.h b/interface/wx/event.h index d2683e5970..061c5de997 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -2377,6 +2377,19 @@ public: /** Returns @true if the UI element can be checked. + For the event handlers that can be used for multiple items, not all of + which can be checked, this method can be useful to determine whether + to call Check() on the event object or not, i.e. the main use case for + this method is: + @code + void MyWindow::OnUpdateUI(wxUpdateUIEvent& event) + { + .... + if ( event.IsCheckable() ) + event.Check(...some condition...); + } + @endcode + @since 3.1.5 */ bool IsCheckable() const;