Wxwidgets: Move the rest of config to main configuration dialog

This commit is contained in:
Ilari Liusvaara 2012-04-08 13:32:01 +03:00
parent daa849e163
commit 4eac708596
7 changed files with 810 additions and 583 deletions

View file

@ -197,7 +197,7 @@ namespace
}; };
x << (k + 1) << get_logical_button_name(i); x << (k + 1) << get_logical_button_name(i);
y << (k + 1) << get_logical_button_name(i); y << (k + 1) << get_logical_button_name(i);
expx << "Controller " << (k + 1) << " " << get_logical_button_name(i); expx << "Controller" << (k + 1) << "" << get_logical_button_name(i);
our_commands.insert(new button_action(x.str(), j, k, y.str())); our_commands.insert(new button_action(x.str(), j, k, y.str()));
if(j == 0) if(j == 0)
our_icommands.insert(new inverse_key(x.str(), expx.str())); our_icommands.insert(new inverse_key(x.str(), expx.str()));
@ -205,7 +205,7 @@ namespace
for(unsigned k = 0; k < 8; ++k) { for(unsigned k = 0; k < 8; ++k) {
stringfmt x, expx; stringfmt x, expx;
x << "controller" << (k + 1) << "analog"; x << "controller" << (k + 1) << "analog";
expx << "Controller " << (k + 1) << " analog function"; expx << "Controller" << (k + 1) << "‣Analog function";
our_commands.insert(new analog_action(x.str(), k)); our_commands.insert(new analog_action(x.str(), k));
our_icommands.insert(new inverse_key(x.str(), expx.str())); our_icommands.insert(new inverse_key(x.str(), expx.str()));
} }

View file

@ -12,7 +12,6 @@
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#define DEFAULT_NOMINAL_RATE 60
#define HISTORY_FRAMES 10 #define HISTORY_FRAMES 10
namespace namespace
@ -22,7 +21,7 @@ namespace
bool time_frozen = true; bool time_frozen = true;
uint64_t frame_number = 0; uint64_t frame_number = 0;
uint64_t frame_start_times[HISTORY_FRAMES]; uint64_t frame_start_times[HISTORY_FRAMES];
double nominal_rate = DEFAULT_NOMINAL_RATE; double nominal_rate = 100;
bool target_nominal = true; bool target_nominal = true;
double target_fps = 100.0; double target_fps = 100.0;
bool target_infinite = false; bool target_infinite = false;
@ -130,8 +129,8 @@ namespace
turboed = false; turboed = false;
}); });
inverse_key turboh("+turbo", "Turbo on hold"); inverse_key turboh("+turbo", "Speed‣Turbo hold");
inverse_key turbot("toggle-turbo", "Toggle turbo"); inverse_key turbot("toggle-turbo", "Speed‣Turbo toggle");
} }
void freeze_time(uint64_t curtime) void freeze_time(uint64_t curtime)

View file

