1 #include "platform/wxwidgets/settings-common.hpp"
2 #include "platform/wxwidgets/settings-keyentry.hpp"
3 #include "core/instance.hpp"
4 #include "core/keymapper.hpp"
9 int horiz_padding
= 60;
12 press_button_dialog::press_button_dialog(wxWindow
* parent
, emulator_instance
& _inst
, const std::string
& title
,
14 : wxDialog(parent
, wxID_ANY
, towxstring(title
)), inst(_inst
)
19 wxBoxSizer
* s2
= new wxBoxSizer(wxVERTICAL
);
20 wxPanel
* p
= new wxPanel(this, wxID_ANY
, wxDefaultPosition
, wxSize(-1, -1), wxWANTS_CHARS
);
21 s2
->Add(p
, 1, wxGROW
);
25 wxFlexGridSizer
* s
= new wxFlexGridSizer(3, 3, 0, 0);
28 s
->Add(horiz_padding
, vert_padding
);
32 s
->Add(t
= new wxStaticText(p
, wxID_ANY
, wxT("Press the key to assign"), wxDefaultPosition
,
33 wxSize(-1, -1), wxWANTS_CHARS
), 1, wxGROW
);
37 s
->Add(horiz_padding
, vert_padding
);
39 p
->Connect(wxEVT_KEY_DOWN
, wxKeyEventHandler(press_button_dialog::on_keyboard_down
), NULL
, this);
40 p
->Connect(wxEVT_KEY_UP
, wxKeyEventHandler(press_button_dialog::on_keyboard_up
), NULL
, this);
41 p
->Connect(wxEVT_LEFT_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
42 p
->Connect(wxEVT_LEFT_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
43 p
->Connect(wxEVT_MIDDLE_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
44 p
->Connect(wxEVT_MIDDLE_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
45 p
->Connect(wxEVT_RIGHT_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
46 p
->Connect(wxEVT_RIGHT_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
47 t
->Connect(wxEVT_KEY_DOWN
, wxKeyEventHandler(press_button_dialog::on_keyboard_down
), NULL
, this);
48 t
->Connect(wxEVT_KEY_UP
, wxKeyEventHandler(press_button_dialog::on_keyboard_up
), NULL
, this);
49 t
->Connect(wxEVT_LEFT_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
50 t
->Connect(wxEVT_LEFT_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
51 t
->Connect(wxEVT_MIDDLE_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
52 t
->Connect(wxEVT_MIDDLE_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
53 t
->Connect(wxEVT_RIGHT_DOWN
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
54 t
->Connect(wxEVT_RIGHT_UP
, wxMouseEventHandler(press_button_dialog::on_mouse
), NULL
, this);
55 settings_activate_keygrab(inst
, [this](std::string key
) { this->dismiss_with(key
); });
56 s
->SetSizeHints(this);
60 bool press_button_dialog::handle_mousebtn(wxMouseEvent
& e
, bool(wxMouseEvent::*down
)()const,
61 bool(wxMouseEvent::*up
)()const, const std::string
& k
, int flag
)
67 if(mouseflag
== flag
) {
76 void press_button_dialog::on_mouse(wxMouseEvent
& e
)
78 handle_mousebtn(e
, &wxMouseEvent::LeftDown
, &wxMouseEvent::LeftUp
, "mouse_left", 1);
79 handle_mousebtn(e
, &wxMouseEvent::MiddleDown
, &wxMouseEvent::MiddleUp
, "mouse_center", 2);
80 handle_mousebtn(e
, &wxMouseEvent::RightDown
, &wxMouseEvent::RightUp
, "mouse_right", 3);
83 void press_button_dialog::on_keyboard_down(wxKeyEvent
& e
)
86 lastkbdkey
= e
.GetKeyCode();
90 void press_button_dialog::on_keyboard_up(wxKeyEvent
& e
)
93 int kcode
= e
.GetKeyCode();
94 if(lastkbdkey
== kcode
) {
95 dismiss_with(map_keycode_to_key(kcode
));
102 void press_button_dialog::dismiss_with(const std::string
& _k
)
109 //Check that k is a valid axis.
111 //Remove the +/- postfix if any.
113 char lch
= k
[k
.length() - 1];
114 if(lch
== '+' || lch
== '-')
115 k
= k
.substr(0, k
.length() - 1);
117 keyboard::key
& key
= inst
.keyboard
->lookup_key(k
);
118 if(key
.get_type() != keyboard::KBD_KEYTYPE_AXIS
)
125 settings_deactivate_keygrab(inst
);
131 key_entry_dialog::key_entry_dialog(wxWindow
* parent
, emulator_instance
& _inst
, const std::string
& title
,
132 const std::string
& spec
, bool clearable
)
133 : wxDialog(parent
, wxID_ANY
, towxstring(title
), wxDefaultPosition
, wxSize(-1, -1)), inst(_inst
)
136 wxString boxchoices
[] = { wxT("Released"), wxT("Don't care"), wxT("Pressed") };
137 std::vector
<wxString
> classeslist
;
138 wxString emptystring
;
139 std::list
<keyboard::modifier
*> mods
;
140 std::list
<keyboard::key
*> keys
;
145 std::set
<std::string
> x
;
146 mods
= inst
.keyboard
->all_modifiers();
147 keys
= inst
.keyboard
->all_keys();
149 std::string kclass
= i
->get_class();
151 classeslist
.push_back(towxstring(kclass
));
153 for(auto k2
: i
->get_subkeys())
154 classes
[kclass
].insert(i
->get_name() + k2
);
158 top_s
= new wxFlexGridSizer(3, 1, 0, 0);
161 t_s
= new wxFlexGridSizer(2, 3, 0, 0);
162 wxFlexGridSizer
* t2_s
= new wxFlexGridSizer(mods
.size(), 2, 0, 0);
163 for(auto i2
: mods
) {
165 std::string i
= i2
->get_name();
166 t2_s
->Add(new wxStaticText(this, wxID_ANY
, towxstring(i
)), 0, wxGROW
);
167 t2_s
->Add(m
.pressed
= new wxComboBox(this, wxID_ANY
, boxchoices
[1], wxDefaultPosition
,
168 wxDefaultSize
, 3, boxchoices
, wxCB_READONLY
), 1, wxGROW
);
169 m
.pressed
->SetSelection(1);
171 m
.pressed
->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED
,
172 wxCommandEventHandler(key_entry_dialog::on_change_setting
), NULL
, this);
175 t_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Key")), 0, wxGROW
);
176 t_s
->Add(mainclass
= new wxComboBox(this, wxID_ANY
, classeslist
[0], wxDefaultPosition
, wxDefaultSize
,
177 classeslist
.size(), &classeslist
[0], wxCB_READONLY
), 0, wxGROW
);
178 mainclass
->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED
,
179 wxCommandEventHandler(key_entry_dialog::on_classchange
), NULL
, this);
180 t_s
->Add(mainkey
= new wxComboBox(this, wxID_ANY
, emptystring
, wxDefaultPosition
, wxDefaultSize
,
181 1, &emptystring
, wxCB_READONLY
), 1, wxGROW
);
182 mainkey
->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED
,
183 wxCommandEventHandler(key_entry_dialog::on_change_setting
), NULL
, this);
186 wxBoxSizer
* pbutton_s
= new wxBoxSizer(wxHORIZONTAL
);
187 pbutton_s
->Add(press
= new wxButton(this, wxID_OK
, wxT("Prompt key")), 0, wxGROW
);
188 press
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
189 wxCommandEventHandler(key_entry_dialog::on_pressbutton
), NULL
, this);
191 pbutton_s
->Add(clear
= new wxButton(this, wxID_OK
, wxT("Clear")), 0, wxGROW
);
192 pbutton_s
->Add(ok
= new wxButton(this, wxID_OK
, wxT("OK")), 0, wxGROW
);
193 pbutton_s
->Add(cancel
= new wxButton(this, wxID_CANCEL
, wxT("Cancel")), 0, wxGROW
);
194 pbutton_s
->AddStretchSpacer();
195 ok
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
196 wxCommandEventHandler(key_entry_dialog::on_ok
), NULL
, this);
197 cancel
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
198 wxCommandEventHandler(key_entry_dialog::on_cancel
), NULL
, this);
199 mainclass
->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED
,
200 wxCommandEventHandler(key_entry_dialog::on_classchange
), NULL
, this);
202 clear
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
203 wxCommandEventHandler(key_entry_dialog::on_clear
), NULL
, this);
204 top_s
->Add(pbutton_s
, 0, wxGROW
);
206 if(classeslist
.empty())
207 throw std::runtime_error("No keys");
209 set_class(tostdstring(classeslist
[0]));
211 t_s
->SetSizeHints(this);
212 top_s
->SetSizeHints(this);
219 #define TMPFLAG_UNMASKED 65
220 #define TMPFLAG_UNMASKED_LINK_CHILD 2
221 #define TMPFLAG_UNMASKED_LINK_PARENT 68
222 #define TMPFLAG_PRESSED 8
223 #define TMPFLAG_PRESSED_LINK_CHILD 16
224 #define TMPFLAG_PRESSED_LINK_PARENT 32
226 void key_entry_dialog::set_mask(const std::string
& mod
)
229 if(!modifiers
.count(mod
))
231 if(modifiers
[mod
].pressed
->GetSelection() == 1) {
233 modifiers
[mod
].pressed
->SetSelection(0);
234 on_change_setting(e
);
238 void key_entry_dialog::set_mod(const std::string
& mod
)
241 if(!modifiers
.count(mod
))
243 if(modifiers
[mod
].pressed
->GetSelection() != 1) {
245 modifiers
[mod
].pressed
->SetSelection(2);
246 on_change_setting(e
);
250 void key_entry_dialog::set_set(const std::string
& mset
,
251 void (key_entry_dialog::*fn
)(const std::string
& mod
))
254 std::string rem
= mset
;
256 size_t s
= rem
.find_first_of(",");
257 if(s
>= rem
.length()) {
261 (this->*fn
)(rem
.substr(0, s
));
262 rem
= rem
.substr(s
+ 1);
267 void key_entry_dialog::load_spec(const std::string
& spec
)
270 std::string _spec
= spec
;
271 size_t s1
= _spec
.find_first_of("/");
272 size_t s2
= _spec
.find_first_of("|");
273 if(s1
>= _spec
.length() || s2
>= _spec
.length())
275 std::string mod
= _spec
.substr(0, s1
);
276 std::string mask
= _spec
.substr(s1
+ 1, s2
- s1
- 1);
277 std::string key
= _spec
.substr(s2
+ 1);
278 set_set(mask
, &key_entry_dialog::set_mask
);
279 set_set(mod
, &key_entry_dialog::set_mod
);
281 for(auto i
: classes
)
282 if(i
.second
.count(key
))
286 mainclass
->SetValue(towxstring(_class
));
287 mainkey
->SetValue(towxstring(key
));
294 void key_entry_dialog::on_change_setting(wxCommandEvent
& e
)
298 void key_entry_dialog::on_pressbutton(wxCommandEvent
& e
)
301 press_button_dialog
* p
= new press_button_dialog(this, inst
, wtitle
, false);
303 std::string key
= p
->getkey();
306 for(auto i
: classes
)
307 if(i
.second
.count(key
))
312 mainclass
->SetValue(towxstring(_class
));
313 mainkey
->SetValue(towxstring(key
));
316 void key_entry_dialog::on_ok(wxCommandEvent
& e
)
322 void key_entry_dialog::on_clear(wxCommandEvent
& e
)
329 void key_entry_dialog::on_cancel(wxCommandEvent
& e
)
332 EndModal(wxID_CANCEL
);
335 void key_entry_dialog::set_class(const std::string
& _class
)
340 if(currentclass
== _class
)
343 for(auto i
: classes
[_class
])
344 mainkey
->Append(towxstring(i
));
345 currentclass
= _class
;
346 mainkey
->SetSelection(0);
352 void key_entry_dialog::on_classchange(wxCommandEvent
& e
)
355 set_class(tostdstring(mainclass
->GetValue()));
358 std::string
key_entry_dialog::getkey()
366 for(auto i
: modifiers
) {
367 if(i
.second
.pressed
->GetSelection() == 2) {
376 for(auto i
: modifiers
) {
377 if(i
.second
.pressed
->GetSelection() != 1) {
384 x
= x
+ "|" + tostdstring(mainkey
->GetValue());
388 std::string
clean_keystring(const std::string
& in
)
390 regex_results tmp
= regex("(.*)/(.*)\\|(.*)", in
);
393 std::string mods
= tmp
[1];
394 std::string mask
= tmp
[2];
395 std::string key
= tmp
[3];
396 std::set
<std::string
> _mods
, _mask
;
398 for(auto& tmp2
: token_iterator
<char>::foreach(mods
, {","}))
400 for(auto& tmp2
: token_iterator
<char>::foreach(mask
, {","}))
408 out
= out
+ "!" + i
+ "+";