Add controller support to quick key menu

This commit is contained in:
Andrew Lanzone 2025-06-01 21:34:20 -07:00
parent 2aa9847b24
commit df237b5f9b
6 changed files with 122 additions and 12 deletions

View File

@ -58,6 +58,12 @@ namespace MWGui
unassign(&mKey[i]); unassign(&mKey[i]);
} }
if (Settings::gui().mControllerMenus)
{
mControllerButtons.a = "#{sSelect}";
mControllerButtons.b = "#{sOK}";
}
} }
void QuickKeysMenu::clear() void QuickKeysMenu::clear()
@ -109,6 +115,13 @@ namespace MWGui
{ {
validate(index); 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() 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) QuickKeysMenuAssign::QuickKeysMenuAssign(QuickKeysMenu* parent)
@ -485,9 +532,45 @@ namespace MWGui
mCancelButton->setCoord((maxWidth - mCancelButton->getTextSize().width - 24) / 2 + 8, mCancelButton->getTop(), mCancelButton->setCoord((maxWidth - mCancelButton->getTextSize().width - 24) / 2 + 8, mCancelButton->getTop(),
mCancelButton->getTextSize().width + 24, mCancelButton->getHeight()); mCancelButton->getTextSize().width + 24, mCancelButton->getHeight());
if (Settings::gui().mControllerMenus)
{
mDisableGamepadCursor = true;
mItemButton->setStateSelected(true);
mControllerButtons.a = "#{sSelect}";
mControllerButtons.b = "#{sCancel}";
}
center(); 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) void QuickKeysMenu::write(ESM::ESMWriter& writer)
{ {
writer.startRecord(ESM::REC_KEYS); writer.startRecord(ESM::REC_KEYS);
@ -597,6 +680,12 @@ namespace MWGui
mMagicList->setHighlightSelected(false); mMagicList->setHighlightSelected(false);
mMagicList->eventSpellClicked += MyGUI::newDelegate(this, &MagicSelectionDialog::onModelIndexSelected); mMagicList->eventSpellClicked += MyGUI::newDelegate(this, &MagicSelectionDialog::onModelIndexSelected);
if (Settings::gui().mControllerMenus)
{
mControllerButtons.a = "#{sSelect}";
mControllerButtons.b = "#{sCancel}";
}
center(); center();
} }
@ -628,4 +717,13 @@ namespace MWGui
mParent->onAssignMagic(spell.mId); 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;
}
} }

View File

@ -72,6 +72,9 @@ namespace MWGui
// Check if quick key is still valid // Check if quick key is still valid
inline void validate(int index); inline void validate(int index);
void unassign(keyData* key); void unassign(keyData* key);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
int mControllerFocus;
}; };
class QuickKeysMenuAssign : public WindowModal class QuickKeysMenuAssign : public WindowModal
@ -87,6 +90,9 @@ namespace MWGui
MyGUI::Button* mCancelButton; MyGUI::Button* mCancelButton;
QuickKeysMenu* mParent; QuickKeysMenu* mParent;
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
int mControllerFocus;
}; };
class MagicSelectionDialog : public WindowModal class MagicSelectionDialog : public WindowModal
@ -105,6 +111,9 @@ namespace MWGui
void onCancelButtonClicked(MyGUI::Widget* sender); void onCancelButtonClicked(MyGUI::Widget* sender);
void onModelIndexSelected(SpellModel::ModelIndex index); void onModelIndexSelected(SpellModel::ModelIndex index);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
int mControllerFocus;
}; };
} }

View File

@ -327,14 +327,14 @@ namespace MWGui
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
} }
void SpellView::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) void SpellView::onControllerButton(const unsigned char button)
{ {
if (mButtons.empty()) if (mButtons.empty())
return; return;
int prevFocus = mControllerFocus; int prevFocus = mControllerFocus;
if (arg.button == SDL_CONTROLLER_BUTTON_A) if (button == SDL_CONTROLLER_BUTTON_A)
{ {
// Select the focused item, if any. // Select the focused item, if any.
if (mControllerFocus >= 0 && mControllerFocus < mButtons.size()) if (mControllerFocus >= 0 && mControllerFocus < mButtons.size())
@ -343,22 +343,22 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->playSound(ESM::RefId::stringRefId("Menu Click")); 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 // Toggle info tooltip
mControllerTooltip = !mControllerTooltip; mControllerTooltip = !mControllerTooltip;
if (mControllerTooltip && mControllerFocus >= 0 && mControllerFocus < mButtons.size()) if (mControllerTooltip && mControllerFocus >= 0 && mControllerFocus < mButtons.size())
MWBase::Environment::get().getInputManager()->warpMouseToWidget(mButtons[mControllerFocus].first); 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--; mControllerFocus--;
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) else if (button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
mControllerFocus++; mControllerFocus++;
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) else if (button == SDL_CONTROLLER_BUTTON_DPAD_LEFT)
mControllerFocus = std::max(0, mControllerFocus - 10); 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); 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 // Jump to first item in previous group
int prevGroupIndex = 0; int prevGroupIndex = 0;
@ -371,7 +371,7 @@ namespace MWGui
} }
mControllerFocus = prevGroupIndex; mControllerFocus = prevGroupIndex;
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) else if (button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)
{ {
// Jump to first item in next group // Jump to first item in next group
for (int groupIndex : mGroupIndices) for (int groupIndex : mGroupIndices)

View File

@ -57,7 +57,7 @@ namespace MWGui
void resetScrollbars(); void resetScrollbars();
void onControllerButtonEvent(const SDL_ControllerButtonEvent& arg); void onControllerButton(const unsigned char button);
private: private:
MyGUI::ScrollView* mScrollView; MyGUI::ScrollView* mScrollView;

View File

@ -275,7 +275,7 @@ namespace MWGui
if (arg.button == SDL_CONTROLLER_BUTTON_B) if (arg.button == SDL_CONTROLLER_BUTTON_B)
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
else else
mSpellView->onControllerButtonEvent(arg); mSpellView->onControllerButton(arg.button);
return true; return true;
} }

View File

@ -192,7 +192,10 @@
<Property key="Alpha" value="0.5"/> <Property key="Alpha" value="0.5"/>
</Widget> </Widget>
</Widget> </Widget>
<Widget type="ImageBox" skin="ImageBox" position="4 4 42 42" align="Stretch" name="ControllerBorder">
<Property key="ImageTexture" value="textures\omw_menu_icon_active.dds"/>
<Property key="Visible" value="false"/>
</Widget>
<Widget type="Widget" skin="MW_Box_Overlay" position="0 0 50 50" align="Stretch"/> <Widget type="Widget" skin="MW_Box_Overlay" position="0 0 50 50" align="Stretch"/>
</Widget> </Widget>
</Resource> </Resource>