From df237b5f9b45db444df0084bded4b9f7e1f33714 Mon Sep 17 00:00:00 2001 From: Andrew Lanzone Date: Sun, 1 Jun 2025 21:34:20 -0700 Subject: [PATCH] Add controller support to quick key menu --- apps/openmw/mwgui/quickkeysmenu.cpp | 98 +++++++++++++++++++++++++++ apps/openmw/mwgui/quickkeysmenu.hpp | 9 +++ apps/openmw/mwgui/spellview.cpp | 18 ++--- apps/openmw/mwgui/spellview.hpp | 2 +- apps/openmw/mwgui/spellwindow.cpp | 2 +- files/data/mygui/openmw_resources.xml | 5 +- 6 files changed, 122 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index 93b0ef071f..daf49e1101 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -58,6 +58,12 @@ namespace MWGui unassign(&mKey[i]); } + + if (Settings::gui().mControllerMenus) + { + mControllerButtons.a = "#{sSelect}"; + mControllerButtons.b = "#{sOK}"; + } } void QuickKeysMenu::clear() @@ -109,6 +115,13 @@ namespace MWGui { validate(index); } + + if (Settings::gui().mControllerMenus) + { + mControllerFocus = 0; + for (int i = 0; i < mKey.size(); i++) + mKey[i].button->setControllerFocus(i == mControllerFocus); + } } void QuickKeysMenu::onClose() @@ -450,6 +463,40 @@ namespace MWGui } } + bool QuickKeysMenu::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) + { + if (arg.button == SDL_CONTROLLER_BUTTON_A) + onQuickKeyButtonClicked(mKey[mControllerFocus].button); + if (arg.button == SDL_CONTROLLER_BUTTON_B) + onOkButtonClicked(mOkButton); + else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP || + arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) + mControllerFocus = (mControllerFocus + 5) % 10; + else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) + { + if (mControllerFocus == 0) + mControllerFocus = 4; + else if (mControllerFocus == 5) + mControllerFocus = 9; + else + mControllerFocus--; + } + else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) + { + if (mControllerFocus == 4) + mControllerFocus = 0; + else if (mControllerFocus == 9) + mControllerFocus = 5; + else + mControllerFocus++; + } + + for (int i = 0; i < mKey.size(); i++) + mKey[i].button->setControllerFocus(i == mControllerFocus); + + return true; + } + // --------------------------------------------------------------------------------------------------------- QuickKeysMenuAssign::QuickKeysMenuAssign(QuickKeysMenu* parent) @@ -485,9 +532,45 @@ namespace MWGui mCancelButton->setCoord((maxWidth - mCancelButton->getTextSize().width - 24) / 2 + 8, mCancelButton->getTop(), mCancelButton->getTextSize().width + 24, mCancelButton->getHeight()); + if (Settings::gui().mControllerMenus) + { + mDisableGamepadCursor = true; + mItemButton->setStateSelected(true); + mControllerButtons.a = "#{sSelect}"; + mControllerButtons.b = "#{sCancel}"; + } + center(); } + bool QuickKeysMenuAssign::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) + { + if (arg.button == SDL_CONTROLLER_BUTTON_A) + { + if (mControllerFocus == 0) + mParent->onItemButtonClicked(mItemButton); + else if (mControllerFocus == 1) + mParent->onMagicButtonClicked(mMagicButton); + else if (mControllerFocus == 2) + mParent->onUnassignButtonClicked(mUnassignButton); + else if (mControllerFocus == 3) + mParent->onCancelButtonClicked(mCancelButton); + } + else if (arg.button == SDL_CONTROLLER_BUTTON_B) + mParent->onCancelButtonClicked(mCancelButton); + else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) + mControllerFocus = wrap(mControllerFocus - 1, 4); + else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) + mControllerFocus = wrap(mControllerFocus + 1, 4); + + mItemButton->setStateSelected(mControllerFocus == 0); + mMagicButton->setStateSelected(mControllerFocus == 1); + mUnassignButton->setStateSelected(mControllerFocus == 2); + mCancelButton->setStateSelected(mControllerFocus == 3); + + return true; + } + void QuickKeysMenu::write(ESM::ESMWriter& writer) { writer.startRecord(ESM::REC_KEYS); @@ -597,6 +680,12 @@ namespace MWGui mMagicList->setHighlightSelected(false); mMagicList->eventSpellClicked += MyGUI::newDelegate(this, &MagicSelectionDialog::onModelIndexSelected); + if (Settings::gui().mControllerMenus) + { + mControllerButtons.a = "#{sSelect}"; + mControllerButtons.b = "#{sCancel}"; + } + center(); } @@ -628,4 +717,13 @@ namespace MWGui mParent->onAssignMagic(spell.mId); } + bool MagicSelectionDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) + { + if (arg.button == SDL_CONTROLLER_BUTTON_B) + onCancelButtonClicked(mCancelButton); + else + mMagicList->onControllerButton(arg.button); + + return true; + } } diff --git a/apps/openmw/mwgui/quickkeysmenu.hpp b/apps/openmw/mwgui/quickkeysmenu.hpp index 904029b9a0..228eb926b4 100644 --- a/apps/openmw/mwgui/quickkeysmenu.hpp +++ b/apps/openmw/mwgui/quickkeysmenu.hpp @@ -72,6 +72,9 @@ namespace MWGui // Check if quick key is still valid inline void validate(int index); void unassign(keyData* key); + + bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; + int mControllerFocus; }; class QuickKeysMenuAssign : public WindowModal @@ -87,6 +90,9 @@ namespace MWGui MyGUI::Button* mCancelButton; QuickKeysMenu* mParent; + + bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; + int mControllerFocus; }; class MagicSelectionDialog : public WindowModal @@ -105,6 +111,9 @@ namespace MWGui void onCancelButtonClicked(MyGUI::Widget* sender); void onModelIndexSelected(SpellModel::ModelIndex index); + + bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; + int mControllerFocus; }; } diff --git a/apps/openmw/mwgui/spellview.cpp b/apps/openmw/mwgui/spellview.cpp index 6ef73c7794..e36a862730 100644 --- a/apps/openmw/mwgui/spellview.cpp +++ b/apps/openmw/mwgui/spellview.cpp @@ -327,14 +327,14 @@ namespace MWGui mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); } - void SpellView::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) + void SpellView::onControllerButton(const unsigned char button) { if (mButtons.empty()) return; int prevFocus = mControllerFocus; - if (arg.button == SDL_CONTROLLER_BUTTON_A) + if (button == SDL_CONTROLLER_BUTTON_A) { // Select the focused item, if any. if (mControllerFocus >= 0 && mControllerFocus < mButtons.size()) @@ -343,22 +343,22 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->playSound(ESM::RefId::stringRefId("Menu Click")); } } - else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK) + else if (button == SDL_CONTROLLER_BUTTON_RIGHTSTICK) { // Toggle info tooltip mControllerTooltip = !mControllerTooltip; if (mControllerTooltip && mControllerFocus >= 0 && mControllerFocus < mButtons.size()) MWBase::Environment::get().getInputManager()->warpMouseToWidget(mButtons[mControllerFocus].first); } - else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) + else if (button == SDL_CONTROLLER_BUTTON_DPAD_UP) mControllerFocus--; - else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) + else if (button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) mControllerFocus++; - else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) + else if (button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) mControllerFocus = std::max(0, mControllerFocus - 10); - else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) + else if (button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) mControllerFocus = std::min(mControllerFocus + 10, (int)mButtons.size() - 1); - else if (arg.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER) + else if (button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER) { // Jump to first item in previous group int prevGroupIndex = 0; @@ -371,7 +371,7 @@ namespace MWGui } mControllerFocus = prevGroupIndex; } - else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) + else if (button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) { // Jump to first item in next group for (int groupIndex : mGroupIndices) diff --git a/apps/openmw/mwgui/spellview.hpp b/apps/openmw/mwgui/spellview.hpp index 222d5f1ba3..5a22dcb4d9 100644 --- a/apps/openmw/mwgui/spellview.hpp +++ b/apps/openmw/mwgui/spellview.hpp @@ -57,7 +57,7 @@ namespace MWGui void resetScrollbars(); - void onControllerButtonEvent(const SDL_ControllerButtonEvent& arg); + void onControllerButton(const unsigned char button); private: MyGUI::ScrollView* mScrollView; diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 3eb041f6ab..b4c970c9bd 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -275,7 +275,7 @@ namespace MWGui if (arg.button == SDL_CONTROLLER_BUTTON_B) MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); else - mSpellView->onControllerButtonEvent(arg); + mSpellView->onControllerButton(arg.button); return true; } diff --git a/files/data/mygui/openmw_resources.xml b/files/data/mygui/openmw_resources.xml index d107c094e3..47fa71e984 100644 --- a/files/data/mygui/openmw_resources.xml +++ b/files/data/mygui/openmw_resources.xml @@ -192,7 +192,10 @@ - + + + +