diff options
Diffstat (limited to 'wx+/context_menu.h')
-rw-r--r-- | wx+/context_menu.h | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/wx+/context_menu.h b/wx+/context_menu.h index 8f80fac2..663596f9 100644 --- a/wx+/context_menu.h +++ b/wx+/context_menu.h @@ -7,6 +7,7 @@ #ifndef CONTEXT_HEADER_18047302153418174632141234 #define CONTEXT_HEADER_18047302153418174632141234 +#include <map> #include <vector> #include <functional> #include <wx/menu.h> @@ -17,7 +18,7 @@ A context menu supporting C++11 lambda callbacks! Usage: ContextMenu menu; - menu.addItem(L"Some Label", [&]{ ...do something... }); -> capture by reference is fine, as long as captured variables have at least scope of ContextMenu::show()! + menu.addItem(L"Some Label", [&]{ ...do something... }); -> capture by reference is fine, as long as captured variables have at least scope of ContextMenu::popup()! ... menu.popup(wnd); */ @@ -27,36 +28,52 @@ namespace zen class ContextMenu : private wxEvtHandler { public: + ContextMenu() : menu(new wxMenu) {} + void addItem(const wxString& label, const std::function<void()>& command, const wxBitmap* bmp = nullptr, bool enabled = true) { - wxMenuItem* newItem = new wxMenuItem(&menu, wxID_ANY, label); + wxMenuItem* newItem = new wxMenuItem(menu.get(), wxID_ANY, label); //menu owns item! if (bmp) newItem->SetBitmap(*bmp); //do not set AFTER appending item! wxWidgets screws up for yet another crappy reason - menu.Append(newItem); + menu->Append(newItem); if (!enabled) newItem->Enable(false); //do not enable BEFORE appending item! wxWidgets screws up for yet another crappy reason - menu.Connect(newItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(ContextMenu::onSelection), new GenericCommand(command), /*pass ownership*/ this); + commandList[newItem->GetId()] = command; //defer event connection, this may be a submenu only! } void addCheckBox(const wxString& label, const std::function<void()>& command, bool checked, bool enabled = true) { - wxMenuItem* newItem = menu.AppendCheckItem(wxID_ANY, label); + wxMenuItem* newItem = menu->AppendCheckItem(wxID_ANY, label); newItem->Check(checked); if (!enabled) newItem->Enable(false); - menu.Connect(newItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(ContextMenu::onSelection), new GenericCommand(command), /*pass ownership*/ this); + commandList[newItem->GetId()] = command; } void addRadio(const wxString& label, const std::function<void()>& command, bool checked, bool enabled = true) { - wxMenuItem* newItem = menu.AppendRadioItem(wxID_ANY, label); + wxMenuItem* newItem = menu->AppendRadioItem(wxID_ANY, label); newItem->Check(checked); if (!enabled) newItem->Enable(false); - menu.Connect(newItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(ContextMenu::onSelection), new GenericCommand(command), /*pass ownership*/ this); + commandList[newItem->GetId()] = command; } - void addSeparator() { menu.AppendSeparator(); } + void addSeparator() { menu->AppendSeparator(); } + + void addSubmenu(const wxString& label, ContextMenu& submenu, const wxBitmap* bmp = nullptr) //invalidates submenu! + { + wxMenuItem* newItem = new wxMenuItem(menu.get(), wxID_ANY, label, L"", wxITEM_NORMAL, submenu.menu.release()); //menu owns item! + if (bmp) newItem->SetBitmap(*bmp); //do not set AFTER appending item! wxWidgets screws up for yet another crappy reason + menu->Append(newItem); + //transfer submenu commands: + commandList.insert(submenu.commandList.begin(), submenu.commandList.end()); + submenu.commandList.clear(); + } void popup(wxWindow& wnd) //show popup menu + process lambdas { - wnd.PopupMenu(&menu); + //eventually all events from submenu items will be received by this menu + for (auto iter = commandList.begin(); iter != commandList.end(); ++iter) + menu->Connect(iter->first, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(ContextMenu::onSelection), new GenericCommand(iter->second), /*pass ownership*/ this); + + wnd.PopupMenu(menu.get()); wxTheApp->ProcessPendingEvents(); //make sure lambdas are evaluated before going out of scope; //although all events seem to be processed within wxWindows::PopupMenu, we shouldn't trust wxWidgets in this regard } @@ -74,7 +91,8 @@ private: std::function<void()> fun_; }; - wxMenu menu; + std::unique_ptr<wxMenu> menu; + std::map<int, std::function<void()>> commandList; //(item id, command) }; } |