@ -662,86 +662,86 @@ namespace
while(1); while(1);
}); });
inverse_key ipause_emulator("pause-emulator", "(Un)pause"); inverse_key ipause_emulator("pause-emulator", "Speed‣(Un)pause");
inverse_key ijback("cycle-jukebox-backward", "Cycle slot backwards"); inverse_key ijback("cycle-jukebox-backward", "Slot select‣Cycle backwards");
inverse_key ijforward("cycle-jukebox-forward", "Cycle slot forwards"); inverse_key ijforward("cycle-jukebox-forward", "Slot select‣Cycle forwards");
inverse_key iloadj("load-jukebox", "load selected slot"); inverse_key iloadj("load-jukebox", "Load‣Selected slot");
inverse_key isavej("save-jukebox", "Save selected slot"); inverse_key isavej("save-jukebox", "Save‣Selected slot");
inverse_key iadvframe("+advance-frame", "Advance frame"); inverse_key iadvframe("+advance-frame", "Speed‣Advance frame");
inverse_key iadvsubframe("+advance-poll", "Advance subframe"); inverse_key iadvsubframe("+advance-poll", "Speed‣Advance subframe");
inverse_key iskiplag("advance-skiplag", "Advance to next poll"); inverse_key iskiplag("advance-skiplag", "Speed‣Advance poll");
inverse_key ireset("reset", "System reset"); inverse_key ireset("reset", "System‣Reset");
inverse_key iset_rwmode("set-rwmode", "Switch to read/write"); inverse_key iset_rwmode("set-rwmode", "Movie‣Switch to read/write");
inverse_key itoggle_romode("set-romode", "Switch to read-only"); inverse_key itoggle_romode("set-romode", "Movie‣Switch to read-only");
inverse_key itoggle_rwmode("toggle-rwmode", "Toggle read-only"); inverse_key itoggle_rwmode("toggle-rwmode", "Movie‣Toggle read-only");
inverse_key irepaint("repaint", "Repaint screen"); inverse_key irepaint("repaint", "System‣Repaint screen");
inverse_key itogglepause("toggle-pause-on-end", "Toggle pause-on-end"); inverse_key itogglepause("toggle-pause-on-end", "Movie‣Toggle pause-on-end");
inverse_key irewind_movie("rewind-movie", "Rewind movie"); inverse_key irewind_movie("rewind-movie", "Movie‣Rewind movie");
inverse_key icancel_saves("cancel-saves", "Cancel pending saves"); inverse_key icancel_saves("cancel-saves", "Save‣Cancel pending saves");
inverse_key iload1("load ${project}1.lsmv", "Load slot 1"); inverse_key iload1("load ${project}1.lsmv", "Load‣Slot 1");
inverse_key iload2("load ${project}2.lsmv", "Load slot 2"); inverse_key iload2("load ${project}2.lsmv", "Load‣Slot 2");
inverse_key iload3("load ${project}3.lsmv", "Load slot 3"); inverse_key iload3("load ${project}3.lsmv", "Load‣Slot 3");
inverse_key iload4("load ${project}4.lsmv", "Load slot 4"); inverse_key iload4("load ${project}4.lsmv", "Load‣Slot 4");
inverse_key iload5("load ${project}5.lsmv", "Load slot 5"); inverse_key iload5("load ${project}5.lsmv", "Load‣Slot 5");
inverse_key iload6("load ${project}6.lsmv", "Load slot 6"); inverse_key iload6("load ${project}6.lsmv", "Load‣Slot 6");
inverse_key iload7("load ${project}7.lsmv", "Load slot 7"); inverse_key iload7("load ${project}7.lsmv", "Load‣Slot 7");
inverse_key iload8("load ${project}8.lsmv", "Load slot 8"); inverse_key iload8("load ${project}8.lsmv", "Load‣Slot 8");
inverse_key iload9("load ${project}9.lsmv", "Load slot 9"); inverse_key iload9("load ${project}9.lsmv", "Load‣Slot 9");
inverse_key iload10("load ${project}10.lsmv", "Load slot 10"); inverse_key iload10("load ${project}10.lsmv", "Load‣Slot 10");
inverse_key iload11("load ${project}11.lsmv", "Load slot 11"); inverse_key iload11("load ${project}11.lsmv", "Load‣Slot 11");
inverse_key iload12("load ${project}12.lsmv", "Load slot 12"); inverse_key iload12("load ${project}12.lsmv", "Load‣Slot 12");
inverse_key iload13("load ${project}13.lsmv", "Load slot 13"); inverse_key iload13("load ${project}13.lsmv", "Load‣Slot 13");
inverse_key iload14("load ${project}14.lsmv", "Load slot 14"); inverse_key iload14("load ${project}14.lsmv", "Load‣Slot 14");
inverse_key iload15("load ${project}15.lsmv", "Load slot 15"); inverse_key iload15("load ${project}15.lsmv", "Load‣Slot 15");
inverse_key iload16("load ${project}16.lsmv", "Load slot 16"); inverse_key iload16("load ${project}16.lsmv", "Load‣Slot 16");
inverse_key iload17("load ${project}17.lsmv", "Load slot 17"); inverse_key iload17("load ${project}17.lsmv", "Load‣Slot 17");
inverse_key iload18("load ${project}18.lsmv", "Load slot 18"); inverse_key iload18("load ${project}18.lsmv", "Load‣Slot 18");
inverse_key iload19("load ${project}19.lsmv", "Load slot 19"); inverse_key iload19("load ${project}19.lsmv", "Load‣Slot 19");
inverse_key iload20("load ${project}20.lsmv", "Load slot 20"); inverse_key iload20("load ${project}20.lsmv", "Load‣Slot 20");
inverse_key iload21("load ${project}21.lsmv", "Load slot 21"); inverse_key iload21("load ${project}21.lsmv", "Load‣Slot 21");
inverse_key iload22("load ${project}22.lsmv", "Load slot 22"); inverse_key iload22("load ${project}22.lsmv", "Load‣Slot 22");
inverse_key iload23("load ${project}23.lsmv", "Load slot 23"); inverse_key iload23("load ${project}23.lsmv", "Load‣Slot 23");
inverse_key iload24("load ${project}24.lsmv", "Load slot 24"); inverse_key iload24("load ${project}24.lsmv", "Load‣Slot 24");
inverse_key iload25("load ${project}25.lsmv", "Load slot 25"); inverse_key iload25("load ${project}25.lsmv", "Load‣Slot 25");
inverse_key iload26("load ${project}26.lsmv", "Load slot 26"); inverse_key iload26("load ${project}26.lsmv", "Load‣Slot 26");
inverse_key iload27("load ${project}27.lsmv", "Load slot 27"); inverse_key iload27("load ${project}27.lsmv", "Load‣Slot 27");
inverse_key iload28("load ${project}28.lsmv", "Load slot 28"); inverse_key iload28("load ${project}28.lsmv", "Load‣Slot 28");
inverse_key iload29("load ${project}29.lsmv", "Load slot 29"); inverse_key iload29("load ${project}29.lsmv", "Load‣Slot 29");
inverse_key iload30("load ${project}30.lsmv", "Load slot 30"); inverse_key iload30("load ${project}30.lsmv", "Load‣Slot 30");
inverse_key iload31("load ${project}31.lsmv", "Load slot 31"); inverse_key iload31("load ${project}31.lsmv", "Load‣Slot 31");
inverse_key iload32("load ${project}32.lsmv", "Load slot 32"); inverse_key iload32("load ${project}32.lsmv", "Load‣Slot 32");
inverse_key isave1("save-state ${project}1.lsmv", "Save slot 1"); inverse_key isave1("save-state ${project}1.lsmv", "Save‣Slot 1");
inverse_key isave2("save-state ${project}2.lsmv", "Save slot 2"); inverse_key isave2("save-state ${project}2.lsmv", "Save‣Slot 2");
inverse_key isave3("save-state ${project}3.lsmv", "Save slot 3"); inverse_key isave3("save-state ${project}3.lsmv", "Save‣Slot 3");
inverse_key isave4("save-state ${project}4.lsmv", "Save slot 4"); inverse_key isave4("save-state ${project}4.lsmv", "Save‣Slot 4");
inverse_key isave5("save-state ${project}5.lsmv", "Save slot 5"); inverse_key isave5("save-state ${project}5.lsmv", "Save‣Slot 5");
inverse_key isave6("save-state ${project}6.lsmv", "Save slot 6"); inverse_key isave6("save-state ${project}6.lsmv", "Save‣Slot 6");
inverse_key isave7("save-state ${project}7.lsmv", "Save slot 7"); inverse_key isave7("save-state ${project}7.lsmv", "Save‣Slot 7");
inverse_key isave8("save-state ${project}8.lsmv", "Save slot 8"); inverse_key isave8("save-state ${project}8.lsmv", "Save‣Slot 8");
inverse_key isave9("save-state ${project}9.lsmv", "Save slot 9"); inverse_key isave9("save-state ${project}9.lsmv", "Save‣Slot 9");
inverse_key isave10("save-state ${project}10.lsmv", "Save slot 10"); inverse_key isave10("save-state ${project}10.lsmv", "Save‣Slot 10");
inverse_key isave11("save-state ${project}11.lsmv", "Save slot 11"); inverse_key isave11("save-state ${project}11.lsmv", "Save‣Slot 11");
inverse_key isave12("save-state ${project}12.lsmv", "Save slot 12"); inverse_key isave12("save-state ${project}12.lsmv", "Save‣Slot 12");
inverse_key isave13("save-state ${project}13.lsmv", "Save slot 13"); inverse_key isave13("save-state ${project}13.lsmv", "Save‣Slot 13");
inverse_key isave14("save-state ${project}14.lsmv", "Save slot 14"); inverse_key isave14("save-state ${project}14.lsmv", "Save‣Slot 14");
inverse_key isave15("save-state ${project}15.lsmv", "Save slot 15"); inverse_key isave15("save-state ${project}15.lsmv", "Save‣Slot 15");
inverse_key isave16("save-state ${project}16.lsmv", "Save slot 16"); inverse_key isave16("save-state ${project}16.lsmv", "Save‣Slot 16");
inverse_key isave17("save-state ${project}17.lsmv", "Save slot 17"); inverse_key isave17("save-state ${project}17.lsmv", "Save‣Slot 17");
inverse_key isave18("save-state ${project}18.lsmv", "Save slot 18"); inverse_key isave18("save-state ${project}18.lsmv", "Save‣Slot 18");
inverse_key isave19("save-state ${project}19.lsmv", "Save slot 19"); inverse_key isave19("save-state ${project}19.lsmv", "Save‣Slot 19");
inverse_key isave20("save-state ${project}20.lsmv", "Save slot 20"); inverse_key isave20("save-state ${project}20.lsmv", "Save‣Slot 20");
inverse_key isave21("save-state ${project}21.lsmv", "Save slot 21"); inverse_key isave21("save-state ${project}21.lsmv", "Save‣Slot 21");
inverse_key isave22("save-state ${project}22.lsmv", "Save slot 22"); inverse_key isave22("save-state ${project}22.lsmv", "Save‣Slot 22");
inverse_key isave23("save-state ${project}23.lsmv", "Save slot 23"); inverse_key isave23("save-state ${project}23.lsmv", "Save‣Slot 23");
inverse_key isave24("save-state ${project}24.lsmv", "Save slot 24"); inverse_key isave24("save-state ${project}24.lsmv", "Save‣Slot 24");
inverse_key isave25("save-state ${project}25.lsmv", "Save slot 25"); inverse_key isave25("save-state ${project}25.lsmv", "Save‣Slot 25");
inverse_key isave26("save-state ${project}26.lsmv", "Save slot 26"); inverse_key isave26("save-state ${project}26.lsmv", "Save‣Slot 26");
inverse_key isave27("save-state ${project}27.lsmv", "Save slot 27"); inverse_key isave27("save-state ${project}27.lsmv", "Save‣Slot 27");
inverse_key isave28("save-state ${project}28.lsmv", "Save slot 28"); inverse_key isave28("save-state ${project}28.lsmv", "Save‣Slot 28");
inverse_key isave29("save-state ${project}29.lsmv", "Save slot 29"); inverse_key isave29("save-state ${project}29.lsmv", "Save‣Slot 29");
inverse_key isave30("save-state ${project}30.lsmv", "Save slot 30"); inverse_key isave30("save-state ${project}30.lsmv", "Save‣Slot 30");
inverse_key isave31("save-state ${project}31.lsmv", "Save slot 31"); inverse_key isave31("save-state ${project}31.lsmv", "Save‣Slot 31");
inverse_key isave32("save-state ${project}32.lsmv", "Save slot 32"); inverse_key isave32("save-state ${project}32.lsmv", "Save‣Slot 32");
bool on_quit_prompt = false; bool on_quit_prompt = false;
class mywindowcallbacks : public information_dispatch class mywindowcallbacks : public information_dispatch

