1 #include "platform/wxwidgets/settings-common.hpp"
2 #include "core/instance.hpp"
3 #include "core/settings.hpp"
9 wxID_CHANGE
= wxID_HIGHEST
+ 1
12 class wxeditor_esettings_advanced
: public settings_tab
15 wxeditor_esettings_advanced(wxWindow
* parent
);
16 ~wxeditor_esettings_advanced();
17 void on_change(wxCommandEvent
& e
);
18 void on_change2(wxMouseEvent
& e
);
19 void on_selchange(wxCommandEvent
& e
);
20 void on_setting_change(const settingvar::base
& val
);
21 void on_mouse(wxMouseEvent
& e
);
22 void on_popup_menu(wxCommandEvent
& e
);
24 struct listener
: public settingvar::listener
26 listener(settingvar::group
& group
, wxeditor_esettings_advanced
& _obj
)
27 : obj(_obj
), grp(group
)
29 group
.add_listener(*this);
33 grp
.remove_listener(*this);
35 void on_setting_change(settingvar::group
& grp
, const settingvar::base
& val
)
37 obj
.on_setting_change(val
);
39 wxeditor_esettings_advanced
& obj
;
40 settingvar::group
& grp
;
45 std::set
<std::string
> settings
;
46 std::map
<std::string
, std::string
> values
;
47 std::map
<std::string
, std::string
> names
;
48 std::map
<int, std::string
> selections
;
49 std::string
selected();
50 wxButton
* changebutton
;
54 wxeditor_esettings_advanced::wxeditor_esettings_advanced(wxWindow
* parent
)
55 : settings_tab(parent
), _listener(lsnes_instance
.settings
, *this)
57 wxSizer
* top_s
= new wxBoxSizer(wxVERTICAL
);
60 top_s
->Add(_settings
= new wxListBox(this, wxID_ANY
), 1, wxGROW
);
61 _settings
->SetMinSize(wxSize(300, 400));
62 _settings
->Connect(wxEVT_COMMAND_LISTBOX_SELECTED
,
63 wxCommandEventHandler(wxeditor_esettings_advanced::on_selchange
), NULL
, this);
64 _settings
->Connect(wxEVT_RIGHT_UP
, wxMouseEventHandler(wxeditor_esettings_advanced::on_mouse
), NULL
,
66 _settings
->Connect(wxEVT_LEFT_UP
, wxMouseEventHandler(wxeditor_esettings_advanced::on_mouse
), NULL
,
69 wxBoxSizer
* pbutton_s
= new wxBoxSizer(wxHORIZONTAL
);
70 pbutton_s
->AddStretchSpacer();
71 pbutton_s
->Add(changebutton
= new wxButton(this, wxID_ANY
, wxT("Change")), 0, wxGROW
);
72 _settings
->Connect(wxEVT_LEFT_DCLICK
,
73 wxMouseEventHandler(wxeditor_esettings_advanced::on_change2
), NULL
, this);
74 changebutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
75 wxCommandEventHandler(wxeditor_esettings_advanced::on_change
), NULL
, this);
76 top_s
->Add(pbutton_s
, 0, wxGROW
);
81 top_s
->SetSizeHints(this);
85 wxeditor_esettings_advanced::~wxeditor_esettings_advanced()
89 std::string
change_value_of_boolean(const std::string
& name
, const settingvar::description
& desc
,
90 const std::string
& current
)
92 return string_to_bool(current
) ? "0" : "1";
95 std::string
change_value_of_enumeration(wxWindow
* parent
, const std::string
& name
,
96 const settingvar::description
& desc
, const std::string
& current
)
98 std::vector
<std::string
> valset
;
100 for(unsigned i
= 0; i
<= desc
._enumeration
->max_val(); i
++) {
101 valset
.push_back(desc
._enumeration
->get(i
));
102 if(desc
._enumeration
->get(i
) == current
)
105 return pick_among(parent
, "Set value to", "Set " + name
+ " to value:", valset
, dflt
);
108 std::string
change_value_of_string(wxWindow
* parent
, const std::string
& name
,
109 const settingvar::description
& desc
, const std::string
& current
)
111 return pick_text(parent
, "Set value to", "Set " + name
+ " to value:", current
);
114 class numeric_inputbox
: public wxDialog
117 numeric_inputbox(wxWindow
* parent
, const std::string
& name
, int64_t minval
, int64_t maxval
,
118 const std::string
& val
)
119 : wxDialog(parent
, wxID_ANY
, wxT("Set value to"))
121 wxSizer
* s1
= new wxBoxSizer(wxVERTICAL
);
123 s1
->Add(new wxStaticText(this, wxID_ANY
, towxstring("Set " + name
+ " to value:")), 0,
126 s1
->Add(sp
= new wxSpinCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxDefaultSize
,
127 wxSP_ARROW_KEYS
, minval
, maxval
, parse_value
<int64_t>(val
)), 1, wxGROW
);
129 wxBoxSizer
* pbutton_s
= new wxBoxSizer(wxHORIZONTAL
);
130 pbutton_s
->AddStretchSpacer();
132 pbutton_s
->Add(t
= new wxButton(this, wxID_CANCEL
, wxT("Cancel")), 0, wxGROW
);
133 t
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
134 wxCommandEventHandler(numeric_inputbox::on_button
), NULL
, this);
135 pbutton_s
->Add(t
= new wxButton(this, wxID_OK
, wxT("OK")), 0, wxGROW
);
136 t
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
137 wxCommandEventHandler(numeric_inputbox::on_button
), NULL
, this);
138 s1
->Add(pbutton_s
, 0, wxGROW
);
140 s1
->SetSizeHints(this);
142 std::string
get_value() { return (stringfmt() << sp
->GetValue()).str(); }
143 void on_button(wxCommandEvent
& e
) { EndModal(e
.GetId()); }
148 class path_inputbox
: public wxDialog
151 path_inputbox(wxWindow
* parent
, const std::string
& name
, const std::string
& val
)
152 : wxDialog(parent
, wxID_ANY
, wxT("Set path to"))
155 wxSizer
* s1
= new wxBoxSizer(wxVERTICAL
);
157 s1
->Add(new wxStaticText(this, wxID_ANY
, towxstring("Set " + name
+ " to value:")), 0,
159 wxSizer
* s2
= new wxBoxSizer(wxHORIZONTAL
);
160 s2
->Add(pth
= new wxTextCtrl(this, wxID_ANY
, towxstring(val
), wxDefaultPosition
,
161 wxSize(400, -1)), 1, wxGROW
);
162 s2
->Add(t
= new wxButton(this, wxID_HIGHEST
+ 1, wxT("...")), 0, wxGROW
);
163 t
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
164 wxCommandEventHandler(path_inputbox::on_pbutton
), NULL
, this);
165 s1
->Add(s2
, 1, wxGROW
);
167 wxBoxSizer
* pbutton_s
= new wxBoxSizer(wxHORIZONTAL
);
168 pbutton_s
->AddStretchSpacer();
169 pbutton_s
->Add(t
= new wxButton(this, wxID_CANCEL
, wxT("Cancel")), 0, wxGROW
);
170 t
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
171 wxCommandEventHandler(path_inputbox::on_button
), NULL
, this);
172 pbutton_s
->Add(t
= new wxButton(this, wxID_OK
, wxT("OK")), 0, wxGROW
);
173 t
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
174 wxCommandEventHandler(path_inputbox::on_button
), NULL
, this);
175 s1
->Add(pbutton_s
, 0, wxGROW
);
177 s1
->SetSizeHints(this);
179 std::string
get_value() { return tostdstring(pth
->GetValue()); }
180 void on_pbutton(wxCommandEvent
& e
) {
182 d
= new wxDirDialog(this, wxT("Select project directory"),
183 pth
->GetValue(), wxDD_DIR_MUST_EXIST
);
184 if(d
->ShowModal() == wxID_CANCEL
) {
188 pth
->SetValue(d
->GetPath());
191 void on_button(wxCommandEvent
& e
) {
203 std::string
change_value_of_numeric(wxWindow
* parent
, const std::string
& name
,
204 const settingvar::description
& desc
, const std::string
& current
)
206 auto d
= new numeric_inputbox(parent
, name
, desc
.min_val
, desc
.max_val
, current
);
207 int x
= d
->ShowModal();
208 if(x
== wxID_CANCEL
) {
210 throw canceled_exception();
212 std::string v
= d
->get_value();
217 std::string
change_value_of_path(wxWindow
* parent
, const std::string
& name
,
218 const settingvar::description
& desc
, const std::string
& current
)
220 auto d
= new path_inputbox(parent
, name
, current
);
221 int x
= d
->ShowModal();
222 if(x
== wxID_CANCEL
) {
224 throw canceled_exception();
226 std::string v
= d
->get_value();
231 void wxeditor_esettings_advanced::on_popup_menu(wxCommandEvent
& e
)
235 if(e
.GetId() == wxID_EDIT
)
239 void wxeditor_esettings_advanced::on_mouse(wxMouseEvent
& e
)
241 if(!e
.RightUp() && !(e
.LeftUp() && e
.ControlDown()))
246 menu
.Connect(wxEVT_COMMAND_MENU_SELECTED
,
247 wxCommandEventHandler(wxeditor_esettings_advanced::on_popup_menu
), NULL
, this);
248 menu
.Append(wxID_EDIT
, towxstring("Change"));
252 void wxeditor_esettings_advanced::on_change2(wxMouseEvent
& e
)
258 void wxeditor_esettings_advanced::on_change(wxCommandEvent
& e
)
262 std::string name
= selected();
267 value
= lsnes_instance
.setcache
.get(name
);
268 auto model
= lsnes_instance
.setcache
.get_description(name
);
271 case settingvar::description::T_BOOLEAN
:
272 value
= change_value_of_boolean(name
, model
, value
); break;
273 case settingvar::description::T_NUMERIC
:
274 value
= change_value_of_numeric(this, name
, model
, value
); break;
275 case settingvar::description::T_STRING
:
276 value
= change_value_of_string(this, name
, model
, value
); break;
277 case settingvar::description::T_PATH
:
278 value
= change_value_of_path(this, name
, model
, value
); break;
279 case settingvar::description::T_ENUMERATION
:
280 value
= change_value_of_enumeration(this, name
, model
, value
); break;
282 value
= change_value_of_string(this, name
, model
, value
); break;
287 lsnes_instance
.iqueue
.run([this, name
, value
]() {
288 run_show_error(this, "Error setting value", "", [name
, value
]() {
289 lsnes_instance
.setcache
.set(name
, value
);
294 void wxeditor_esettings_advanced::on_selchange(wxCommandEvent
& e
)
298 std::string sel
= selected();
299 bool enable
= (sel
!= "");
300 changebutton
->Enable(enable
);
303 void wxeditor_esettings_advanced::on_setting_change(const settingvar::base
& val
)
307 runuifun([this, &val
]() {
308 std::string setting
= val
.get_iname();
309 std::string value
= val
.str();
310 this->settings
.insert(setting
);
311 this->values
[setting
] = value
;
316 void wxeditor_esettings_advanced::refresh()
320 settings
= lsnes_instance
.setcache
.get_keys();
321 for(auto i
: settings
) {
322 values
[i
] = lsnes_instance
.setcache
.get(i
);
323 names
[i
] = lsnes_instance
.setcache
.get_hname(i
);
328 std::string
wxeditor_esettings_advanced::selected()
332 int x
= _settings
->GetSelection();
333 if(selections
.count(x
))
334 return selections
[x
];
339 void wxeditor_esettings_advanced::_refresh()
343 std::vector
<wxString
> strings
;
344 std::multimap
<std::string
, std::string
> sort
;
346 for(auto i
: settings
)
347 sort
.insert(std::make_pair(names
[i
], i
));
349 //FIXME: Do something with this?
350 //auto description = lsnes_instance.setcache.get_description(i.second);
351 strings
.push_back(towxstring(names
[i
.second
] + " (Value: " + values
[i
.second
] + ")"));
352 selections
[k
++] = i
.second
;
354 _settings
->Set(strings
.size(), &strings
[0]);
357 settings_tab_factory
advanced_tab("Advanced", [](wxWindow
* parent
) -> settings_tab
* {
358 return new wxeditor_esettings_advanced(parent
);