Update wxSearchCtrl popup menu state after showing it

Fix the state of the check/radio items in the menu by updating the
template used by macOS to create the actual menu after showing it and
possibly changing the items state.

This is not ideal because changing the state from the program, e.g.
using wxMenuItem::Check(), still doesn't work correctly, i.e. isn't
reflected in the menu when it's shown, but better than nothing until a
better solution (which ideally would update the menu just before showing
it, but it's not clear how exactly can we do it, knowing that we don't
get wxEVT_MENU_OPEN for this menu neither) can be found.
This commit is contained in:
Vadim Zeitlin
2021-04-04 14:21:27 +02:00
parent 7112582f18
commit 0f1d1d2ae9
5 changed files with 26 additions and 2 deletions

View File

@@ -62,6 +62,10 @@ public:
wxSearchWidgetImpl * GetSearchPeer() const; wxSearchWidgetImpl * GetSearchPeer() const;
#if wxUSE_MENUS
virtual void OSXAfterMenuEvent() wxOVERRIDE;
#endif // wxUSE_MENUS
protected: protected:
wxSize DoGetBestSize() const wxOVERRIDE; wxSize DoGetBestSize() const wxOVERRIDE;

View File

@@ -299,6 +299,11 @@ public:
// Return the DPI corresponding to the given scale factor. // Return the DPI corresponding to the given scale factor.
static wxSize OSXMakeDPIFromScaleFactor(double scaleFactor); static wxSize OSXMakeDPIFromScaleFactor(double scaleFactor);
#if wxUSE_MENUS
// Called on the invoking window after handling the menu event.
virtual void OSXAfterMenuEvent() { }
#endif // wxUSE_MENUS
protected: protected:
// For controls like radio buttons which are genuinely composite // For controls like radio buttons which are genuinely composite
wxList m_subControls; wxList m_subControls;

View File

@@ -199,7 +199,7 @@ wxMenu* SearchCtrlWidgetsPage::CreateTestMenu()
{ {
wxString itemText = wxString::Format("item %i",i); wxString itemText = wxString::Format("item %i",i);
wxString tipText = wxString::Format("tip %i",i); wxString tipText = wxString::Format("tip %i",i);
menu->Append(ID_SEARCHMENU+i, itemText, tipText, wxITEM_NORMAL); menu->Append(ID_SEARCHMENU+i, itemText, tipText, wxITEM_CHECK);
} }
return menu; return menu;
} }
@@ -243,7 +243,8 @@ void SearchCtrlWidgetsPage::OnTextEnter(wxCommandEvent& event)
void SearchCtrlWidgetsPage::OnSearchMenu(wxCommandEvent& event) void SearchCtrlWidgetsPage::OnSearchMenu(wxCommandEvent& event)
{ {
int id = event.GetId() - ID_SEARCHMENU; int id = event.GetId() - ID_SEARCHMENU;
wxLogMessage("Search menu: \"item %i\" selected (%s).", id); wxLogMessage("Search menu: \"item %i\" selected (%s).",
id, event.IsChecked() ? "checked" : "unchecked");
} }
void SearchCtrlWidgetsPage::OnSearch(wxCommandEvent& event) void SearchCtrlWidgetsPage::OnSearch(wxCommandEvent& event)

View File

@@ -375,6 +375,12 @@ bool wxMenu::HandleCommandProcess( wxMenuItem* item, wxWindow* senderWindow )
processed = item->GetPeer()->DoDefault(); processed = item->GetPeer()->DoDefault();
} }
if (wxWindow* const w = GetInvokingWindow())
{
// Let the invoking window update itself if necessary.
w->OSXAfterMenuEvent();
}
return processed; return processed;
} }

View File

@@ -119,6 +119,14 @@ wxMenu* wxSearchCtrl::GetMenu()
return m_menu; return m_menu;
} }
void wxSearchCtrl::OSXAfterMenuEvent()
{
// The menu is used as a template for creating the actual menu shown by the
// control, so update this template with the latest menu state after a menu
// command as the state of check/radio items could have changed after it.
GetSearchPeer()->SetSearchMenu( m_menu );
}
#endif // wxUSE_MENUS #endif // wxUSE_MENUS
void wxSearchCtrl::ShowSearchButton( bool show ) void wxSearchCtrl::ShowSearchButton( bool show )