View file

@ -148,8 +148,8 @@ namespace
} }
}); });
inverse_key ienable_sound("enable-sound on", "Enable sound"); inverse_key ienable_sound("enable-sound on", "Sound‣Enable");
inverse_key idisable_sound("enable-sound off", "Disable sound"); inverse_key idisable_sound("enable-sound off", "Sound‣Disable");
function_ptr_command<const std::string&> set_sound_device("set-sound-device", "Set sound device", function_ptr_command<const std::string&> set_sound_device("set-sound-device", "Set sound device",
"Syntax: set-sound-device <id>\nSet sound device to <id>.\n", "Syntax: set-sound-device <id>\nSet sound device to <id>.\n",

View file

@ -1,430 +0,0 @@
#include "platform/wxwidgets/platform.hpp"
#include "core/keymapper.hpp"
#include <wx/wx.h>
namespace
{
struct keyentry_mod_data
{
wxCheckBox* pressed;
wxCheckBox* unmasked;
unsigned tmpflags;
};
class wxdialog_keyentry : public wxDialog
{
public:
wxdialog_keyentry(wxWindow* parent, const std::string& title, const std::string& spec,
bool clearable);
void on_change_setting(wxCommandEvent& e);
void on_ok(wxCommandEvent& e);
void on_cancel(wxCommandEvent& e);
void on_clear(wxCommandEvent& e);
void on_classchange(wxCommandEvent& e);
std::string getkey();
private:
void set_mask(const std::string& mod);
void set_mod(const std::string& mod);
void set_set(const std::string& mset,
void (wxdialog_keyentry::*fn)(const std::string& mod));
void load_spec(const std::string& spec);
std::map<std::string, keyentry_mod_data> modifiers;
wxComboBox* mainclass;
wxComboBox* mainkey;
wxButton* ok;
wxButton* cancel;
wxButton* clear;
bool cleared;
};
class wxdialog_hotkeys;
class hotkey
{
public:
hotkey(wxdialog_hotkeys* h, wxWindow* win, wxSizer* s, inverse_key* ikey, unsigned o);
void update(const std::string& primary, const std::string& secondary);
inverse_key* get_associated();
std::string get_title();
private:
wxButton* primaryb;
wxButton* secondaryb;
inverse_key* associated;
std::string title;
};
class wxdialog_hotkeys : public wxDialog
{
public:
wxdialog_hotkeys(wxWindow* parent);
~wxdialog_hotkeys();
void on_close(wxCommandEvent& e);
void on_reconfig(wxCommandEvent& e);
private:
void update();
wxScrolledWindow* scroll;
wxSizer* scroll_sizer;
std::map<unsigned, hotkey*> hotkeys;
wxButton* close;
};
wxdialog_keyentry::wxdialog_keyentry(wxWindow* parent, const std::string& title, const std::string& spec,
bool clearable)
: wxDialog(parent, wxID_ANY, towxstring(title), wxDefaultPosition, wxSize(-1, -1))
{
std::vector<wxString> keych;
std::set<std::string> mods, keys;
cleared = false;
runemufn([&mods, &keys]() { mods = modifier::get_set(); keys = keygroup::get_keys(); });
Centre();
wxFlexGridSizer* top_s = new wxFlexGridSizer(2, 1, 0, 0);
SetSizer(top_s);
wxFlexGridSizer* t_s = new wxFlexGridSizer(mods.size() + 1, 3, 0, 0);
for(auto i : mods) {
t_s->Add(new wxStaticText(this, wxID_ANY, towxstring(i)), 0, wxGROW);
keyentry_mod_data m;
t_s->Add(m.pressed = new wxCheckBox(this, wxID_ANY, wxT("Pressed")), 0, wxGROW);
t_s->Add(m.unmasked = new wxCheckBox(this, wxID_ANY, wxT("Unmasked")), 0, wxGROW);
m.pressed->Disable();
modifiers[i] = m;
m.pressed->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_change_setting), NULL, this);
m.unmasked->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_change_setting), NULL, this);
}
for(auto i : keys)
keych.push_back(towxstring(i));
t_s->Add(new wxStaticText(this, wxID_ANY, wxT("Key")), 0, wxGROW);
t_s->Add(mainkey = new wxComboBox(this, wxID_ANY, keych[0], wxDefaultPosition, wxDefaultSize,
keych.size(), &keych[0], wxCB_READONLY), 1, wxGROW);
mainkey->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED,
wxCommandEventHandler(wxdialog_keyentry::on_change_setting), NULL, this);
top_s->Add(t_s);
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
if(clearable)
pbutton_s->Add(clear = new wxButton(this, wxID_OK, wxT("Clear")), 0, wxGROW);
pbutton_s->AddStretchSpacer();
pbutton_s->Add(ok = new wxButton(this, wxID_OK, wxT("OK")), 0, wxGROW);
pbutton_s->Add(cancel = new wxButton(this, wxID_CANCEL, wxT("Cancel")), 0, wxGROW);
ok->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_ok), NULL, this);
cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_cancel), NULL, this);
if(clearable)
clear->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_clear), NULL, this);
top_s->Add(pbutton_s, 0, wxGROW);
t_s->SetSizeHints(this);
top_s->SetSizeHints(this);
Fit();
if(spec != "")
load_spec(spec);
}
#define TMPFLAG_UNMASKED 65
#define TMPFLAG_UNMASKED_LINK_CHILD 2
#define TMPFLAG_UNMASKED_LINK_PARENT 68
#define TMPFLAG_PRESSED 8
#define TMPFLAG_PRESSED_LINK_CHILD 16
#define TMPFLAG_PRESSED_LINK_PARENT 32
void wxdialog_keyentry::set_mask(const std::string& mod)
{
if(!modifiers.count(mod))
return;
if(modifiers[mod].unmasked->IsEnabled()) {
wxCommandEvent e;
modifiers[mod].unmasked->SetValue(true);
on_change_setting(e);
}
}
void wxdialog_keyentry::set_mod(const std::string& mod)
{
if(!modifiers.count(mod))
return;
if(modifiers[mod].pressed->IsEnabled()) {
wxCommandEvent e;
modifiers[mod].pressed->SetValue(true);
on_change_setting(e);
}
}
void wxdialog_keyentry::set_set(const std::string& mset,
void (wxdialog_keyentry::*fn)(const std::string& mod))
{
std::string rem = mset;
while(rem != "") {
size_t s = rem.find_first_of(",");
if(s >= rem.length()) {
(this->*fn)(rem);
break;
} else {
(this->*fn)(rem.substr(0, s));
rem = rem.substr(s + 1);
}
}
}
void wxdialog_keyentry::load_spec(const std::string& spec)
{
std::string _spec = spec;
size_t s1 = _spec.find_first_of("/");
size_t s2 = _spec.find_first_of("|");
if(s1 >= _spec.length() || s2 >= _spec.length())
return; //Bad.
std::string mod = _spec.substr(0, s1);
std::string mask = _spec.substr(s1 + 1, s2 - s1 - 1);
std::string key = _spec.substr(s2 + 1);
set_set(mask, &wxdialog_keyentry::set_mask);
set_set(mod, &wxdialog_keyentry::set_mod);
mainkey->SetValue(towxstring(key));
}
void wxdialog_keyentry::on_change_setting(wxCommandEvent& e)
{
for(auto& i : modifiers)
i.second.tmpflags = 0;
for(auto& i : modifiers) {
modifier* m = NULL;
try {
m = &modifier::lookup(i.first);
} catch(...) {
i.second.pressed->Disable();
i.second.unmasked->Disable();
continue;
}
std::string j = m->linked_name();
if(i.second.unmasked->GetValue())
i.second.tmpflags |= TMPFLAG_UNMASKED;
if(j != "") {
if(modifiers[j].unmasked->GetValue())
i.second.tmpflags |= TMPFLAG_UNMASKED_LINK_PARENT;
if(i.second.unmasked->GetValue())
modifiers[j].tmpflags |= TMPFLAG_UNMASKED_LINK_CHILD;
}
if(i.second.pressed->GetValue())
i.second.tmpflags |= TMPFLAG_PRESSED;
if(j != "") {
if(modifiers[j].pressed->GetValue())
i.second.tmpflags |= TMPFLAG_PRESSED_LINK_PARENT;
if(i.second.pressed->GetValue())
modifiers[j].tmpflags |= TMPFLAG_PRESSED_LINK_CHILD;
}
}
for(auto& i : modifiers) {
//Unmasked is to be enabled if neither unmasked link flag is set.
if(i.second.tmpflags & ((TMPFLAG_UNMASKED_LINK_CHILD | TMPFLAG_UNMASKED_LINK_PARENT) & ~64)) {
i.second.unmasked->SetValue(false);
i.second.unmasked->Disable();
} else
i.second.unmasked->Enable();
//Pressed is to be enabled if:
//- This modifier is unmasked or parent is unmasked.
//- Parent nor child is not pressed.
if(((i.second.tmpflags & (TMPFLAG_UNMASKED | TMPFLAG_UNMASKED_LINK_PARENT |
TMPFLAG_PRESSED_LINK_CHILD | TMPFLAG_PRESSED_LINK_PARENT)) & 112) == 64)
i.second.pressed->Enable();
else {
i.second.pressed->SetValue(false);
i.second.pressed->Disable();
}
}
}
void wxdialog_keyentry::on_ok(wxCommandEvent& e)
{
EndModal(wxID_OK);
}
void wxdialog_keyentry::on_clear(wxCommandEvent& e)
{
cleared = true;
EndModal(wxID_OK);
}
void wxdialog_keyentry::on_cancel(wxCommandEvent& e)
{
EndModal(wxID_CANCEL);
}
std::string wxdialog_keyentry::getkey()
{
if(cleared)
return "";
std::string x;
bool f;
f = true;
for(auto i : modifiers) {
if(i.second.pressed->GetValue()) {
if(!f)
x = x + ",";
f = false;
x = x + i.first;
}
}
x = x + "/";
f = true;
for(auto i : modifiers) {
if(i.second.unmasked->GetValue()) {
if(!f)
x = x + ",";
f = false;
x = x + i.first;
}
}
x = x + "|" + tostdstring(mainkey->GetValue());
return x;
}
wxdialog_hotkeys::wxdialog_hotkeys(wxWindow* parent)
: wxDialog(parent, wxID_ANY, wxT("Hotkeys"), wxDefaultPosition, wxSize(-1, -1))
{
scroll = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1));
scroll->SetMinSize(wxSize(-1, 500));
Centre();
wxFlexGridSizer* top_s = new wxFlexGridSizer(2, 1, 0, 0);
SetSizer(top_s);
scroll_sizer = new wxFlexGridSizer(0, 3, 0, 0);
scroll->SetSizer(scroll_sizer);
//Obtain all the inverses.
std::set<inverse_key*> inverses;
runemufn([&inverses]() {
auto x = inverse_key::get_ikeys();
for(auto y : x)
inverses.insert(y);
});
unsigned y = 0;
for(auto x : inverses) {
hotkeys[y] = new hotkey(this, scroll, scroll_sizer, x, y);
y++;
}
update();
top_s->Add(scroll);
scroll->SetScrollRate(0, 20);
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
pbutton_s->AddStretchSpacer();
pbutton_s->Add(close = new wxButton(this, wxID_CANCEL, wxT("Close")), 0, wxGROW);
close->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxdialog_hotkeys::on_close), NULL, this);
top_s->Add(pbutton_s, 0, wxGROW);
scroll_sizer->SetSizeHints(this);
top_s->SetSizeHints(this);
scroll_sizer->Layout();
top_s->Layout();
Fit();
}
void wxdialog_hotkeys::on_reconfig(wxCommandEvent& e)
{
int id = e.GetId();
if(id <= wxID_HIGHEST)
return;
unsigned button = (id - wxID_HIGHEST - 1) / 2;
bool primflag = (((id - wxID_HIGHEST - 1) % 2) == 0);
if(!hotkeys.count(button))
return;
wxdialog_keyentry* d = new wxdialog_keyentry(this, "Specify key for " + hotkeys[button]->
get_title(), hotkeys[button]->get_associated()->get(primflag), true);
if(d->ShowModal() == wxID_CANCEL) {
d->Destroy();
return;
}
std::string key = d->getkey();
d->Destroy();
if(key != "")
hotkeys[button]->get_associated()->set(key, primflag);
else
hotkeys[button]->get_associated()->clear(primflag);
update();
}
void wxdialog_hotkeys::update()
{
std::map<inverse_key*, std::pair<std::string, std::string>> data;
runemufn([&data]() {
auto x = inverse_key::get_ikeys();
for(auto y : x)
data[y] = std::make_pair(y->get(true), y->get(false));
});
for(auto i : hotkeys) {
inverse_key* j = i.second->get_associated();
if(!data.count(j))
continue;
auto y = data[j];
i.second->update(y.first, y.second);
}
}
wxdialog_hotkeys::~wxdialog_hotkeys()
{
for(auto i : hotkeys)
delete i.second;
}
void wxdialog_hotkeys::on_close(wxCommandEvent& e)
{
EndModal(wxID_OK);
}
hotkey::hotkey(wxdialog_hotkeys* h, wxWindow* win, wxSizer* s, inverse_key* ikey, unsigned o)
{
title = ikey->getname();
s->Add(new wxStaticText(win, wxID_ANY, towxstring(title)), 0, wxGROW);
s->Add(primaryb = new wxButton(win, wxID_HIGHEST + 1 + 2 * o, wxT("(none)"), wxDefaultPosition,
wxSize(200, -1)), 0, wxGROW);
s->Add(secondaryb = new wxButton(win, wxID_HIGHEST + 2 + 2 * o, wxT("(none)"), wxDefaultPosition,
wxSize(200, -1)), 0, wxGROW);
primaryb->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxdialog_hotkeys::on_reconfig), NULL, h);
secondaryb->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxdialog_hotkeys::on_reconfig), NULL, h);
associated = ikey;
}
inverse_key* hotkey::get_associated()
{
return associated;
}
std::string hotkey::get_title()
{
return title;
}
void hotkey::update(const std::string& primary, const std::string& secondary)
{
primaryb->SetLabel((primary != "") ? towxstring(primary) : towxstring("(none)"));
secondaryb->SetLabel((secondary != "") ? towxstring(secondary) : towxstring("(none)"));
}
}
std::string wxeditor_keyselect(wxWindow* parent, bool clearable)
{
wxdialog_keyentry* d = new wxdialog_keyentry(parent, "Specify key", "", clearable);
if(d->ShowModal() == wxID_CANCEL) {
d->Destroy();
throw canceled_exception();
}
std::string key = d->getkey();
d->Destroy();
return key;
}
void wxeditor_hotkeys_display(wxWindow* parent)
{
modal_pause_holder hld;
wxdialog_hotkeys* d = new wxdialog_hotkeys(parent);
d->ShowModal();
d->Destroy();
}

