#pragma once template // This class exists to record the needed to unbind a drop down menu action and delete // the corresponding item from the drop down menu when the handler is destroyed. // (Because the handler is a method of an object that is about to be destroyed.) // Also avoids the need for manually creating a new windowid to link each additional bind // to each menu item, thus avoids the likelihood of mismatching binds and menu entries. class MenuLink { typedef void (T::* method_handler)(wxCommandEvent&); // (thing.*p)(args) is how you use a pointer to method T* m_handler = nullptr; method_handler m_method; int m_winid; wxMenu* m_menu = nullptr; wxMenuItem* m_menuItem = nullptr; public: MenuLink() = delete; MenuLink(const MenuLink&) = default; MenuLink(const MenuLink&&) = delete; MenuLink& operator=(const MenuLink&) = delete; MenuLink& operator=(MenuLink&) = delete; MenuLink(T* handler, method_handler method) : m_handler(handler), m_method{ method }, m_winid{ wxWindow::NewControlId() }{} MenuLink(T* handler, method_handler method, MyIDs winid) : m_handler(handler), m_method{ method }, m_winid{ winid } {} ~MenuLink() { if (m_menu != nullptr) { m_menu->Unbind(wxEVT_MENU, m_method, m_handler, m_winid); m_menu->Destroy(m_menuItem); } } wxMenuItem* Insert( wxMenu* menu, size_t pos, const wxString& item, const wxString& help = wxEmptyString ) { if (m_menu == nullptr) m_menu = menu; else { assert(false); throw MyException("Reinsertion of menu item"); } m_menuItem = menu->Insert(pos, m_winid, item, help); menu->Bind(wxEVT_MENU, m_method, m_handler, m_winid); return m_menuItem; } void queue_event() { if (m_menu != nullptr) { auto event = new wxCommandEvent(wxEVT_MENU, m_winid); wxQueueEvent(m_menu, event); } else { assert(false); throw MyException("Event sent to uninitialized Menu item"); } } }; class Frame : public wxFrame { int m_TipOfTheDayIndex; int m_FileDialogFilterIndex; public: bool m_showTipsAtStartup; wxFileName m_LastUsedWallet; wxFileName m_DefaultWalletLocation; Frame(const wxString& title); virtual ~Frame(); wxLogWindow*m_pLogWindow{ nullptr }; std::unique_ptrm_pLogNull{ nullptr }; wxPanel* m_panel{nullptr}; //The once current child panel. private: typedef MenuLink MenuLink; void StorePositionToConfig(void); void RestorePositionFromConfig(const wxSize&); void OnExit(wxCommandEvent&); void OnAbout(wxCommandEvent&); void OnDeleteConfiguration(wxCommandEvent&); void OnMyCloseMPanel(wxCommandEvent&); public: void OnSaveNew(wxCommandEvent&); void NewWallet(wxFileName&, ristretto255::hash<256>&); void RecreateWalletFromExistingSecret(wxCommandEvent&); void OnFileOpen(wxCommandEvent&); void OnClose(wxCloseEvent& event); private: void OnMenuOpen(wxMenuEvent&); public: void OnFirstUse(wxCommandEvent&); public: // MenuLink menu_OnFirstUse = // MenuLink(&Frame::OnFirstUse, myID_WELCOME_TO_ROCOIN); }; extern Frame* singletonFrame;