[dialogs] Move JoypadConfig to its own class.
This commit is contained in:
parent
5f421b53c0
commit
14a4b6f820
|
@ -773,6 +773,7 @@ set(
|
|||
dialogs/game-boy-config.cpp
|
||||
dialogs/game-maker.cpp
|
||||
dialogs/gb-rom-info.cpp
|
||||
dialogs/joypad-config.cpp
|
||||
widgets/group-check-box.cpp
|
||||
widgets/keep-on-top-styler.cpp
|
||||
widgets/option-validator.cpp
|
||||
|
@ -826,6 +827,7 @@ set(
|
|||
dialogs/game-boy-config.h
|
||||
dialogs/game-maker.h
|
||||
dialogs/gb-rom-info.h
|
||||
dialogs/joypad-config.h
|
||||
dialogs/validated-child.h
|
||||
widgets/dpi-support.h
|
||||
widgets/group-check-box.h
|
||||
|
|
|
@ -2227,18 +2227,22 @@ EVT_HANDLER(EmulatorDirectories, "Directories...")
|
|||
|
||||
EVT_HANDLER(JoypadConfigure, "Joypad options...")
|
||||
{
|
||||
wxDialog* dlg = GetXRCDialog("JoypadConfig");
|
||||
joy.PollAllJoysticks();
|
||||
|
||||
auto frame = wxGetApp().frame;
|
||||
bool joy_timer = frame->IsJoyPollTimerRunning();
|
||||
|
||||
if (!joy_timer) frame->StartJoyPollTimer();
|
||||
if (!joy_timer) {
|
||||
frame->StartJoyPollTimer();
|
||||
}
|
||||
|
||||
if (ShowModal(dlg) == wxID_OK)
|
||||
update_opts();
|
||||
if (ShowModal(GetXRCDialog("JoypadConfig")) == wxID_OK) {
|
||||
update_joypad_opts();
|
||||
}
|
||||
|
||||
if (!joy_timer) frame->StopJoyPollTimer();
|
||||
if (!joy_timer) {
|
||||
frame->StopJoyPollTimer();
|
||||
}
|
||||
|
||||
SetJoystick();
|
||||
}
|
||||
|
|
|
@ -209,6 +209,9 @@ std::array<Option, kNbOptions>& Option::All() {
|
|||
bool statusbar = false;
|
||||
uint32_t ini_version = kIniLatestVersion;
|
||||
|
||||
/// Joypad
|
||||
uint32_t default_stick = 1;
|
||||
|
||||
/// Geometry
|
||||
bool fullscreen = false;
|
||||
bool window_maximized = false;
|
||||
|
@ -289,7 +292,7 @@ std::array<Option, kNbOptions>& Option::All() {
|
|||
/// Joypad
|
||||
Option(OptionID::kJoy),
|
||||
Option(OptionID::kJoyAutofireThrottle, &gopts.autofire_rate, 1, 1000),
|
||||
Option(OptionID::kJoyDefault, &gopts.default_stick, 1, 4),
|
||||
Option(OptionID::kJoyDefault, &g_owned_opts.default_stick, 1, 4),
|
||||
|
||||
/// Keyboard
|
||||
Option(OptionID::kKeyboard),
|
||||
|
|
|
@ -64,7 +64,7 @@ static constexpr std::array<Option::Type, kNbOptions> kOptionsTypes = {
|
|||
/// Joypad
|
||||
/*kJoy*/ Option::Type::kNone,
|
||||
/*kJoyAutofireThrottle*/ Option::Type::kInt,
|
||||
/*kJoyDefault*/ Option::Type::kInt,
|
||||
/*kJoyDefault*/ Option::Type::kUnsigned,
|
||||
|
||||
/// Keyboard
|
||||
/*kKeyboard*/ Option::Type::kNone,
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#include "dialogs/joypad-config.h"
|
||||
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
||||
#include "dialogs/validated-child.h"
|
||||
#include "opts.h"
|
||||
#include "widgets/option-validator.h"
|
||||
#include "widgets/user-input-ctrl.h"
|
||||
|
||||
namespace dialogs {
|
||||
|
||||
// static
|
||||
JoypadConfig* JoypadConfig::NewInstance(wxWindow* parent) {
|
||||
assert(parent);
|
||||
return new JoypadConfig(parent);
|
||||
}
|
||||
|
||||
JoypadConfig::JoypadConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(this) {
|
||||
#if !wxCHECK_VERSION(3, 1, 0)
|
||||
// This needs to be set before loading any element on the window. This also
|
||||
// has no effect since wx 3.1.0, where it became the default.
|
||||
this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
|
||||
#endif
|
||||
wxXmlResource::Get()->LoadDialog(this, parent, "JoypadConfig");
|
||||
|
||||
for (int joypad = 0; joypad < 4; joypad++) {
|
||||
wxWindow* panel = GetValidatedChild(this, wxString::Format("joy%d", joypad + 1));
|
||||
|
||||
GetValidatedChild(panel, "DefaultConfig")
|
||||
->SetValidator(
|
||||
widgets::OptionSelectedValidator(config::OptionID::kJoyDefault, joypad + 1));
|
||||
|
||||
// Set up tab order so input is easy to configure. Note that there are
|
||||
// two tabs for each panel, so we must check for the parent before
|
||||
// setting up the tab order.
|
||||
wxWindow* prev = nullptr;
|
||||
wxWindow* prev_parent = nullptr;
|
||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||
const wxString game_key_name = config::GameKeyToString(game_key);
|
||||
widgets::UserInputCtrl* game_key_control =
|
||||
GetValidatedChild<widgets::UserInputCtrl>(panel, game_key_name);
|
||||
wxWindow* current_parent = game_key_control->GetParent();
|
||||
|
||||
game_key_control->SetValidator(
|
||||
widgets::UserInputCtrlValidator(config::GameControl(joypad, game_key)));
|
||||
|
||||
if (current_parent == prev_parent) {
|
||||
// The first control will be skipped here, but that's fine since
|
||||
// we don't care where it fits in the tab order.
|
||||
assert(prev);
|
||||
game_key_control->MoveAfterInTabOrder(prev);
|
||||
}
|
||||
prev = game_key_control;
|
||||
prev_parent = current_parent;
|
||||
|
||||
// Bind the individual "Clear" key event.
|
||||
panel->Bind(wxEVT_BUTTON, std::bind(&widgets::UserInputCtrl::Clear, game_key_control),
|
||||
XRCID(wxString("Clear" + config::GameKeyToString(game_key)).c_str()));
|
||||
}
|
||||
|
||||
// Finally, bind the per-joypad "Defaults" and "Clear" events.
|
||||
panel->Bind(wxEVT_BUTTON, std::bind(&JoypadConfig::ResetToDefaults, this, panel),
|
||||
XRCID("Defaults"));
|
||||
panel->Bind(wxEVT_BUTTON, std::bind(&JoypadConfig::ClearJoypad, this, panel),
|
||||
XRCID("Clear"));
|
||||
}
|
||||
|
||||
this->Fit();
|
||||
}
|
||||
|
||||
void JoypadConfig::ResetToDefaults(wxWindow* panel) {
|
||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||
GetValidatedChild<widgets::UserInputCtrl>(panel, config::GameKeyToString(game_key))
|
||||
->SetInputs(kDefaultBindings.find(config::GameControl(0, game_key))->second);
|
||||
}
|
||||
}
|
||||
|
||||
void JoypadConfig::ClearJoypad(wxWindow* panel) {
|
||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||
GetValidatedChild<widgets::UserInputCtrl>(panel, config::GameKeyToString(game_key))
|
||||
->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_
|
||||
#define VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_
|
||||
|
||||
#include <wx/dialog.h>
|
||||
|
||||
#include "widgets/keep-on-top-styler.h"
|
||||
|
||||
namespace dialogs {
|
||||
|
||||
// Manages the Joypad configuration dialog.
|
||||
class JoypadConfig : public wxDialog {
|
||||
public:
|
||||
static JoypadConfig* NewInstance(wxWindow* parent);
|
||||
~JoypadConfig() override = default;
|
||||
|
||||
private:
|
||||
// The constructor is private so initialization has to be done via the
|
||||
// static method. This is because this class is destroyed when its
|
||||
// owner, `parent` is destroyed. This prevents accidental deletion.
|
||||
JoypadConfig(wxWindow* parent);
|
||||
|
||||
// Resets all Joypad controls for `panel` to defaults.
|
||||
void ResetToDefaults(wxWindow* panel);
|
||||
|
||||
// Clears all Joypad controls.
|
||||
void ClearJoypad(wxWindow* panel);
|
||||
|
||||
const widgets::KeepOnTopStyler keep_on_top_styler_;
|
||||
};
|
||||
|
||||
} // namespace dialogs
|
||||
|
||||
#endif // VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_
|
|
@ -43,6 +43,7 @@
|
|||
#include "dialogs/display-config.h"
|
||||
#include "dialogs/game-boy-config.h"
|
||||
#include "dialogs/gb-rom-info.h"
|
||||
#include "dialogs/joypad-config.h"
|
||||
#include "opts.h"
|
||||
#include "widgets/option-validator.h"
|
||||
#include "widgets/user-input-ctrl.h"
|
||||
|
@ -1604,40 +1605,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// manage the joypad prefs' per-panel default/clear buttons
|
||||
static class JoyPadConfig_t : public wxEvtHandler {
|
||||
public:
|
||||
wxWindow* p;
|
||||
void JoypadConfigButtons(wxCommandEvent& ev)
|
||||
{
|
||||
bool clear = ev.GetId() == XRCID("Clear");
|
||||
|
||||
// For the individual clear buttons, we assume their name is
|
||||
// "Clear" + control_name
|
||||
// ClearUp for Up; ClearR for R etc
|
||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||
const wxString control_name = config::GameKeyToString(game_key);
|
||||
widgets::UserInputCtrl* tc = XRCCTRL_D(*p, control_name, widgets::UserInputCtrl);
|
||||
wxString singleClearButton("Clear" + control_name);
|
||||
if (ev.GetId() == XRCID(singleClearButton.c_str())) {
|
||||
tc->Clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||
widgets::UserInputCtrl* tc =
|
||||
XRCCTRL_D(*p, config::GameKeyToString(game_key), widgets::UserInputCtrl);
|
||||
|
||||
if (clear) {
|
||||
tc->Clear();
|
||||
} else {
|
||||
tc->SetInputs(kDefaultBindings.find(config::GameControl(0, game_key))->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
} JoyPadConfigHandler[4];
|
||||
|
||||
// manage throttle spinctrl/canned setting choice interaction
|
||||
static class ThrottleCtrl_t : public wxEvtHandler {
|
||||
public:
|
||||
|
@ -2775,54 +2742,7 @@ bool MainFrame::BindControls()
|
|||
d->Fit();
|
||||
}
|
||||
dialogs::DirectoriesConfig::NewInstance(this);
|
||||
wxDialog* joyDialog = LoadXRCropertySheetDialog("JoypadConfig");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wxString pn;
|
||||
// NOTE: wx2.9.1 behaves differently for referenced nodes
|
||||
// than 2.8! Unless there is an actual child node, the ID field
|
||||
// will not be overwritten. This means that there should be a
|
||||
// dummy child node (e.g. position=(0,0)). If you get
|
||||
// "Unable to load dialog JoypadConfig from resources", this is
|
||||
// probably the reason.
|
||||
pn.Printf(wxT("joy%d"), i + 1);
|
||||
wxWindow* w = SafeXRCCTRL<wxWindow>(joyDialog, pn);
|
||||
|
||||
w->FindWindow("DefaultConfig")
|
||||
->SetValidator(wxBoolIntValidator(&gopts.default_stick, i + 1));
|
||||
wxWindow *prev = NULL, *prevp = NULL;
|
||||
|
||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||
const wxString control_name = config::GameKeyToString(game_key);
|
||||
widgets::UserInputCtrl* tc = XRCCTRL_D(*w, control_name, widgets::UserInputCtrl);
|
||||
CheckThrowXRCError(tc, control_name);
|
||||
wxWindow* p = tc->GetParent();
|
||||
|
||||
if (p == prevp)
|
||||
tc->MoveAfterInTabOrder(prev);
|
||||
|
||||
prev = tc;
|
||||
prevp = p;
|
||||
tc->SetValidator(widgets::UserInputCtrlValidator(config::GameControl(i, game_key)));
|
||||
}
|
||||
|
||||
JoyPadConfigHandler[i].p = w;
|
||||
w->Connect(XRCID("Defaults"), wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons),
|
||||
NULL, &JoyPadConfigHandler[i]);
|
||||
w->Connect(XRCID("Clear"), wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons),
|
||||
NULL, &JoyPadConfigHandler[i]);
|
||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||
const wxString control_name = config::GameKeyToString(game_key);
|
||||
w->Connect(XRCID(wxString("Clear" + control_name).c_str()),
|
||||
wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons),
|
||||
NULL, &JoyPadConfigHandler[i]);
|
||||
}
|
||||
|
||||
joyDialog->Fit();
|
||||
}
|
||||
dialogs::JoypadConfig::NewInstance(this);
|
||||
|
||||
#ifndef NO_LINK
|
||||
d = LoadXRCDialog("LinkConfig");
|
||||
|
|
|
@ -531,11 +531,13 @@ void load_opts(bool first_time_launch) {
|
|||
|
||||
// Note: run load_opts() first to guarantee all config opts exist
|
||||
void update_opts() {
|
||||
wxConfigBase* cfg = wxConfigBase::Get();
|
||||
|
||||
for (config::Option& opt : config::Option::All()) {
|
||||
SaveOption(&opt);
|
||||
}
|
||||
}
|
||||
|
||||
void update_joypad_opts() {
|
||||
wxConfigBase* cfg = wxConfigBase::Get();
|
||||
|
||||
// For joypad, compare the UserInput sets. Since UserInput guarantees a
|
||||
// certain ordering, it is possible that the user control in the panel shows
|
||||
|
@ -551,6 +553,7 @@ void update_opts() {
|
|||
cfg->Write(option_name, config::UserInput::SpanToConfigString(iter.second));
|
||||
}
|
||||
}
|
||||
|
||||
if (game_bindings_changed) {
|
||||
config::GameControlState::Instance().OnGameBindingsChanged();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ extern struct opts_t {
|
|||
std::map<config::GameControl, std::set<config::UserInput>>
|
||||
game_control_bindings;
|
||||
int autofire_rate = 1;
|
||||
int default_stick = 1;
|
||||
|
||||
/// Keyboard
|
||||
config::Shortcuts shortcuts;
|
||||
|
@ -85,6 +84,8 @@ void load_opts(bool first_time_launch);
|
|||
// call whenever opt vars change
|
||||
// will detect changes and write config if necessary
|
||||
void update_opts();
|
||||
// Updates the joypad options.
|
||||
void update_joypad_opts();
|
||||
// Updates the shortcut options.
|
||||
void update_shortcut_opts();
|
||||
// returns true if option name correct; prints error if val invalid
|
||||
|
|
|
@ -334,7 +334,7 @@ bool systemReadJoypads()
|
|||
uint32_t systemReadJoypad(int joy)
|
||||
{
|
||||
if (joy < 0 || joy > 3)
|
||||
joy = gopts.default_stick - 1;
|
||||
joy = OPTION(kJoyDefault) - 1;
|
||||
|
||||
uint32_t ret = config::GameControlState::Instance().GetJoypad(joy);
|
||||
|
||||
|
@ -772,17 +772,17 @@ void systemUpdateMotionSensor()
|
|||
|
||||
int systemGetSensorX()
|
||||
{
|
||||
return sensorx[gopts.default_stick - 1];
|
||||
return sensorx[OPTION(kJoyDefault) - 1];
|
||||
}
|
||||
|
||||
int systemGetSensorY()
|
||||
{
|
||||
return sensory[gopts.default_stick - 1];
|
||||
return sensory[OPTION(kJoyDefault) - 1];
|
||||
}
|
||||
|
||||
int systemGetSensorZ()
|
||||
{
|
||||
return sensorz[gopts.default_stick - 1] / 10;
|
||||
return sensorz[OPTION(kJoyDefault) - 1] / 10;
|
||||
}
|
||||
|
||||
class PrintDialog : public wxEvtHandler, public wxPrintout {
|
||||
|
|
Loading…
Reference in New Issue