diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:18:53 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:18:53 +0200 |
commit | 32cb97237e7691d31977ab503c6ea4511e8eb3a8 (patch) | |
tree | 4e97b53e9f7b74e8cc5d7548507d9e82ae38e36f /wx+/context_menu.h | |
parent | 4.6 (diff) | |
download | FreeFileSync-32cb97237e7691d31977ab503c6ea4511e8eb3a8.tar.gz FreeFileSync-32cb97237e7691d31977ab503c6ea4511e8eb3a8.tar.bz2 FreeFileSync-32cb97237e7691d31977ab503c6ea4511e8eb3a8.zip |
5.0
Diffstat (limited to 'wx+/context_menu.h')
-rw-r--r-- | wx+/context_menu.h | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/wx+/context_menu.h b/wx+/context_menu.h new file mode 100644 index 00000000..894da832 --- /dev/null +++ b/wx+/context_menu.h @@ -0,0 +1,81 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved * +// ************************************************************************** + +#ifndef CONTEXT_HEADER_18047302153418174632141234 +#define CONTEXT_HEADER_18047302153418174632141234 + +#include <vector> +#include <functional> +#include <wx/menu.h> +#include <wx/app.h> + +/* +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.popup(wnd); +*/ + +namespace zen +{ +class ContextMenu : private wxEvtHandler +{ +public: + void addItem(const wxString& label, const std::function<void()>& command, const wxBitmap* bmp = NULL, bool enabled = true) + { + wxMenuItem* newItem = new wxMenuItem(&menu, wxID_ANY, label); + if (bmp) newItem->SetBitmap(*bmp); + if (!enabled) newItem->Enable(false); + menu.Append(newItem); //do NOT append item before setting bitmap! 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); + } + + void addCheckBox(const wxString& label, const std::function<void()>& command, bool checked, bool enabled = true) + { + 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); + } + + void addRadio(const wxString& label, const std::function<void()>& command, bool checked, bool enabled = true) + { + 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); + } + + void addSeparator() { menu.AppendSeparator(); } + + void popup(wxWindow& wnd) //show popup menu + process lambdas + { + wnd.PopupMenu(&menu); + 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 + } + +private: + void onSelection(wxCommandEvent& event) + { + if (auto cmd = dynamic_cast<GenericCommand*>(event.m_callbackUserData)) + (cmd->fun_)(); + } + + struct GenericCommand : public wxObject + { + GenericCommand(const std::function<void()>& fun) : fun_(fun) {} + std::function<void()> fun_; + }; + + wxMenu menu; +}; +} + +#endif //CONTEXT_HEADER_18047302153418174632141234 |