forked from cheng/wallet
35a3be9aa7
the sqlite view capability VIEW UserZookoIDs Made add_name responsive, but add_name still does not use the VIEW triggers. Got distracted by sizing issues. There is some issues with resizing architecture - I know they put an ad hoc workaround in on dialogs, need to read up on what they did and why.
133 lines
4.7 KiB
C++
133 lines
4.7 KiB
C++
#pragma once
|
|
// wxWidgets has drop down menus, wxMenu, owned by the wxMenuBar,
|
|
// which is owned by the Frame window, but menus subject to replacement need
|
|
// to be destroyed by the child window.
|
|
// wxMenuOwner tracks a drop down menu that might be at a location in
|
|
// the menubar, places it in that location in the menubar on demand,
|
|
// and on destruction destroys it
|
|
// If, on destruction wxMenuBar is still pointing to this wxMenu, it
|
|
// replaces it with the default (empty) menu for that location.
|
|
// and disables it.
|
|
// We maintain an array of default empty wxMenu menus that are nullptr for
|
|
// locations not subject to replacement, and are the disabled initial and final
|
|
// wxMenuBar values for locations in the Menubar where the real drop down
|
|
// in the menubar will be installed by wxMenuTracker.
|
|
struct wxMenuTracker {
|
|
wxMenuTracker(int);
|
|
void Replace();
|
|
~wxMenuTracker() noexcept;
|
|
// Non nullptr members of InitialAndFinal have to be explicitly initially placed
|
|
// in the menubar in the frame constructor and explicitly disabled in
|
|
// the frame initializer. In the debug build, congruence between the menu bar
|
|
// and InitialAndFinal should be checked with assert.
|
|
static wxMenu* InitialAndFinal[3];
|
|
static void check_dynamic_menus_absent();
|
|
wxMenuTracker(wxMenuTracker&&) = delete; // Move constructor
|
|
wxMenuTracker(const wxMenuTracker&) = delete; // Copy constructor
|
|
wxMenuTracker& operator=(wxMenuTracker&&) = delete; // Move assignment.
|
|
wxMenuTracker& operator=(const wxMenuTracker&) = delete; // Copy assignment.
|
|
bool operator==(const wxMenuTracker&) const = delete;
|
|
auto operator<=>(const wxMenuTracker&) const = delete;
|
|
wxMenu* Menu;
|
|
const int MenuPosition;
|
|
// The menu title is defined elsewhere as an array
|
|
// of const strings
|
|
// menu_strings[MenuPosition].head
|
|
};
|
|
|
|
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
|
|
{ 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_ptr<wxLogNull>m_pLogNull{ nullptr };
|
|
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 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;
|