Add <functional> to files that use std::function
[lsnes.git] / src / platform / wxwidgets / settings-common.cpp
blob14831c62ec75d6a9a207628d1c68b13fe51343ee
1 #include <functional>
2 #include "platform/wxwidgets/settings-common.hpp"
3 #include "core/instance.hpp"
4 #include "core/instance-map.hpp"
5 #include "core/keymapper.hpp"
7 namespace
9 std::map<std::string, settings_tab_factory*>& _factories()
11 static std::map<std::string, settings_tab_factory*> x;
12 return x;
15 class wxeditor_esettings2;
16 instance_map<wxeditor_esettings2> sdialogs;
20 settings_tab_factory::settings_tab_factory(const std::string& tabname,
21 std::function<settings_tab*(wxWindow* parent, emulator_instance& inst)> create_fn)
22 : _tabname(tabname), _create_fn(create_fn)
24 _factories()[_tabname] = this;
27 settings_tab_factory::~settings_tab_factory()
29 _factories().erase(_tabname);
32 std::list<settings_tab_factory*> settings_tab_factory::factories()
34 std::list<settings_tab_factory*> f;
35 for(auto i : _factories())
36 f.push_back(i.second);
37 return f;
40 settings_menu::settings_menu(wxWindow* win, emulator_instance& _inst, int id)
41 : inst(_inst)
43 CHECK_UI_THREAD;
44 parent = win;
45 items[id] = NULL;
46 Append(id, towxstring("All as tabs..."));
47 win->Connect(id++, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(settings_menu::on_selected), NULL,
48 this);
49 AppendSeparator();
50 for(auto i : settings_tab_factory::factories()) {
51 items[id] = i;
52 Append(id, towxstring(i->get_name() + "..."));
53 win->Connect(id++, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(settings_menu::on_selected),
54 NULL, this);
58 void settings_menu::on_selected(wxCommandEvent& e)
60 CHECK_UI_THREAD;
61 int id = e.GetId();
62 if(!items.count(id))
63 return;
64 display_settings_dialog(parent, inst, items[id]);
67 namespace
69 volatile bool keygrab_active = false;
70 std::string pkey;
71 std::function<void(std::string key)> keygrab_callback;
73 class keygrabber : public keyboard::event_listener
75 public:
76 keygrabber()
78 keygrab_active = false;
80 ~keygrabber() throw()
83 void on_key_event(keyboard::modifier_set& mods, keyboard::key& key, keyboard::event& event)
85 if(!keygrab_active)
86 return;
87 uint32_t dev = event.get_change_mask();
88 auto subkeys = key.get_subkeys();
89 for(unsigned i = 0; i < 16 && i < subkeys.size(); i++) {
90 std::string pname = key.get_name() + subkeys[i];
91 if(((dev >> (2 * i)) & 3) == 3)
92 pkey = pname;
93 if(((dev >> (2 * i)) & 3) == 2) {
94 if(pkey == pname) {
95 keygrab_active = false;
96 std::string tmp = pkey;
97 runuifun([this, tmp]() { this->keygrab_callback(tmp); });
98 } else
99 pkey = "";
103 volatile bool keygrab_active;
104 std::string pkey;
105 std::function<void(std::string key)> keygrab_callback;
108 class wxeditor_esettings2 : public wxDialog
110 public:
111 wxeditor_esettings2(emulator_instance& _inst, wxWindow* parent, settings_tab_factory* singletab);
112 ~wxeditor_esettings2();
113 bool ShouldPreventAppExit() const;
114 void on_close(wxCommandEvent& e);
115 void on_notify();
116 private:
117 emulator_instance& inst;
118 wxNotebook* tabset;
119 wxButton* closebutton;
120 std::list<settings_tab*> tabs;
121 std::string get_title(settings_tab_factory* singletab);
122 public:
123 keygrabber keygrab;
126 std::string wxeditor_esettings2::get_title(settings_tab_factory* singletab)
128 if(!singletab)
129 return "lsnes: Configuration";
130 else
131 return "lsnes: Configuration: " + singletab->get_name();
134 wxeditor_esettings2::wxeditor_esettings2(emulator_instance& _inst, wxWindow* parent,
135 settings_tab_factory* singletab)
136 : wxDialog(parent, wxID_ANY, towxstring(get_title(singletab)), wxDefaultPosition, wxSize(-1, -1),
137 wxCAPTION | wxSYSTEM_MENU | wxCLOSE_BOX | wxRESIZE_BORDER), inst(_inst)
139 CHECK_UI_THREAD;
140 //Grab keys to prevent the joystick driver from running who knows what commands.
141 inst.keyboard->set_exclusive(&keygrab);
143 Centre();
144 wxSizer* top_s = new wxBoxSizer(wxVERTICAL);
145 SetSizer(top_s);
147 if(singletab) {
148 //If this throws, let it throw through.
149 settings_tab* t = singletab->create(this, inst);
150 top_s->Add(t, 1, wxGROW);
151 t->set_notify([this]() { this->on_notify(); });
152 tabs.push_back(t);
153 } else {
154 int created = 0;
155 tabset = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
156 for(auto i : settings_tab_factory::factories()) {
157 settings_tab* t;
158 try {
159 t = i->create(tabset, inst);
160 } catch(...) {
161 continue;
163 tabset->AddPage(t, towxstring(i->get_name()));
164 t->set_notify([this]() { this->on_notify(); });
165 tabs.push_back(t);
166 created++;
168 top_s->Add(tabset, 1, wxGROW);
169 if(!created)
170 throw std::runtime_error("Nothing to configure here, move along");
173 wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
174 pbutton_s->AddStretchSpacer();
175 pbutton_s->Add(closebutton = new wxButton(this, wxID_ANY, wxT("Close")), 0, wxGROW);
176 closebutton->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
177 wxCommandEventHandler(wxeditor_esettings2::on_close), NULL, this);
178 top_s->Add(pbutton_s, 0, wxGROW);
180 top_s->SetSizeHints(this);
181 Fit();
184 wxeditor_esettings2::~wxeditor_esettings2()
186 CHECK_UI_THREAD;
187 for(auto i : tabs)
188 i->notify_close();
189 inst.keyboard->set_exclusive(NULL);
190 sdialogs.remove(inst);
193 bool wxeditor_esettings2::ShouldPreventAppExit() const
195 return false;
198 void wxeditor_esettings2::on_close(wxCommandEvent& e)
200 CHECK_UI_THREAD;
201 for(auto i : tabs)
202 i->on_close();
203 EndModal(wxID_OK);
206 void wxeditor_esettings2::on_notify()
208 CHECK_UI_THREAD;
209 for(auto i : tabs)
210 i->on_notify();
214 void display_settings_dialog(wxWindow* parent, emulator_instance& inst, settings_tab_factory* singletab)
216 CHECK_UI_THREAD;
217 modal_pause_holder hld;
218 wxDialog* editor;
219 try {
220 try {
221 editor = sdialogs.create(inst, parent, singletab);
222 } catch(std::exception& e) {
223 std::string title = "Configure";
224 if(singletab)
225 title = "Configure " + singletab->get_name();
226 show_message_ok(parent, title, e.what(), wxICON_EXCLAMATION);
227 return;
229 editor->ShowModal();
230 } catch(...) {
231 return;
233 editor->Destroy();
234 do_save_configuration();
237 void settings_activate_keygrab(emulator_instance& inst, std::function<void(std::string key)> callback)
239 auto s = sdialogs.lookup(inst);
240 if(!s) return;
241 s->keygrab.keygrab_callback = callback;
242 s->keygrab.keygrab_active = true;
245 void settings_deactivate_keygrab(emulator_instance& inst)
247 auto s = sdialogs.lookup(inst);
248 if(!s) return;
249 s->keygrab.keygrab_active = false;