forked from cheng/wallet
137a78735b
Painfully discovered that wxWidgets does not like it if you do not handle the close event. Default handling is broken, perhaps unavoidably because the base object does not know about the derived object.
97 lines
2.8 KiB
C++
97 lines
2.8 KiB
C++
#pragma once
|
|
template <typename T>
|
|
// 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
|
|
{
|
|
public:
|
|
wxLogWindow*m_pLogWindow{ nullptr };
|
|
std::unique_ptr<wxLogNull>m_pLogNull{ nullptr };
|
|
Frame(wxString);
|
|
~Frame();
|
|
wxFileName m_LastUsedSqlite;
|
|
wxPanel* m_panel{nullptr}; //The once current child panel.
|
|
private:
|
|
typedef MenuLink<Frame> MenuLink;
|
|
void StorePositionToConfig(void);
|
|
void RestorePositionFromConfig(const wxSize&);
|
|
void OnExit(wxCommandEvent&);
|
|
void OnClose(wxCloseEvent&);
|
|
void OnAbout(wxCommandEvent&);
|
|
void OnDeleteConfiguration(wxCommandEvent&);
|
|
void OnMyCloseMpanel(wxCommandEvent&);
|
|
|
|
public:
|
|
void OnSaveNew(wxCommandEvent&);
|
|
void NewWalletNewSecret(wxCommandEvent&);
|
|
void RecreateWalletFromExistingSecret(wxCommandEvent&);
|
|
void OnFileOpen(wxCommandEvent&);
|
|
|
|
private:
|
|
void OnDelete(wxCommandEvent&);
|
|
void OnMenuOpen(wxMenuEvent&);
|
|
public:
|
|
void OnFirstUse(wxCommandEvent&);
|
|
|
|
public:
|
|
// MenuLink menu_OnFirstUse =
|
|
// MenuLink(&Frame::OnFirstUse, myID_WELCOME_TO_ROCOIN);
|
|
};
|
|
|
|
extern Frame* singletonFrame;
|
|
|