View file

@ -63,8 +63,6 @@ enum
wxID_EDIT_AUTHORS, wxID_EDIT_AUTHORS,
wxID_AUTOHOLD_FIRST, wxID_AUTOHOLD_FIRST,
wxID_AUTOHOLD_LAST = wxID_AUTOHOLD_FIRST + 1023, wxID_AUTOHOLD_LAST = wxID_AUTOHOLD_FIRST + 1023,
wxID_EDIT_KEYBINDINGS,
wxID_EDIT_ALIAS,
wxID_EDIT_MEMORYWATCH, wxID_EDIT_MEMORYWATCH,
wxID_SAVE_MEMORYWATCH, wxID_SAVE_MEMORYWATCH,
wxID_LOAD_MEMORYWATCH, wxID_LOAD_MEMORYWATCH,
@ -73,7 +71,6 @@ enum
wxID_REWIND_MOVIE, wxID_REWIND_MOVIE,
wxID_MEMORY_SEARCH, wxID_MEMORY_SEARCH,
wxID_CANCEL_SAVES, wxID_CANCEL_SAVES,
wxID_EDIT_HOTKEYS,
wxID_SHOW_STATUS, wxID_SHOW_STATUS,
wxID_SET_SPEED, wxID_SET_SPEED,
wxID_SET_VOLUME, wxID_SET_VOLUME,
@ -764,12 +761,6 @@ wxwin_mainwindow::wxwin_mainwindow()
menu_special(wxT("Capture"), reinterpret_cast<dumper_menu*>(dmenu = new dumper_menu(this, menu_special(wxT("Capture"), reinterpret_cast<dumper_menu*>(dmenu = new dumper_menu(this,
wxID_DUMP_FIRST, wxID_DUMP_LAST))); wxID_DUMP_FIRST, wxID_DUMP_LAST)));
menu_start(wxT("Settings"));
menu_entry(wxID_EDIT_KEYBINDINGS, wxT("Configure keybindings..."));
menu_entry(wxID_EDIT_ALIAS, wxT("Configure aliases..."));
menu_separator();
menu_entry(wxID_EDIT_HOTKEYS, wxT("Configure hotkeys..."));
} }
void wxwin_mainwindow::request_paint() void wxwin_mainwindow::request_paint()
@ -912,62 +903,6 @@ void wxwin_mainwindow::handle_menu_click_cancelable(wxCommandEvent& e)
case wxID_EDIT_AUTHORS: case wxID_EDIT_AUTHORS:
wxeditor_authors_display(this); wxeditor_authors_display(this);
return; return;
case wxID_EDIT_HOTKEYS:
wxeditor_hotkeys_display(this);
return;
case wxID_EDIT_KEYBINDINGS: {
modal_pause_holder hld;
std::set<std::string> bind;
runemufn([&bind]() { bind = keymapper::get_bindings(); });
std::vector<std::string> choices;
choices.push_back(NEW_KEYBINDING);
for(auto i : bind)
choices.push_back(i);
std::string key = pick_among(this, "Select binding", "Select keybinding to edit", choices);
if(key == NEW_KEYBINDING)
key = wxeditor_keyselect(this, false);
std::string old_command_value;
runemufn([&old_command_value, key]() { old_command_value = keymapper::get_command_for(key); });
std::string newcommand = pick_text(this, "Edit binding", "Enter new command for binding:",
old_command_value);
bool fault = false;
std::string faulttext;
runemufn([&fault, &faulttext, key, newcommand]() {
try {
keymapper::bind_for(key, newcommand);
} catch(std::exception& e) {
fault = true;
faulttext = e.what();
}
});
if(fault)
show_message_ok(this, "Error", "Can't bind key: " + faulttext, wxICON_EXCLAMATION);
return;
}
case wxID_EDIT_ALIAS: {
modal_pause_holder hld;
std::set<std::string> bind;
runemufn([&bind]() { bind = command::get_aliases(); });
std::vector<std::string> choices;
choices.push_back(NEW_ALIAS);
for(auto i : bind)
choices.push_back(i);
std::string alias = pick_among(this, "Select alias", "Select alias to edit", choices);
if(alias == NEW_ALIAS) {
alias = pick_text(this, "Enter alias name", "Enter name for the new alias:");
if(!command::valid_alias_name(alias)) {
show_message_ok(this, "Error", "Not a valid alias name: " + alias,
wxICON_EXCLAMATION);
throw canceled_exception();
}
}
std::string old_alias_value;
runemufn([alias, &old_alias_value]() { old_alias_value = command::get_alias_for(alias); });
std::string newcmd = pick_text(this, "Edit alias", "Enter new commands for alias:",
old_alias_value, true);
runemufn([alias, newcmd]() { command::set_alias_for(alias, newcmd); });
return;
}
case wxID_EDIT_MEMORYWATCH: { case wxID_EDIT_MEMORYWATCH: {
modal_pause_holder hld; modal_pause_holder hld;
std::set<std::string> bind; std::set<std::string> bind;

View file

@ -1,10 +1,12 @@
#include "platform/wxwidgets/platform.hpp" #include "platform/wxwidgets/platform.hpp"
#include "core/command.hpp"
#include "core/dispatch.hpp" #include "core/dispatch.hpp"
#include "core/settings.hpp" #include "core/settings.hpp"
#include "library/string.hpp" #include "library/string.hpp"
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/treectrl.h>
#include <wx/event.h> #include <wx/event.h>
#include <wx/control.h> #include <wx/control.h>
#include <wx/combobox.h> #include <wx/combobox.h>
@ -42,6 +44,256 @@ extern "C"
const char* scalealgo_choices[] = {"Fast Bilinear", "Bilinear", "Bicubic", "Experimential", "Point", "Area", const char* scalealgo_choices[] = {"Fast Bilinear", "Bilinear", "Bicubic", "Experimential", "Point", "Area",
"Bicubic-Linear", "Gauss", "Sinc", "Lanczos", "Spline"}; "Bicubic-Linear", "Gauss", "Sinc", "Lanczos", "Spline"};
namespace
{
struct keyentry_mod_data
{
wxCheckBox* pressed;
wxCheckBox* unmasked;
unsigned tmpflags;
};
class wxdialog_keyentry : public wxDialog
{
public:
wxdialog_keyentry(wxWindow* parent, const std::string& title, const std::string& spec,
bool clearable);
void on_change_setting(wxCommandEvent& e);
void on_ok(wxCommandEvent& e);
void on_cancel(wxCommandEvent& e);
void on_clear(wxCommandEvent& e);
void on_classchange(wxCommandEvent& e);
std::string getkey();
private:
void set_mask(const std::string& mod);
void set_mod(const std::string& mod);
void set_set(const std::string& mset,
void (wxdialog_keyentry::*fn)(const std::string& mod));
void load_spec(const std::string& spec);
std::map<std::string, keyentry_mod_data> modifiers;
wxComboBox* mainclass;
wxComboBox* mainkey;
wxButton* ok;
wxButton* cancel;
wxButton* clear;
bool cleared;
};
wxdialog_keyentry::wxdialog_keyentry(wxWindow* parent, const std::string& title, const std::string& spec,
bool clearable)
: wxDialog(parent, wxID_ANY, towxstring(title), wxDefaultPosition, wxSize(-1, -1))
{
std::vector<wxString> keych;
std::set<std::string> mods, keys;
cleared = false;
runemufn([&mods, &keys]() { mods = modifier::get_set(); keys = keygroup::get_keys(); });
Centre();
wxFlexGridSizer* top_s = new wxFlexGridSizer(2, 1, 0, 0);
SetSizer(top_s);
wxFlexGridSizer* t_s = new wxFlexGridSizer(mods.size() + 1, 3, 0, 0);
for(auto i : mods) {
t_s->Add(new wxStaticText(this, wxID_ANY, towxstring(i)), 0, wxGROW);
keyentry_mod_data m;
t_s->Add(m.pressed = new wxCheckBox(this, wxID_ANY, wxT("Pressed")), 0, wxGROW);
t_s->Add(m.unmasked = new wxCheckBox(this, wxID_ANY, wxT("Unmasked")), 0, wxGROW);
m.pressed->Disable();
modifiers[i] = m;
m.pressed->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_change_setting), NULL, this);
m.unmasked->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_change_setting), NULL, this);
}
for(auto i : keys)
keych.push_back(towxstring(i));
t_s->Add(new wxStaticText(this, wxID_ANY, wxT("Key")), 0, wxGROW);
t_s->Add(mainkey = new wxComboBox(this, wxID_ANY, keych[0], wxDefaultPosition, wxDefaultSize,
keych.size(), &keych[0], wxCB_READONLY), 1, wxGROW);
mainkey->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED,
wxCommandEventHandler(wxdialog_keyentry::on_change_setting), NULL, this);
top_s->Add(t_s);
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
if(clearable)
pbutton_s->Add(clear = new wxButton(this, wxID_OK, wxT("Clear")), 0, wxGROW);
pbutton_s->AddStretchSpacer();
pbutton_s->Add(ok = new wxButton(this, wxID_OK, wxT("OK")), 0, wxGROW);
pbutton_s->Add(cancel = new wxButton(this, wxID_CANCEL, wxT("Cancel")), 0, wxGROW);
ok->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_ok), NULL, this);
cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_cancel), NULL, this);
if(clearable)
clear->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxdialog_keyentry::on_clear), NULL, this);
top_s->Add(pbutton_s, 0, wxGROW);
t_s->SetSizeHints(this);
top_s->SetSizeHints(this);
Fit();
if(spec != "")
load_spec(spec);
}
#define TMPFLAG_UNMASKED 65
#define TMPFLAG_UNMASKED_LINK_CHILD 2
#define TMPFLAG_UNMASKED_LINK_PARENT 68
#define TMPFLAG_PRESSED 8
#define TMPFLAG_PRESSED_LINK_CHILD 16
#define TMPFLAG_PRESSED_LINK_PARENT 32
void wxdialog_keyentry::set_mask(const std::string& mod)
{
if(!modifiers.count(mod))
return;
if(modifiers[mod].unmasked->IsEnabled()) {
wxCommandEvent e;
modifiers[mod].unmasked->SetValue(true);
on_change_setting(e);
}
}
void wxdialog_keyentry::set_mod(const std::string& mod)
{
if(!modifiers.count(mod))
return;
if(modifiers[mod].pressed->IsEnabled()) {
wxCommandEvent e;
modifiers[mod].pressed->SetValue(true);
on_change_setting(e);
}
}
void wxdialog_keyentry::set_set(const std::string& mset,
void (wxdialog_keyentry::*fn)(const std::string& mod))
{
std::string rem = mset;
while(rem != "") {
size_t s = rem.find_first_of(",");
if(s >= rem.length()) {
(this->*fn)(rem);
break;
} else {
(this->*fn)(rem.substr(0, s));
rem = rem.substr(s + 1);
}
}
}
void wxdialog_keyentry::load_spec(const std::string& spec)
{
std::string _spec = spec;
size_t s1 = _spec.find_first_of("/");
size_t s2 = _spec.find_first_of("|");
if(s1 >= _spec.length() || s2 >= _spec.length())
return; //Bad.
std::string mod = _spec.substr(0, s1);
std::string mask = _spec.substr(s1 + 1, s2 - s1 - 1);
std::string key = _spec.substr(s2 + 1);
set_set(mask, &wxdialog_keyentry::set_mask);
set_set(mod, &wxdialog_keyentry::set_mod);
mainkey->SetValue(towxstring(key));
}
void wxdialog_keyentry::on_change_setting(wxCommandEvent& e)
{
for(auto& i : modifiers)
i.second.tmpflags = 0;
for(auto& i : modifiers) {
modifier* m = NULL;
try {
m = &modifier::lookup(i.first);
} catch(...) {
i.second.pressed->Disable();
i.second.unmasked->Disable();
continue;
}
std::string j = m->linked_name();
if(i.second.unmasked->GetValue())
i.second.tmpflags |= TMPFLAG_UNMASKED;
if(j != "") {
if(modifiers[j].unmasked->GetValue())
i.second.tmpflags |= TMPFLAG_UNMASKED_LINK_PARENT;
if(i.second.unmasked->GetValue())
modifiers[j].tmpflags |= TMPFLAG_UNMASKED_LINK_CHILD;
}
if(i.second.pressed->GetValue())
i.second.tmpflags |= TMPFLAG_PRESSED;
if(j != "") {
if(modifiers[j].pressed->GetValue())
i.second.tmpflags |= TMPFLAG_PRESSED_LINK_PARENT;
if(i.second.pressed->GetValue())
modifiers[j].tmpflags |= TMPFLAG_PRESSED_LINK_CHILD;
}
}
for(auto& i : modifiers) {
//Unmasked is to be enabled if neither unmasked link flag is set.
if(i.second.tmpflags & ((TMPFLAG_UNMASKED_LINK_CHILD | TMPFLAG_UNMASKED_LINK_PARENT) & ~64)) {
i.second.unmasked->SetValue(false);
i.second.unmasked->Disable();
} else
i.second.unmasked->Enable();
//Pressed is to be enabled if:
//- This modifier is unmasked or parent is unmasked.
//- Parent nor child is not pressed.
if(((i.second.tmpflags & (TMPFLAG_UNMASKED | TMPFLAG_UNMASKED_LINK_PARENT |
TMPFLAG_PRESSED_LINK_CHILD | TMPFLAG_PRESSED_LINK_PARENT)) & 112) == 64)
i.second.pressed->Enable();
else {
i.second.pressed->SetValue(false);
i.second.pressed->Disable();
}
}
}
void wxdialog_keyentry::on_ok(wxCommandEvent& e)
{
EndModal(wxID_OK);
}
void wxdialog_keyentry::on_clear(wxCommandEvent& e)
{
cleared = true;
EndModal(wxID_OK);
}
void wxdialog_keyentry::on_cancel(wxCommandEvent& e)
{
EndModal(wxID_CANCEL);
}
std::string wxdialog_keyentry::getkey()
{
if(cleared)
return "";
std::string x;
bool f;
f = true;
for(auto i : modifiers) {
if(i.second.pressed->GetValue()) {
if(!f)
x = x + ",";
f = false;
x = x + i.first;
}
}
x = x + "/";
f = true;
for(auto i : modifiers) {
if(i.second.unmasked->GetValue()) {
if(!f)
x = x + ",";
f = false;
x = x + i.first;
}
}
x = x + "|" + tostdstring(mainkey->GetValue());
return x;
}
}
class wxeditor_esettings_joystick_aconfig : public wxDialog class wxeditor_esettings_joystick_aconfig : public wxDialog
{ {
public: public:
@ -537,6 +789,474 @@ void wxeditor_esettings_screen::refresh()
Fit(); Fit();
} }
class wxeditor_esettings_aliases : public wxPanel
{
public:
wxeditor_esettings_aliases(wxWindow* parent);
~wxeditor_esettings_aliases();
void on_add(wxCommandEvent& e);
void on_edit(wxCommandEvent& e);
void on_delete(wxCommandEvent& e);
private:
std::map<int, std::string> numbers;
wxListBox* select;
void refresh();
std::string selected();
};
wxeditor_esettings_aliases::wxeditor_esettings_aliases(wxWindow* parent)
: wxPanel(parent, -1)
{
wxButton* tmp;
wxSizer* top_s = new wxBoxSizer(wxVERTICAL);
SetSizer(top_s);
top_s->Add(select = new wxListBox(this, wxID_ANY), 1, wxGROW);
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
pbutton_s->AddStretchSpacer();
pbutton_s->Add(tmp = new wxButton(this, wxID_ANY, wxT("Add")), 0, wxGROW);
tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_aliases::on_add), NULL,
this);
pbutton_s->Add(tmp = new wxButton(this, wxID_ANY, wxT("Edit")), 0, wxGROW);
tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_aliases::on_edit), NULL,
this);
pbutton_s->Add(tmp = new wxButton(this, wxID_ANY, wxT("Delete")), 0, wxGROW);
tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_aliases::on_delete), NULL,
this);
top_s->Add(pbutton_s, 0, wxGROW);
refresh();
top_s->SetSizeHints(this);
Fit();
}
wxeditor_esettings_aliases::~wxeditor_esettings_aliases()
{
}
void wxeditor_esettings_aliases::on_add(wxCommandEvent& e)
{
try {
std::string name = pick_text(this, "Enter alias name", "Enter name for the new alias:");
if(!command::valid_alias_name(name)) {
show_message_ok(this, "Error", "Not a valid alias name: " + name, wxICON_EXCLAMATION);
throw canceled_exception();
}
std::string old_alias_value;
runemufn([name, &old_alias_value]() { old_alias_value = command::get_alias_for(name); });
std::string newcmd = pick_text(this, "Edit alias", "Enter new commands for '" + name + "':",
old_alias_value, true);
runemufn([name, newcmd]() { command::set_alias_for(name, newcmd); });
} catch(...) {
}
refresh();
}
void wxeditor_esettings_aliases::on_edit(wxCommandEvent& e)
{
std::string name = selected();
if(name == "") {
refresh();
return;
}
try {
std::string old_alias_value;
runemufn([name, &old_alias_value]() { old_alias_value = command::get_alias_for(name); });
std::string newcmd = pick_text(this, "Edit alias", "Enter new commands for '" + name + "':",
old_alias_value, true);
runemufn([name, newcmd]() { command::set_alias_for(name, newcmd); });
} catch(...) {
}
refresh();
}
void wxeditor_esettings_aliases::on_delete(wxCommandEvent& e)
{
std::string name = selected();
if(name == "") {
refresh();
return;
}
runemufn([name]() { command::set_alias_for(name, ""); });
refresh();
}
void wxeditor_esettings_aliases::refresh()
{
int n = select->GetSelection();
std::set<std::string> bind;
std::vector<wxString> choices;
runemufn([&bind]() { bind = command::get_aliases(); });
for(auto i : bind) {
numbers[choices.size()] = i;
choices.push_back(towxstring(i));
}
select->Set(choices.size(), &choices[0]);
if(n == wxNOT_FOUND && select->GetCount())
select->SetSelection(0);
else if(n >= select->GetCount())
select->SetSelection(select->GetCount() ? (select->GetCount() - 1) : wxNOT_FOUND);
else
select->SetSelection(n);
}
std::string wxeditor_esettings_aliases::selected()
{
int x = select->GetSelection();
if(numbers.count(x))
return numbers[x];
else
return "";
}
class wxeditor_esettings_hotkeys : public wxPanel
{
public:
wxeditor_esettings_hotkeys(wxWindow* parent);
~wxeditor_esettings_hotkeys();
void on_primary(wxCommandEvent& e);
void on_secondary(wxCommandEvent& e);
private:
std::map<std::string, wxTreeItemId> items;
std::map<std::string, inverse_key*> realitems;
std::map<std::string, std::string> leafname;
wxTreeItemId true_root;
wxTreeCtrl* select;
wxButton* pri_button;
wxButton* sec_button;
void refresh();
std::string selected();
};
wxeditor_esettings_hotkeys::wxeditor_esettings_hotkeys(wxWindow* parent)
: wxPanel(parent, -1)
{
wxSizer* top_s = new wxBoxSizer(wxVERTICAL);
SetSizer(top_s);
top_s->Add(select = new wxTreeCtrl(this, wxID_ANY), 1, wxGROW);
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
pbutton_s->AddStretchSpacer();
pbutton_s->Add(pri_button = new wxButton(this, wxID_ANY, wxT("Change primary")), 0, wxGROW);
pri_button->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxeditor_esettings_hotkeys::on_primary), NULL, this);
pbutton_s->Add(sec_button = new wxButton(this, wxID_ANY, wxT("Change secondary")), 0, wxGROW);
sec_button->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxeditor_esettings_hotkeys::on_secondary), NULL, this);
top_s->Add(pbutton_s, 0, wxGROW);
items[""] = select->AddRoot(wxT(""));
refresh();
top_s->SetSizeHints(this);
Fit();
}
wxeditor_esettings_hotkeys::~wxeditor_esettings_hotkeys()
{
}
void wxeditor_esettings_hotkeys::on_primary(wxCommandEvent& e)
{
std::string name = selected();
if(name == "") {
refresh();
return;
}
try {
std::string key;
inverse_key* ik = realitems[name];
if(!ik) {
refresh();
return;
}
runemufn([&key, ik]() { key = ik->get(true); });
wxdialog_keyentry* d = new wxdialog_keyentry(this, "Specify key for " + name, key, true);
if(d->ShowModal() == wxID_CANCEL) {
d->Destroy();
return;
}
key = d->getkey();
d->Destroy();
if(key != "")
runemufn([key, ik]() { ik->set(key, true); });
else
runemufn([key, ik]() { ik->clear(true); });
refresh();
} catch(...) {
refresh();
}
}
void wxeditor_esettings_hotkeys::on_secondary(wxCommandEvent& e)
{
std::string name = selected();
if(name == "") {
refresh();
return;
}
try {
std::string key;
inverse_key* ik = realitems[name];
if(!ik) {
refresh();
return;
}
runemufn([&key, ik]() { key = ik->get(false); });
wxdialog_keyentry* d = new wxdialog_keyentry(this, "Specify key for " + name, key, true);
if(d->ShowModal() == wxID_CANCEL) {
d->Destroy();
return;
}
key = d->getkey();
d->Destroy();
if(key != "")
runemufn([key, ik]() { ik->set(key, false); });
else
runemufn([key, ik]() { ik->clear(false); });
refresh();
} catch(...) {
refresh();
}
}
void wxeditor_esettings_hotkeys::refresh()
{
std::set<std::string> closure_additional;
std::map<std::string, inverse_key*> keyorder;
std::map<inverse_key*, std::pair<std::string, std::string>> data;
runemufn([&data, &keyorder]() {
auto x = inverse_key::get_ikeys();
for(auto y : x) {
keyorder[y->getname()] = y;
data[y] = std::make_pair(y->get(true), y->get(false));
}
});
//Close keyorder with respect to parents.
for(auto i : keyorder) {
std::string tmp = i.first;
for(size_t itr = 0; itr < tmp.length() - 2 && itr < tmp.length(); itr++) {
unsigned char ch1 = tmp[itr];
unsigned char ch2 = tmp[itr + 1];
unsigned char ch3 = tmp[itr + 2];
if(ch1 == 0xE2 && ch2 == 0x80 && ch3 == 0xA3) {
closure_additional.insert(tmp.substr(0, itr));
}
}
}
for(auto i : closure_additional)
if(!keyorder.count(i)) {
keyorder[i] = NULL;
}
//Then add the needed entries to the tree. Thanks to the ordering, presence of parent before child is always
//guaranteed.
for(auto i : keyorder) {
if(!items.count(i.first)) {
//Not found, add.
//Find the parent name.
std::string tmp = i.first;
std::string parent = "";
std::string leaf = i.first;
for(size_t itr = 0; itr < tmp.length() - 2 && itr < tmp.length(); itr++) {
unsigned char ch1 = tmp[itr];
unsigned char ch2 = tmp[itr + 1];
unsigned char ch3 = tmp[itr + 2];
if(ch1 == 0xE2 && ch2 == 0x80 && ch3 == 0xA3) {
parent = tmp.substr(0, itr);
leaf = tmp.substr(itr + 3);
}
}
items[i.first] = select->AppendItem(items[parent], towxstring(leaf));
leafname[i.first] = leaf;
}
if(i.second) {
//Real, set the keys.
realitems[i.first] = i.second;
std::string text = leafname[i.first];
if(data[i.second].first == "")
text = text + " (not set)";
else if(data[i.second].second == "")
text = text + " (" + data[i.second].first + ")";
else
text = text + " (" + data[i.second].first + " or " + data[i.second].second + ")";
select->SetItemText(items[i.first], towxstring(text));
}
}
}
std::string wxeditor_esettings_hotkeys::selected()
{
wxTreeItemId sel = select->GetSelection();
std::string item;
bool found = false;
for(auto i : items)
if(i.second == sel) {
found = true;
item = i.first;
}
if(!found || !realitems.count(item))
return "";
return item;
}
class wxeditor_esettings_bindings : public wxPanel
{
public:
wxeditor_esettings_bindings(wxWindow* parent);
~wxeditor_esettings_bindings();
void on_add(wxCommandEvent& e);
void on_edit(wxCommandEvent& e);
void on_delete(wxCommandEvent& e);
private:
std::map<int, std::string> numbers;
wxListBox* select;
void refresh();
std::set<std::string> settings;
std::map<std::string, std::string> values;
std::map<int, std::string> selections;
std::string selected();
wxListBox* _settings;
};
wxeditor_esettings_bindings::wxeditor_esettings_bindings(wxWindow* parent)
: wxPanel(parent, -1)
{
wxButton* tmp;
wxSizer* top_s = new wxBoxSizer(wxVERTICAL);
SetSizer(top_s);
top_s->Add(select = new wxListBox(this, wxID_ANY), 1, wxGROW);
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
pbutton_s->AddStretchSpacer();
pbutton_s->Add(tmp = new wxButton(this, wxID_ANY, wxT("Add")), 0, wxGROW);
tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_bindings::on_add), NULL,
this);
pbutton_s->Add(tmp = new wxButton(this, wxID_ANY, wxT("Edit")), 0, wxGROW);
tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_bindings::on_edit), NULL,
this);
pbutton_s->Add(tmp = new wxButton(this, wxID_ANY, wxT("Delete")), 0, wxGROW);
tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_bindings::on_delete), NULL,
this);
top_s->Add(pbutton_s, 0, wxGROW);
refresh();
top_s->SetSizeHints(this);
Fit();
}
wxeditor_esettings_bindings::~wxeditor_esettings_bindings()
{
}
void wxeditor_esettings_bindings::on_add(wxCommandEvent& e)
{
try {
std::string name;
wxdialog_keyentry* d = new wxdialog_keyentry(this, "Specify new key", "", false);
if(d->ShowModal() == wxID_CANCEL) {
d->Destroy();
throw 42;
}
name = d->getkey();
d->Destroy();
std::string newcommand = pick_text(this, "New binding", "Enter command for binding:", "");
bool fault = false;
std::string faulttext;
runemufn([&fault, &faulttext, name, newcommand]() {
try {
keymapper::bind_for(name, newcommand);
} catch(std::exception& e) {
fault = true;
faulttext = e.what();
}
});
if(fault)
wxMessageBox(wxT("Error"), towxstring("Can't bind key: " + faulttext), wxICON_EXCLAMATION);
refresh();
} catch(...) {
refresh();
}
}
void wxeditor_esettings_bindings::on_edit(wxCommandEvent& e)
{
std::string name = selected();
if(name == "") {
refresh();
return;
}
try {
std::string old_command_value;
runemufn([&old_command_value, name]() { old_command_value = keymapper::get_command_for(name); });
std::string newcommand = pick_text(this, "Edit binding", "Enter new command for binding:",
old_command_value);
bool fault = false;
std::string faulttext;
runemufn([&fault, &faulttext, name, newcommand]() {
try {
keymapper::bind_for(name, newcommand);
} catch(std::exception& e) {
fault = true;
faulttext = e.what();
}
});
if(fault)
wxMessageBox(wxT("Error"), towxstring("Can't bind key: " + faulttext), wxICON_EXCLAMATION);
refresh();
} catch(...) {
refresh();
}
}
void wxeditor_esettings_bindings::on_delete(wxCommandEvent& e)
{
std::string name = selected();
if(name == "") {
refresh();
return;
}
runemufn([name]() { try { keymapper::bind_for(name, ""); } catch(...) {} });
refresh();
}
void wxeditor_esettings_bindings::refresh()
{
int n = select->GetSelection();
std::map<std::string, std::string> bind;
std::vector<wxString> choices;
runemufn([&bind]() {
std::set<std::string> a = keymapper::get_bindings();
for(auto i : a)
bind[i] = keymapper::get_command_for(i);
});
for(auto i : bind) {
numbers[choices.size()] = i.first;
choices.push_back(towxstring(i.first + " (" + i.second + ")"));
}
select->Set(choices.size(), &choices[0]);
if(n == wxNOT_FOUND && select->GetCount())
select->SetSelection(0);
else if(n >= select->GetCount())
select->SetSelection(select->GetCount() ? (select->GetCount() - 1) : wxNOT_FOUND);
else
select->SetSelection(n);
}
std::string wxeditor_esettings_bindings::selected()
{
int x = select->GetSelection();
if(numbers.count(x))
return numbers[x];
else
return "";
}
class wxeditor_esettings_advanced : public wxPanel, information_dispatch class wxeditor_esettings_advanced : public wxPanel, information_dispatch
{ {
public: public:
@ -692,6 +1412,9 @@ wxeditor_esettings::wxeditor_esettings(wxWindow* parent)
tabset->AddPage(new wxeditor_esettings_joystick(tabset), wxT("Joysticks")); tabset->AddPage(new wxeditor_esettings_joystick(tabset), wxT("Joysticks"));
tabset->AddPage(new wxeditor_esettings_paths(tabset), wxT("Paths")); tabset->AddPage(new wxeditor_esettings_paths(tabset), wxT("Paths"));
tabset->AddPage(new wxeditor_esettings_screen(tabset), wxT("Scaling")); tabset->AddPage(new wxeditor_esettings_screen(tabset), wxT("Scaling"));
tabset->AddPage(new wxeditor_esettings_hotkeys(tabset), wxT("Hotkeys"));
tabset->AddPage(new wxeditor_esettings_aliases(tabset), wxT("Aliases"));
tabset->AddPage(new wxeditor_esettings_bindings(tabset), wxT("Bindings"));
tabset->AddPage(new wxeditor_esettings_advanced(tabset), wxT("Advanced")); tabset->AddPage(new wxeditor_esettings_advanced(tabset), wxT("Advanced"));
top_s->Add(tabset, 1, wxGROW); top_s->Add(tabset, 1, wxGROW);