1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-10-22 17:26:36 +00:00

Add controller support to spell buying and training windows

This commit is contained in:
Andrew Lanzone 2025-05-25 23:14:13 -07:00
parent cd745c7df3
commit 71fd8b8840
4 changed files with 111 additions and 0 deletions

View file

@ -31,6 +31,13 @@ namespace MWGui
getWidget(mSpellsView, "SpellsView");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onCancelButtonClicked);
if (Settings::gui().mControllerMenus)
{
mDisableGamepadCursor = true;
mControllerButtons.a = "#{sBuy}";
mControllerButtons.b = "#{sBack}";
}
}
bool SpellBuyingWindow::sortSpells(const ESM::Spell* left, const ESM::Spell* right)
@ -70,6 +77,8 @@ namespace MWGui
toAdd->setUserString("SpellCost", std::to_string(spell.mData.mCost));
toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onSpellButtonClick);
mSpellsWidgetMap.insert(std::make_pair(toAdd, spell.mId));
if (price <= playerGold)
mSpellButtons.emplace_back(toAdd);
}
void SpellBuyingWindow::clearSpells()
@ -79,6 +88,7 @@ namespace MWGui
while (mSpellsView->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mSpellsView->getChildAt(0));
mSpellsWidgetMap.clear();
mSpellButtons.clear();
}
void SpellBuyingWindow::setPtr(const MWWorld::Ptr& actor)
@ -129,6 +139,13 @@ namespace MWGui
updateLabels();
if (Settings::gui().mControllerMenus)
{
mControllerFocus = 0;
if (mSpellButtons.size() > 0)
mSpellButtons[0]->setStateSelected(true);
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the
// scrollbar is hidden
mSpellsView->setVisibleVScroll(false);
@ -199,4 +216,42 @@ namespace MWGui
mSpellsView->setViewOffset(
MyGUI::IntPoint(0, static_cast<int>(mSpellsView->getViewOffset().top + _rel * 0.3f)));
}
bool SpellBuyingWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
onSpellButtonClick(mSpellButtons[mControllerFocus]);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onCancelButtonClicked(mCancelButton);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{
if (mSpellButtons.size() <= 1)
return true;
mSpellButtons[mControllerFocus]->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus - 1, mSpellButtons.size());
mSpellButtons[mControllerFocus]->setStateSelected(true);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{
if (mSpellButtons.size() <= 1)
return true;
mSpellButtons[mControllerFocus]->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus + 1, mSpellButtons.size());
mSpellButtons[mControllerFocus]->setStateSelected(true);
}
// Scroll the list to keep the active item in view
if (mControllerFocus <= 5)
mSpellsView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mSpellsView->setViewOffset(MyGUI::IntPoint(0, -10 * (mControllerFocus - 5)));
return true;
}
}

View file

@ -39,6 +39,7 @@ namespace MWGui
MyGUI::ScrollView* mSpellsView;
std::map<MyGUI::Widget*, ESM::RefId> mSpellsWidgetMap;
std::vector<MyGUI::Button*> mSpellButtons;
void onCancelButtonClicked(MyGUI::Widget* _sender);
void onSpellButtonClick(MyGUI::Widget* _sender);
@ -55,6 +56,8 @@ namespace MWGui
private:
static bool sortSpells(const ESM::Spell* left, const ESM::Spell* right);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
int mControllerFocus;
};
}

View file

@ -37,6 +37,13 @@ namespace MWGui
mTimeAdvancer.eventProgressChanged += MyGUI::newDelegate(this, &TrainingWindow::onTrainingProgressChanged);
mTimeAdvancer.eventFinished += MyGUI::newDelegate(this, &TrainingWindow::onTrainingFinished);
if (Settings::gui().mControllerMenus)
{
mDisableGamepadCursor = true;
mControllerButtons.a = "#{sBuy}";
mControllerButtons.b = "#{sBack}";
}
}
void TrainingWindow::onOpen()
@ -105,6 +112,7 @@ namespace MWGui
const int lineHeight = Settings::gui().mFontSize + 2;
mTrainingButtons.clear();
for (size_t i = 0; i < skills.size(); ++i)
{
const ESM::Skill* skill = skills[i].first;
@ -128,6 +136,16 @@ namespace MWGui
button->setSize(button->getTextSize().width + 12, button->getSize().height);
ToolTips::createSkillToolTip(button, skill->mId);
if (price <= playerGold)
mTrainingButtons.emplace_back(button);
}
if (Settings::gui().mControllerMenus)
{
mControllerFocus = 0;
if (mTrainingButtons.size() > 0)
mTrainingButtons[0]->setStateSelected(true);
}
center();
@ -229,4 +247,35 @@ namespace MWGui
return !mTimeAdvancer.isRunning();
}
bool TrainingWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
onTrainingSelected(mTrainingButtons[mControllerFocus]);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onCancelButtonClicked(mCancelButton);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{
if (mTrainingButtons.size() <= 1)
return true;
mTrainingButtons[mControllerFocus]->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus - 1, mTrainingButtons.size());
mTrainingButtons[mControllerFocus]->setStateSelected(true);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{
if (mTrainingButtons.size() <= 1)
return true;
mTrainingButtons[mControllerFocus]->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus + 1, mTrainingButtons.size());
mTrainingButtons[mControllerFocus]->setStateSelected(true);
}
return true;
}
}

View file

@ -49,9 +49,13 @@ namespace MWGui
MyGUI::Widget* mTrainingOptions;
MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPlayerGold;
std::vector<MyGUI::Button*> mTrainingButtons;
WaitDialogProgressBar mProgressBar;
TimeAdvancer mTimeAdvancer;
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
int mControllerFocus;
};
}