mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-03 13:31:18 +12:00
input: configurable controller hotkeys
This commit is contained in:
parent
71c9faaba8
commit
31ab6b8164
5 changed files with 172 additions and 7 deletions
|
@ -345,6 +345,7 @@ void CemuConfig::Load(XMLConfigParser& parser)
|
||||||
|
|
||||||
// hotkeys
|
// hotkeys
|
||||||
auto xml_hotkeys = parser.get("Hotkeys");
|
auto xml_hotkeys = parser.get("Hotkeys");
|
||||||
|
hotkeys.modifiers = xml_hotkeys.get("modifiers", sHotkeyCfg{});
|
||||||
hotkeys.exitFullscreen = xml_hotkeys.get("ExitFullscreen", sHotkeyCfg{uKeyboardHotkey{WXK_ESCAPE}});
|
hotkeys.exitFullscreen = xml_hotkeys.get("ExitFullscreen", sHotkeyCfg{uKeyboardHotkey{WXK_ESCAPE}});
|
||||||
hotkeys.toggleFullscreen = xml_hotkeys.get("ToggleFullscreen", sHotkeyCfg{uKeyboardHotkey{WXK_F11}});
|
hotkeys.toggleFullscreen = xml_hotkeys.get("ToggleFullscreen", sHotkeyCfg{uKeyboardHotkey{WXK_F11}});
|
||||||
hotkeys.toggleFullscreenAlt = xml_hotkeys.get("ToggleFullscreenAlt", sHotkeyCfg{uKeyboardHotkey{WXK_CONTROL_M, true}}); // ALT+ENTER
|
hotkeys.toggleFullscreenAlt = xml_hotkeys.get("ToggleFullscreenAlt", sHotkeyCfg{uKeyboardHotkey{WXK_CONTROL_M, true}}); // ALT+ENTER
|
||||||
|
@ -553,6 +554,7 @@ void CemuConfig::Save(XMLConfigParser& parser)
|
||||||
|
|
||||||
// hotkeys
|
// hotkeys
|
||||||
auto xml_hotkeys = config.set("Hotkeys");
|
auto xml_hotkeys = config.set("Hotkeys");
|
||||||
|
xml_hotkeys.set("modifiers", hotkeys.modifiers);
|
||||||
xml_hotkeys.set("ExitFullscreen", hotkeys.exitFullscreen);
|
xml_hotkeys.set("ExitFullscreen", hotkeys.exitFullscreen);
|
||||||
xml_hotkeys.set("ToggleFullscreen", hotkeys.toggleFullscreen);
|
xml_hotkeys.set("ToggleFullscreen", hotkeys.toggleFullscreen);
|
||||||
xml_hotkeys.set("ToggleFullscreenAlt", hotkeys.toggleFullscreenAlt);
|
xml_hotkeys.set("ToggleFullscreenAlt", hotkeys.toggleFullscreenAlt);
|
||||||
|
|
|
@ -208,18 +208,20 @@ typedef sint16 ControllerHotkey_t;
|
||||||
struct sHotkeyCfg
|
struct sHotkeyCfg
|
||||||
{
|
{
|
||||||
static constexpr uint8 keyboardNone{WXK_NONE};
|
static constexpr uint8 keyboardNone{WXK_NONE};
|
||||||
|
static constexpr sint8 controllerNone{-1}; // no enums to work with, but buttons start from 0
|
||||||
|
|
||||||
uKeyboardHotkey keyboard{keyboardNone};
|
uKeyboardHotkey keyboard{keyboardNone};
|
||||||
|
ControllerHotkey_t controller{controllerNone};
|
||||||
|
|
||||||
/* for defaults */
|
/* for defaults */
|
||||||
sHotkeyCfg(const uKeyboardHotkey& keyboard = {WXK_NONE}) :
|
sHotkeyCfg(const uKeyboardHotkey& keyboard = {WXK_NONE}, const ControllerHotkey_t& controller = {-1}) :
|
||||||
keyboard(keyboard){};
|
keyboard(keyboard), controller(controller) {};
|
||||||
|
|
||||||
/* for reading from xml */
|
/* for reading from xml */
|
||||||
sHotkeyCfg(const char* xml_values)
|
sHotkeyCfg(const char* xml_values)
|
||||||
{
|
{
|
||||||
std::istringstream iss(xml_values);
|
std::istringstream iss(xml_values);
|
||||||
iss >> keyboard.raw;
|
iss >> keyboard.raw >> controller;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -228,7 +230,7 @@ struct fmt::formatter<sHotkeyCfg> : formatter<string_view>
|
||||||
{
|
{
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(const sHotkeyCfg c, FormatContext &ctx) const {
|
auto format(const sHotkeyCfg c, FormatContext &ctx) const {
|
||||||
std::string xml_values = fmt::format("{}", c.keyboard.raw);
|
std::string xml_values = fmt::format("{} {}", c.keyboard.raw, c.controller);
|
||||||
return formatter<string_view>::format(xml_values, ctx);
|
return formatter<string_view>::format(xml_values, ctx);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -544,6 +546,7 @@ struct CemuConfig
|
||||||
// hotkeys
|
// hotkeys
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
sHotkeyCfg modifiers;
|
||||||
sHotkeyCfg toggleFullscreen;
|
sHotkeyCfg toggleFullscreen;
|
||||||
sHotkeyCfg toggleFullscreenAlt;
|
sHotkeyCfg toggleFullscreenAlt;
|
||||||
sHotkeyCfg exitFullscreen;
|
sHotkeyCfg exitFullscreen;
|
||||||
|
|
|
@ -20,12 +20,14 @@ struct HotkeyEntry
|
||||||
{
|
{
|
||||||
std::unique_ptr<wxStaticText> name;
|
std::unique_ptr<wxStaticText> name;
|
||||||
std::unique_ptr<wxButton> keyInput;
|
std::unique_ptr<wxButton> keyInput;
|
||||||
|
std::unique_ptr<wxButton> controllerInput;
|
||||||
sHotkeyCfg& hotkey;
|
sHotkeyCfg& hotkey;
|
||||||
|
|
||||||
HotkeyEntry(wxStaticText* name, wxButton* keyInput, sHotkeyCfg& hotkey)
|
HotkeyEntry(wxStaticText* name, wxButton* keyInput, wxButton* controllerInput, sHotkeyCfg& hotkey)
|
||||||
: name(name), keyInput(keyInput), hotkey(hotkey)
|
: name(name), keyInput(keyInput), controllerInput(controllerInput), hotkey(hotkey)
|
||||||
{
|
{
|
||||||
keyInput->SetClientData(&hotkey);
|
keyInput->SetClientData(&hotkey);
|
||||||
|
controllerInput->SetClientData(&hotkey);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,8 +36,9 @@ HotkeySettings::HotkeySettings(wxWindow* parent)
|
||||||
{
|
{
|
||||||
SetIcon(wxICON(X_HOTKEY_SETTINGS));
|
SetIcon(wxICON(X_HOTKEY_SETTINGS));
|
||||||
|
|
||||||
m_sizer = new wxFlexGridSizer(0, 2, 5, 5);
|
m_sizer = new wxFlexGridSizer(0, 3, 5, 5);
|
||||||
m_sizer->AddGrowableCol(1);
|
m_sizer->AddGrowableCol(1);
|
||||||
|
m_sizer->AddGrowableCol(2);
|
||||||
|
|
||||||
m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE);
|
m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE);
|
||||||
m_panel->SetSizer(m_sizer);
|
m_panel->SetSizer(m_sizer);
|
||||||
|
@ -43,17 +46,27 @@ HotkeySettings::HotkeySettings(wxWindow* parent)
|
||||||
|
|
||||||
Center();
|
Center();
|
||||||
|
|
||||||
|
SetActiveController();
|
||||||
|
|
||||||
CreateColumnHeaders();
|
CreateColumnHeaders();
|
||||||
|
|
||||||
|
/* global modifier */
|
||||||
|
CreateHotkeyRow("Hotkey modifier", s_cfgHotkeys.modifiers);
|
||||||
|
m_hotkeys.at(0).keyInput->Hide();
|
||||||
|
|
||||||
/* hotkeys */
|
/* hotkeys */
|
||||||
CreateHotkeyRow("Toggle fullscreen", s_cfgHotkeys.toggleFullscreen);
|
CreateHotkeyRow("Toggle fullscreen", s_cfgHotkeys.toggleFullscreen);
|
||||||
CreateHotkeyRow("Take screenshot", s_cfgHotkeys.takeScreenshot);
|
CreateHotkeyRow("Take screenshot", s_cfgHotkeys.takeScreenshot);
|
||||||
|
|
||||||
|
m_controllerTimer = new wxTimer(this);
|
||||||
|
Bind(wxEVT_TIMER, &HotkeySettings::OnControllerTimer, this);
|
||||||
|
|
||||||
m_sizer->SetSizeHints(this);
|
m_sizer->SetSizeHints(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
HotkeySettings::~HotkeySettings()
|
HotkeySettings::~HotkeySettings()
|
||||||
{
|
{
|
||||||
|
m_controllerTimer->Stop();
|
||||||
if (m_needToSave)
|
if (m_needToSave)
|
||||||
{
|
{
|
||||||
g_config.Save();
|
g_config.Save();
|
||||||
|
@ -70,6 +83,11 @@ void HotkeySettings::Init(wxFrame* mainWindowFrame)
|
||||||
{
|
{
|
||||||
s_keyboardHotkeyToFuncMap[keyboardHotkey] = func;
|
s_keyboardHotkeyToFuncMap[keyboardHotkey] = func;
|
||||||
}
|
}
|
||||||
|
auto controllerHotkey = cfgHotkey->controller;
|
||||||
|
if (controllerHotkey > sHotkeyCfg::controllerNone)
|
||||||
|
{
|
||||||
|
s_controllerHotkeyToFuncMap[controllerHotkey] = func;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s_mainWindow = mainWindowFrame;
|
s_mainWindow = mainWindowFrame;
|
||||||
}
|
}
|
||||||
|
@ -78,26 +96,33 @@ void HotkeySettings::CreateColumnHeaders(void)
|
||||||
{
|
{
|
||||||
auto* emptySpace = new wxStaticText(m_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL);
|
auto* emptySpace = new wxStaticText(m_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL);
|
||||||
auto* keyboard = new wxStaticText(m_panel, wxID_ANY, "Keyboard", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL);
|
auto* keyboard = new wxStaticText(m_panel, wxID_ANY, "Keyboard", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL);
|
||||||
|
auto* controller = new wxStaticText(m_panel, wxID_ANY, "Controller", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL);
|
||||||
|
|
||||||
keyboard->SetMinSize(m_minButtonSize);
|
keyboard->SetMinSize(m_minButtonSize);
|
||||||
|
controller->SetMinSize(m_minButtonSize);
|
||||||
|
|
||||||
auto flags = wxSizerFlags().Expand();
|
auto flags = wxSizerFlags().Expand();
|
||||||
m_sizer->Add(emptySpace, flags);
|
m_sizer->Add(emptySpace, flags);
|
||||||
m_sizer->Add(keyboard, flags);
|
m_sizer->Add(keyboard, flags);
|
||||||
|
m_sizer->Add(controller, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HotkeySettings::CreateHotkeyRow(const wxString& label, sHotkeyCfg& cfgHotkey)
|
void HotkeySettings::CreateHotkeyRow(const wxString& label, sHotkeyCfg& cfgHotkey)
|
||||||
{
|
{
|
||||||
auto* name = new wxStaticText(m_panel, wxID_ANY, label);
|
auto* name = new wxStaticText(m_panel, wxID_ANY, label);
|
||||||
auto* keyInput = new wxButton(m_panel, wxID_ANY, To_wxString(cfgHotkey.keyboard), wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS | wxBU_EXACTFIT);
|
auto* keyInput = new wxButton(m_panel, wxID_ANY, To_wxString(cfgHotkey.keyboard), wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS | wxBU_EXACTFIT);
|
||||||
|
auto* controllerInput = new wxButton(m_panel, wxID_ANY, To_wxString(cfgHotkey.controller), wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS | wxBU_EXACTFIT);
|
||||||
|
|
||||||
/* for starting input */
|
/* for starting input */
|
||||||
keyInput->Bind(wxEVT_BUTTON, &HotkeySettings::OnKeyboardHotkeyInputLeftClick, this);
|
keyInput->Bind(wxEVT_BUTTON, &HotkeySettings::OnKeyboardHotkeyInputLeftClick, this);
|
||||||
|
controllerInput->Bind(wxEVT_BUTTON, &HotkeySettings::OnControllerHotkeyInputLeftClick, this);
|
||||||
|
|
||||||
/* for cancelling and clearing input */
|
/* for cancelling and clearing input */
|
||||||
keyInput->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(HotkeySettings::OnKeyboardHotkeyInputRightClick), NULL, this);
|
keyInput->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(HotkeySettings::OnKeyboardHotkeyInputRightClick), NULL, this);
|
||||||
|
controllerInput->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(HotkeySettings::OnControllerHotkeyInputRightClick), NULL, this);
|
||||||
|
|
||||||
keyInput->SetMinSize(m_minButtonSize);
|
keyInput->SetMinSize(m_minButtonSize);
|
||||||
|
controllerInput->SetMinSize(m_minButtonSize);
|
||||||
|
|
||||||
#if BOOST_OS_WINDOWS
|
#if BOOST_OS_WINDOWS
|
||||||
const wxColour inputButtonColor = 0xfafafa;
|
const wxColour inputButtonColor = 0xfafafa;
|
||||||
|
@ -105,14 +130,53 @@ void HotkeySettings::CreateHotkeyRow(const wxString& label, sHotkeyCfg& cfgHotke
|
||||||
const wxColour inputButtonColor = GetBackgroundColour();
|
const wxColour inputButtonColor = GetBackgroundColour();
|
||||||
#endif
|
#endif
|
||||||
keyInput->SetBackgroundColour(inputButtonColor);
|
keyInput->SetBackgroundColour(inputButtonColor);
|
||||||
|
controllerInput->SetBackgroundColour(inputButtonColor);
|
||||||
|
|
||||||
auto flags = wxSizerFlags(1).Expand().Border(wxALL, 5).CenterVertical();
|
auto flags = wxSizerFlags(1).Expand().Border(wxALL, 5).CenterVertical();
|
||||||
m_sizer->Add(name, flags);
|
m_sizer->Add(name, flags);
|
||||||
m_sizer->Add(keyInput, flags);
|
m_sizer->Add(keyInput, flags);
|
||||||
|
m_sizer->Add(controllerInput, flags);
|
||||||
|
|
||||||
m_hotkeys.emplace_back(name, keyInput, controllerInput, cfgHotkey);
|
m_hotkeys.emplace_back(name, keyInput, controllerInput, cfgHotkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HotkeySettings::OnControllerTimer(wxTimerEvent& event)
|
||||||
|
{
|
||||||
|
if (m_activeController.expired())
|
||||||
|
{
|
||||||
|
m_controllerTimer->Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& controller = *m_activeController.lock();
|
||||||
|
auto buttons = controller.update_state().buttons;
|
||||||
|
if (!buttons.IsIdle())
|
||||||
|
{
|
||||||
|
for (const auto& newHotkey : buttons.GetButtonList())
|
||||||
|
{
|
||||||
|
m_controllerTimer->Stop();
|
||||||
|
auto* inputButton = static_cast<wxButton*>(m_controllerTimer->GetClientData());
|
||||||
|
auto& cfgHotkey = *static_cast<sHotkeyCfg*>(inputButton->GetClientData());
|
||||||
|
const auto oldHotkey = cfgHotkey.controller;
|
||||||
|
const bool isModifier = (&cfgHotkey == &s_cfgHotkeys.modifiers);
|
||||||
|
/* ignore same hotkeys and block duplicate hotkeys */
|
||||||
|
if ((newHotkey != oldHotkey) && (isModifier || (newHotkey != s_cfgHotkeys.modifiers.controller)) &&
|
||||||
|
(s_controllerHotkeyToFuncMap.find(newHotkey) == s_controllerHotkeyToFuncMap.end()))
|
||||||
|
{
|
||||||
|
m_needToSave |= true;
|
||||||
|
cfgHotkey.controller = newHotkey;
|
||||||
|
/* don't bind modifier to map */
|
||||||
|
if (!isModifier)
|
||||||
|
{
|
||||||
|
s_controllerHotkeyToFuncMap.erase(oldHotkey);
|
||||||
|
s_controllerHotkeyToFuncMap[newHotkey] = s_cfgHotkeyToFuncMap.at(&cfgHotkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FinalizeInput<ControllerHotkey_t>(inputButton);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HotkeySettings::OnKeyboardHotkeyInputLeftClick(wxCommandEvent& event)
|
void HotkeySettings::OnKeyboardHotkeyInputLeftClick(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
auto* inputButton = static_cast<wxButton*>(event.GetEventObject());
|
auto* inputButton = static_cast<wxButton*>(event.GetEventObject());
|
||||||
|
@ -127,6 +191,26 @@ void HotkeySettings::OnKeyboardHotkeyInputLeftClick(wxCommandEvent& event)
|
||||||
m_activeInputButton = inputButton;
|
m_activeInputButton = inputButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HotkeySettings::OnControllerHotkeyInputLeftClick(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
auto* inputButton = static_cast<wxButton*>(event.GetEventObject());
|
||||||
|
if (m_activeInputButton)
|
||||||
|
{
|
||||||
|
/* ignore multiple clicks of the same button */
|
||||||
|
if (inputButton == m_activeInputButton) return;
|
||||||
|
RestoreInputButton<ControllerHotkey_t>();
|
||||||
|
}
|
||||||
|
m_controllerTimer->Stop();
|
||||||
|
if (!SetActiveController())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
inputButton->SetLabelText(m_editModeHotkeyText);
|
||||||
|
m_controllerTimer->SetClientData(inputButton);
|
||||||
|
m_controllerTimer->Start(25);
|
||||||
|
m_activeInputButton = inputButton;
|
||||||
|
}
|
||||||
|
|
||||||
void HotkeySettings::OnKeyboardHotkeyInputRightClick(wxMouseEvent& event)
|
void HotkeySettings::OnKeyboardHotkeyInputRightClick(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
if (m_activeInputButton)
|
if (m_activeInputButton)
|
||||||
|
@ -146,6 +230,41 @@ void HotkeySettings::OnKeyboardHotkeyInputRightClick(wxMouseEvent& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HotkeySettings::OnControllerHotkeyInputRightClick(wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
if (m_activeInputButton)
|
||||||
|
{
|
||||||
|
RestoreInputButton<ControllerHotkey_t>();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto* inputButton = static_cast<wxButton*>(event.GetEventObject());
|
||||||
|
auto& cfgHotkey = *static_cast<sHotkeyCfg*>(inputButton->GetClientData());
|
||||||
|
ControllerHotkey_t newHotkey{ sHotkeyCfg::controllerNone };
|
||||||
|
if (cfgHotkey.controller != newHotkey)
|
||||||
|
{
|
||||||
|
m_needToSave |= true;
|
||||||
|
s_controllerHotkeyToFuncMap.erase(cfgHotkey.controller);
|
||||||
|
cfgHotkey.controller = newHotkey;
|
||||||
|
FinalizeInput<ControllerHotkey_t>(inputButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HotkeySettings::SetActiveController(void)
|
||||||
|
{
|
||||||
|
auto emulatedController = InputManager::instance().get_controller(0);
|
||||||
|
if (emulatedController.use_count() <= 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto& controllers = emulatedController->get_controllers();
|
||||||
|
if (controllers.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_activeController = controllers.at(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void HotkeySettings::OnKeyUp(wxKeyEvent& event)
|
void HotkeySettings::OnKeyUp(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
auto* inputButton = static_cast<wxButton*>(event.GetEventObject());
|
auto* inputButton = static_cast<wxButton*>(event.GetEventObject());
|
||||||
|
@ -178,6 +297,9 @@ void HotkeySettings::FinalizeInput(wxButton* inputButton)
|
||||||
{
|
{
|
||||||
inputButton->Unbind(wxEVT_KEY_UP, &HotkeySettings::OnKeyUp, this);
|
inputButton->Unbind(wxEVT_KEY_UP, &HotkeySettings::OnKeyUp, this);
|
||||||
inputButton->SetLabelText(To_wxString(cfgHotkey.keyboard));
|
inputButton->SetLabelText(To_wxString(cfgHotkey.keyboard));
|
||||||
|
} else if constexpr (std::is_same_v<T, ControllerHotkey_t>)
|
||||||
|
{
|
||||||
|
inputButton->SetLabelText(To_wxString(cfgHotkey.controller));
|
||||||
}
|
}
|
||||||
m_activeInputButton = nullptr;
|
m_activeInputButton = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -225,6 +347,14 @@ wxString HotkeySettings::To_wxString(uKeyboardHotkey hotkey)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString HotkeySettings::To_wxString(ControllerHotkey_t hotkey)
|
||||||
|
{
|
||||||
|
if ((hotkey == sHotkeyCfg::controllerNone) || m_activeController.expired()) {
|
||||||
|
return m_disabledHotkeyText;
|
||||||
|
}
|
||||||
|
return m_activeController.lock()->get_button_name(hotkey);
|
||||||
|
}
|
||||||
|
|
||||||
void HotkeySettings::CaptureInput(wxKeyEvent& event)
|
void HotkeySettings::CaptureInput(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
uKeyboardHotkey hotkey{};
|
uKeyboardHotkey hotkey{};
|
||||||
|
@ -236,3 +366,22 @@ void HotkeySettings::CaptureInput(wxKeyEvent& event)
|
||||||
if (it != s_keyboardHotkeyToFuncMap.end())
|
if (it != s_keyboardHotkeyToFuncMap.end())
|
||||||
it->second();
|
it->second();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HotkeySettings::CaptureInput(const ControllerState& currentState, const ControllerState& lastState)
|
||||||
|
{
|
||||||
|
const auto& modifier = s_cfgHotkeys.modifiers.controller;
|
||||||
|
if ((modifier >= 0) && currentState.buttons.GetButtonState(modifier))
|
||||||
|
{
|
||||||
|
for (const auto& buttonId : currentState.buttons.GetButtonList())
|
||||||
|
{
|
||||||
|
const auto it = s_controllerHotkeyToFuncMap.find(buttonId);
|
||||||
|
if (it == s_controllerHotkeyToFuncMap.end())
|
||||||
|
continue;
|
||||||
|
/* only capture clicks */
|
||||||
|
if (lastState.buttons.GetButtonState(buttonId))
|
||||||
|
break;
|
||||||
|
it->second();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ public:
|
||||||
static void Init(wxFrame* mainWindowFrame);
|
static void Init(wxFrame* mainWindowFrame);
|
||||||
|
|
||||||
static void CaptureInput(wxKeyEvent& event);
|
static void CaptureInput(wxKeyEvent& event);
|
||||||
|
static void CaptureInput(const ControllerState& currentState, const ControllerState& lastState);
|
||||||
|
|
||||||
HotkeySettings(wxWindow* parent);
|
HotkeySettings(wxWindow* parent);
|
||||||
~HotkeySettings();
|
~HotkeySettings();
|
||||||
|
@ -20,23 +21,28 @@ private:
|
||||||
inline static wxFrame* s_mainWindow = nullptr;
|
inline static wxFrame* s_mainWindow = nullptr;
|
||||||
static const std::unordered_map<sHotkeyCfg*, std::function<void(void)>> s_cfgHotkeyToFuncMap;
|
static const std::unordered_map<sHotkeyCfg*, std::function<void(void)>> s_cfgHotkeyToFuncMap;
|
||||||
inline static std::unordered_map<uint16, std::function<void(void)>> s_keyboardHotkeyToFuncMap{};
|
inline static std::unordered_map<uint16, std::function<void(void)>> s_keyboardHotkeyToFuncMap{};
|
||||||
|
inline static std::unordered_map<uint16, std::function<void(void)>> s_controllerHotkeyToFuncMap{};
|
||||||
inline static auto& s_cfgHotkeys = GetConfig().hotkeys;
|
inline static auto& s_cfgHotkeys = GetConfig().hotkeys;
|
||||||
|
|
||||||
wxPanel* m_panel;
|
wxPanel* m_panel;
|
||||||
wxFlexGridSizer* m_sizer;
|
wxFlexGridSizer* m_sizer;
|
||||||
wxButton* m_activeInputButton{ nullptr };
|
wxButton* m_activeInputButton{ nullptr };
|
||||||
|
wxTimer* m_controllerTimer{ nullptr };
|
||||||
const wxSize m_minButtonSize{ 250, 45 };
|
const wxSize m_minButtonSize{ 250, 45 };
|
||||||
const wxString m_disabledHotkeyText{ _("----") };
|
const wxString m_disabledHotkeyText{ _("----") };
|
||||||
const wxString m_editModeHotkeyText{ _("") };
|
const wxString m_editModeHotkeyText{ _("") };
|
||||||
|
|
||||||
std::vector<HotkeyEntry> m_hotkeys;
|
std::vector<HotkeyEntry> m_hotkeys;
|
||||||
|
std::weak_ptr<ControllerBase> m_activeController{};
|
||||||
bool m_needToSave = false;
|
bool m_needToSave = false;
|
||||||
|
|
||||||
/* helpers */
|
/* helpers */
|
||||||
void CreateColumnHeaders(void);
|
void CreateColumnHeaders(void);
|
||||||
void CreateHotkeyRow(const wxString& label, sHotkeyCfg& cfgHotkey);
|
void CreateHotkeyRow(const wxString& label, sHotkeyCfg& cfgHotkey);
|
||||||
wxString To_wxString(uKeyboardHotkey hotkey);
|
wxString To_wxString(uKeyboardHotkey hotkey);
|
||||||
|
wxString To_wxString(ControllerHotkey_t hotkey);
|
||||||
bool IsValidKeycodeUp(int keycode);
|
bool IsValidKeycodeUp(int keycode);
|
||||||
|
bool SetActiveController(void);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void FinalizeInput(wxButton* inputButton);
|
void FinalizeInput(wxButton* inputButton);
|
||||||
|
@ -46,6 +52,9 @@ private:
|
||||||
|
|
||||||
/* events */
|
/* events */
|
||||||
void OnKeyboardHotkeyInputLeftClick(wxCommandEvent& event);
|
void OnKeyboardHotkeyInputLeftClick(wxCommandEvent& event);
|
||||||
|
void OnControllerHotkeyInputLeftClick(wxCommandEvent& event);
|
||||||
void OnKeyboardHotkeyInputRightClick(wxMouseEvent& event);
|
void OnKeyboardHotkeyInputRightClick(wxMouseEvent& event);
|
||||||
|
void OnControllerHotkeyInputRightClick(wxMouseEvent& event);
|
||||||
void OnKeyUp(wxKeyEvent& event);
|
void OnKeyUp(wxKeyEvent& event);
|
||||||
|
void OnControllerTimer(wxTimerEvent& event);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "input/api/Controller.h"
|
#include "input/api/Controller.h"
|
||||||
#include "config/CemuConfig.h"
|
#include "config/CemuConfig.h"
|
||||||
|
#include "gui/input/HotkeySettings.h"
|
||||||
|
|
||||||
#include "gui/guiWrapper.h"
|
#include "gui/guiWrapper.h"
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ const ControllerState& ControllerBase::update_state()
|
||||||
|
|
||||||
#undef APPLY_AXIS_BUTTON
|
#undef APPLY_AXIS_BUTTON
|
||||||
|
|
||||||
|
HotkeySettings::CaptureInput(result, m_last_state);
|
||||||
|
|
||||||
m_last_state = std::move(result);
|
m_last_state = std::move(result);
|
||||||
return m_last_state;
|
return m_last_state;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue