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]);
}
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;
}
}

View File

@ -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;
};
}

View File

@ -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)

View File

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

View File

@ -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;
}

View File

@ -192,7 +192,10 @@
<Property key="Alpha" value="0.5"/>
</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>
</Resource>