1 #include "platform/wxwidgets/settings-common.hpp"
2 #include "platform/wxwidgets/settings-keyentry.hpp"
3 #include "core/keymapper.hpp"
8 int horiz_padding
= 60;
11 press_button_dialog::press_button_dialog(wxWindow
* parent
, const std::string
& title
, bool _axis
)
12 : wxDialog(parent
, wxID_ANY
, towxstring(title
))
16 wxBoxSizer
* s2
= new wxBoxSizer(wxVERTICAL
);
17 wxPanel
* p
= new wxPanel(this, wxID_ANY
, wxDefaultPosition
, wxSize(-1, -1), wxWANTS_CHARS
);
18 s2
->Add(p
, 1, wxGROW
);
22 wxFlexGridSizer
* s
= new wxFlexGridSizer(3, 3, 0, 0);
25 s
->Add(horiz_padding
, vert_padding
);
29 s
->Add(t
= new wxStaticText(p
, wxID_ANY
, wxT("Press the key to assign"), wxDefaultPosition
,
30 wxSize(-1, -1), wxWANTS_CHARS
), 1, wxGROW
);
34 s
->Add(horiz_padding
, vert_padding
);
36 p
->Connect(wxEVT_KEY_DOWN
, wxKeyEventHandler(press_button_dialog::on_keyboard_down
), NULL
, this);
37 p
->Connect(wxEVT_KEY_UP
, wxKeyEventHandler(press_button_dialog::on_keyboard_up
), NULL
, this);
38 p
->Connect(wxEVT_LEFT_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
39 p
->Connect(wxEVT_LEFT_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
40 p
->Connect(wxEVT_MIDDLE_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
41 p
->Connect(wxEVT_MIDDLE_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
42 p
->Connect(wxEVT_RIGHT_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
43 p
->Connect(wxEVT_RIGHT_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
44 t
->Connect(wxEVT_KEY_DOWN
, wxKeyEventHandler(press_button_dialog::on_keyboard_down
), NULL
, this);
45 t
->Connect(wxEVT_KEY_UP
, wxKeyEventHandler(press_button_dialog::on_keyboard_up
), NULL
, this);
46 t
->Connect(wxEVT_LEFT_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
47 t
->Connect(wxEVT_LEFT_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
48 t
->Connect(wxEVT_MIDDLE_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
49 t
->Connect(wxEVT_MIDDLE_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
50 t
->Connect(wxEVT_RIGHT_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
51 t
->Connect(wxEVT_RIGHT_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
52 settings_activate_keygrab([this](std::string key
) { this->dismiss_with(key
); });
53 s
->SetSizeHints(this);
57 bool press_button_dialog::handle_mousebtn(wxMouseEvent
& e
, bool(wxMouseEvent::*down
)()const,
58 bool(wxMouseEvent::*up
)()const, const std::string
& k
, int flag
)
63 if(mouseflag
== flag
) {
72 void press_button_dialog::on_mouse(wxMouseEvent
& e
)
74 handle_mousebtn(e
, &wxMouseEvent::LeftDown
, &wxMouseEvent::LeftUp
, "mouse_left", 1);
75 handle_mousebtn(e
, &wxMouseEvent::MiddleDown
, &wxMouseEvent::MiddleUp
, "mouse_center", 2);
76 handle_mousebtn(e
, &wxMouseEvent::RightDown
, &wxMouseEvent::RightUp
, "mouse_right", 3);
79 void press_button_dialog::on_keyboard_down(wxKeyEvent
& e
)
81 lastkbdkey
= e
.GetKeyCode();
85 void press_button_dialog::on_keyboard_up(wxKeyEvent
& e
)
87 int kcode
= e
.GetKeyCode();
88 if(lastkbdkey
== kcode
) {
89 dismiss_with(map_keycode_to_key(kcode
));
96 void press_button_dialog::dismiss_with(const std::string
& _k
)
102 //Check that k is a valid axis.
104 //Remove the +/- postfix if any.
106 char lch
= k
[k
.length() - 1];
107 if(lch
== '+' || lch
== '-')
108 k
= k
.substr(0, k
.length() - 1);
110 keyboard::key
& key
= lsnes_kbd
.lookup_key(k
);
111 if(key
.get_type() != keyboard::KBD_KEYTYPE_AXIS
)
118 settings_deactivate_keygrab();
124 key_entry_dialog::key_entry_dialog(wxWindow
* parent
, const std::string
& title
, const std::string
& spec
,
126 : wxDialog(parent
, wxID_ANY
, towxstring(title
), wxDefaultPosition
, wxSize(-1, -1))
128 wxString boxchoices
[] = { wxT("Released"), wxT("Don't care"), wxT("Pressed") };
129 std::vector
<wxString
> classeslist
;
130 wxString emptystring
;
131 std::list
<keyboard::modifier
*> mods
;
132 std::list
<keyboard::key
*> keys
;
137 std::set
<std::string
> x
;
138 mods
= lsnes_kbd
.all_modifiers();
139 keys
= lsnes_kbd
.all_keys();
141 std::string kclass
= i
->get_class();
143 classeslist
.push_back(towxstring(kclass
));
145 for(auto k2
: i
->get_subkeys())
146 classes
[kclass
].insert(i
->get_name() + k2
);
150 top_s
= new wxFlexGridSizer(3, 1, 0, 0);
153 t_s
= new wxFlexGridSizer(2, 3, 0, 0);
154 wxFlexGridSizer
* t2_s
= new wxFlexGridSizer(mods
.size(), 2, 0, 0);
155 for(auto i2
: mods
) {
157 std::string i
= i2
->get_name();
158 t2_s
->Add(new wxStaticText(this, wxID_ANY
, towxstring(i
)), 0, wxGROW
);
159 t2_s
->Add(m
.pressed
= new wxComboBox(this, wxID_ANY
, boxchoices
[1], wxDefaultPosition
,
160 wxDefaultSize
, 3, boxchoices
, wxCB_READONLY
), 1, wxGROW
);
161 m
.pressed
->SetSelection(1);
163 m
.pressed
->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED
,
164 wxCommandEventHandler(key_entry_dialog::on_change_setting
), NULL
, this);
167 t_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Key")), 0, wxGROW
);
168 t_s
->Add(mainclass
= new wxComboBox(this, wxID_ANY
, classeslist
[0], wxDefaultPosition
, wxDefaultSize
,
169 classeslist
.size(), &classeslist
[0], wxCB_READONLY
), 0, wxGROW
);
170 mainclass
->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED
,
171 wxCommandEventHandler(key_entry_dialog::on_classchange
), NULL
, this);
172 t_s
->Add(mainkey
= new wxComboBox(this, wxID_ANY
, emptystring
, wxDefaultPosition
, wxDefaultSize
,
173 1, &emptystring
, wxCB_READONLY
), 1, wxGROW
);
174 mainkey
->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED
,
175 wxCommandEventHandler(key_entry_dialog::on_change_setting
), NULL
, this);
178 wxBoxSizer
* pbutton_s
= new wxBoxSizer(wxHORIZONTAL
);
179 pbutton_s
->Add(press
= new wxButton(this, wxID_OK
, wxT("Prompt key")), 0, wxGROW
);
180 press
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
181 wxCommandEventHandler(key_entry_dialog::on_pressbutton
), NULL
, this);
183 pbutton_s
->Add(clear
= new wxButton(this, wxID_OK
, wxT("Clear")), 0, wxGROW
);
184 pbutton_s
->Add(ok
= new wxButton(this, wxID_OK
, wxT("OK")), 0, wxGROW
);
185 pbutton_s
->Add(cancel
= new wxButton(this, wxID_CANCEL
, wxT("Cancel")), 0, wxGROW
);
186 pbutton_s
->AddStretchSpacer();
187 ok
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
188 wxCommandEventHandler(key_entry_dialog::on_ok
), NULL
, this);
189 cancel
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
190 wxCommandEventHandler(key_entry_dialog::on_cancel
), NULL
, this);
191 mainclass
->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED
,
192 wxCommandEventHandler(key_entry_dialog::on_classchange
), NULL
, this);
194 clear
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
195 wxCommandEventHandler(key_entry_dialog::on_clear
), NULL
, this);
196 top_s
->Add(pbutton_s
, 0, wxGROW
);
198 set_class(tostdstring(classeslist
[0]));
200 t_s
->SetSizeHints(this);
201 top_s
->SetSizeHints(this);
208 #define TMPFLAG_UNMASKED 65
209 #define TMPFLAG_UNMASKED_LINK_CHILD 2
210 #define TMPFLAG_UNMASKED_LINK_PARENT 68
211 #define TMPFLAG_PRESSED 8
212 #define TMPFLAG_PRESSED_LINK_CHILD 16
213 #define TMPFLAG_PRESSED_LINK_PARENT 32
215 void key_entry_dialog::set_mask(const std::string
& mod
)
217 if(!modifiers
.count(mod
))
219 if(modifiers
[mod
].pressed
->GetSelection() == 1) {
221 modifiers
[mod
].pressed
->SetSelection(0);
222 on_change_setting(e
);
226 void key_entry_dialog::set_mod(const std::string
& mod
)
228 if(!modifiers
.count(mod
))
230 if(modifiers
[mod
].pressed
->GetSelection() != 1) {
232 modifiers
[mod
].pressed
->SetSelection(2);
233 on_change_setting(e
);
237 void key_entry_dialog::set_set(const std::string
& mset
,
238 void (key_entry_dialog::*fn
)(const std::string
& mod
))
240 std::string rem
= mset
;
242 size_t s
= rem
.find_first_of(",");
243 if(s
>= rem
.length()) {
247 (this->*fn
)(rem
.substr(0, s
));
248 rem
= rem
.substr(s
+ 1);
253 void key_entry_dialog::load_spec(const std::string
& spec
)
255 std::string _spec
= spec
;
256 size_t s1
= _spec
.find_first_of("/");
257 size_t s2
= _spec
.find_first_of("|");
258 if(s1
>= _spec
.length() || s2
>= _spec
.length())
260 std::string mod
= _spec
.substr(0, s1
);
261 std::string mask
= _spec
.substr(s1
+ 1, s2
- s1
- 1);
262 std::string key
= _spec
.substr(s2
+ 1);
263 set_set(mask
, &key_entry_dialog::set_mask
);
264 set_set(mod
, &key_entry_dialog::set_mod
);
266 for(auto i
: classes
)
267 if(i
.second
.count(key
))
271 mainclass
->SetValue(towxstring(_class
));
272 mainkey
->SetValue(towxstring(key
));
279 void key_entry_dialog::on_change_setting(wxCommandEvent
& e
)
283 void key_entry_dialog::on_pressbutton(wxCommandEvent
& e
)
285 press_button_dialog
* p
= new press_button_dialog(this, wtitle
, false);
287 std::string key
= p
->getkey();
290 for(auto i
: classes
)
291 if(i
.second
.count(key
))
296 mainclass
->SetValue(towxstring(_class
));
297 mainkey
->SetValue(towxstring(key
));
300 void key_entry_dialog::on_ok(wxCommandEvent
& e
)
305 void key_entry_dialog::on_clear(wxCommandEvent
& e
)
311 void key_entry_dialog::on_cancel(wxCommandEvent
& e
)
313 EndModal(wxID_CANCEL
);
316 void key_entry_dialog::set_class(const std::string
& _class
)
320 if(currentclass
== _class
)
323 for(auto i
: classes
[_class
])
324 mainkey
->Append(towxstring(i
));
325 currentclass
= _class
;
326 mainkey
->SetSelection(0);
332 void key_entry_dialog::on_classchange(wxCommandEvent
& e
)
334 set_class(tostdstring(mainclass
->GetValue()));
337 std::string
key_entry_dialog::getkey()
344 for(auto i
: modifiers
) {
345 if(i
.second
.pressed
->GetSelection() == 2) {
354 for(auto i
: modifiers
) {
355 if(i
.second
.pressed
->GetSelection() != 1) {
362 x
= x
+ "|" + tostdstring(mainkey
->GetValue());
366 std::string
clean_keystring(const std::string
& in
)
368 regex_results tmp
= regex("(.*)/(.*)\\|(.*)", in
);
371 std::string mods
= tmp
[1];
372 std::string mask
= tmp
[2];
373 std::string key
= tmp
[3];
374 std::set
<std::string
> _mods
, _mask
;
376 for(auto& tmp2
: token_iterator_foreach(mods
, {","}))
378 for(auto& tmp2
: token_iterator_foreach(mask
, {","}))
386 out
= out
+ "!" + i
+ "+";