19#include <wx/eventfilter.h>
21#include <wx/weakref.h>
31using Menus = std::vector< wxWeakRef< wxMenu > >;
39 Menus result{ &menu };
41 for (
size_t ii = 0; ii < result.size(); ++ii ) {
42 if (
auto pMenu = result[ii] ) {
43 for (
const auto &pItem : pMenu->GetMenuItems() ) {
44 if (
const auto pSubMenu = pItem->GetSubMenu() )
45 result.push_back( pSubMenu );
54 return std::count( menus.begin(), menus.end(), pObj );
59std::optional< wxArrayStringEx >
FindPathName( wxMenu &theMenu,
int id )
61 wxMenuItem *pItem =
nullptr;
62 wxMenu *pSubMenu =
nullptr;
63 if ( !( pItem = theMenu.FindItem(
id, &pSubMenu ) ) )
68 for ( ; pSubMenu; pSubMenu = pSubMenu->GetParent() ) {
69 const auto &items = pSubMenu->GetMenuItems();
70 const auto begin = items.begin(),
end = items.end();
71 if ( !
names.empty() ) {
73 if (
const auto iter = std::find_if(
begin,
end,
75 return pNewItem->GetSubMenu() == pItem->GetMenu(); } );
81 auto name = pItem->GetItemLabelText();
82 if ( 1 != std::count_if(
begin,
end, [&](
auto item){
83 return item->GetItemLabelText() ==
name; } ) )
97 wxEvtHandler::AddFilter(
this );
102 wxEvtHandler::RemoveFilter(
this );
112 auto pObj =
event.GetEventObject();
114 event.GetEventType() == wxEVT_MENU &&
120 auto pPath =
FindPathName( *
static_cast<wxMenu*
>(pObj), event.GetId() );
158 if ( fields.size() == 1)
163 auto found = [&]() -> std::pair<wxMenuItem *, wxMenu*> {
164 wxMenuItem *pItem =
nullptr;
165 auto pMenu = theMenu;
166 for (
auto pField = fields.begin() + 1, endFields = fields.end();
167 pMenu && pField != endFields; ++pField ) {
168 auto &
name = *pField;
169 const auto &list = pMenu->GetMenuItems();
170 const auto pred = [&
name](
auto &pItem){
171 return pItem->GetItemLabelText() ==
name; };
172 const auto begin = list.begin(),
end = list.end(),
173 iter = std::find_if(
begin,
end, pred);
176 if (
auto next = iter;
177 end == next ||
end != std::find_if(++next,
end, pred) )
178 return {
nullptr,
nullptr };
181 if ( pField + 1 != endFields )
182 pMenu = pItem->GetSubMenu();
184 return { pItem, pMenu };
187 if (
auto [pItem, pMenu] = found; pItem && pMenu ) {
192 wxCommandEvent
event{ wxEVT_MENU, pItem->GetId() };
193 event.SetEventObject( pMenu );
194 if ( pMenu->ProcessEvent( event ) ) {
203 "PopupMenu has failed to invoke %s",
204 wxJoin(fields,
',').ToStdString().c_str()));
211 wxMenu *
const pMenu =
mpMenu;
220 auto cleanup =
finally( []{
sMenuStack.pop_back(); } );
225 pWindow->PopupMenu( pMenu, { pos.
x, pos.
y } );
The output stream of the journal system.
Journal system's error status, command dictionary, initializers.
void Popup(const BasicUI::WindowPlacement &window, const Point &pos={})
Display the menu at pos, invoke at most one action, then hide it.
Subclasses may hold information such as a parent window pointer for a dialog.
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
void FailedEventSerialization()
Facilities for recording and playback of sequences of user interaction.
wxArrayStringEx GetTokens()
void Output(const wxString &string)
BuiltinEffectsModule::Registration< Reverse > reverse
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept
A pair of screen coordinates, x increasing rightward, y downward.