1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2026-02-11 09:38:28 +00:00

Basic controller support for all character creation windows

This commit is contained in:
Andrew Lanzone 2025-05-12 01:34:28 -07:00
parent c4a87cfe4d
commit 83162477ec
9 changed files with 322 additions and 10 deletions

View file

@ -271,4 +271,35 @@ namespace MWGui
mSpellArea->setVisibleVScroll(true);
mSpellArea->setViewOffset(MyGUI::IntPoint(0, 0));
}
bool BirthDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
// Have A button do nothing so mouse controller still works.
return false;
}
else if (arg.button == SDL_CONTROLLER_BUTTON_START)
{
onOkClicked(nullptr);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onBackClicked(nullptr);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
winMgr->setKeyFocusWidget(mBirthList);
winMgr->injectKeyPress(MyGUI::KeyCode::ArrowUp, 0, false);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
winMgr->setKeyFocusWidget(mBirthList);
winMgr->injectKeyPress(MyGUI::KeyCode::ArrowDown, 0, false);
}
return true;
}
}

View file

@ -55,6 +55,8 @@ namespace MWGui
std::vector<MyGUI::Widget*> mSpellItems;
ESM::RefId mCurrentBirthId;
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
};
}
#endif

View file

@ -18,6 +18,7 @@
#include <components/esm3/loadnpc.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/settings/values.hpp>
#include <components/vfs/manager.hpp>
#include "tooltips.hpp"
@ -46,15 +47,20 @@ namespace MWGui
getWidget(mClassImage, "ClassImage");
getWidget(mClassName, "ClassName");
MyGUI::Button* backButton;
getWidget(backButton, "BackButton");
backButton->setCaptionWithReplacing("#{sMessageQuestionAnswer3}");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked);
getWidget(mBackButton, "BackButton");
mBackButton->setCaptionWithReplacing("#{sMessageQuestionAnswer3}");
mBackButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked);
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
okButton->setCaptionWithReplacing("#{sMessageQuestionAnswer2}");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked);
getWidget(mOkButton, "OKButton");
mOkButton->setCaptionWithReplacing("#{sMessageQuestionAnswer2}");
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked);
if (Settings::gui().mControllerMenus)
{
mOkButton->setStateSelected(true);
trackFocusEvents(mBackButton);
trackFocusEvents(mOkButton);
}
center();
}
@ -71,6 +77,33 @@ namespace MWGui
center();
}
bool GenerateClassResultDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
if (mMouseFocus != nullptr)
return false;
if (mOkButtonFocus)
onOkClicked(mOkButton);
else
onBackClicked(mBackButton);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onBackClicked(mBackButton);
}
else if ((arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT && mOkButtonFocus) ||
(arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT && !mOkButtonFocus))
{
mOkButtonFocus = !mOkButtonFocus;
mOkButton->setStateSelected(mOkButtonFocus);
mBackButton->setStateSelected(!mOkButtonFocus);
}
return true;
}
// widget controls
void GenerateClassResultDialog::onOkClicked(MyGUI::Widget* _sender)
@ -278,6 +311,37 @@ namespace MWGui
setClassImage(mClassImage, mCurrentClassId);
}
bool PickClassDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
// Have A button do nothing so mouse controller still works.
return false;
}
else if (arg.button == SDL_CONTROLLER_BUTTON_START)
{
onOkClicked(nullptr);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onBackClicked(nullptr);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
winMgr->setKeyFocusWidget(mClassList);
winMgr->injectKeyPress(MyGUI::KeyCode::ArrowUp, 0, false);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
winMgr->setKeyFocusWidget(mClassList);
winMgr->injectKeyPress(MyGUI::KeyCode::ArrowDown, 0, false);
}
return true;
}
/* InfoBoxDialog */
void InfoBoxDialog::fitToText(MyGUI::TextBox* widget)
@ -353,6 +417,14 @@ namespace MWGui
fitToText(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &InfoBoxDialog::onButtonClicked);
coord.top += button->getHeight();
if (Settings::gui().mControllerMenus && buttons.size() > 1 && this->mButtons.empty())
{
// First button is selected by default
button->setStateSelected(true);
}
trackFocusEvents(button);
this->mButtons.push_back(button);
}
}
@ -382,6 +454,53 @@ namespace MWGui
}
}
bool InfoBoxDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
if (mMouseFocus != nullptr)
return false;
onButtonClicked(mButtons[mControllerFocus]);
return true;
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
if (mButtons.size() == 1)
onButtonClicked(mButtons[0]);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{
if (mButtons.size() <= 1)
return true;
if (mButtons.size() == 2 && mControllerFocus == 0)
return true;
mButtons[mControllerFocus]->setStateSelected(false);
if (mControllerFocus == 0)
mControllerFocus = mButtons.size() - 1;
else
mControllerFocus--;
mButtons[mControllerFocus]->setStateSelected(true);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{
if (mButtons.size() <= 1)
return true;
if (mButtons.size() == 2 && mControllerFocus == mButtons.size() - 1)
return true;
mButtons[mControllerFocus]->setStateSelected(false);
if (mControllerFocus == mButtons.size() - 1)
mControllerFocus = 0;
else
mControllerFocus++;
mButtons[mControllerFocus]->setStateSelected(true);
}
return true;
}
/* ClassChoiceDialog */
ClassChoiceDialog::ClassChoiceDialog()
@ -552,6 +671,24 @@ namespace MWGui
MyGUI::UString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {})));
}
bool CreateClassDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
// Have A button do nothing so mouse controller still works.
return false;
}
else if (arg.button == SDL_CONTROLLER_BUTTON_START)
{
onOkClicked(nullptr);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onBackClicked(nullptr);
}
return true;
}
// widget controls
void CreateClassDialog::onDialogCancel()
@ -739,6 +876,16 @@ namespace MWGui
return true;
}
bool SelectSpecializationDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onCancelClicked(nullptr);
return true;
}
return false;
}
/* SelectAttributeDialog */
SelectAttributeDialog::SelectAttributeDialog()
@ -791,6 +938,16 @@ namespace MWGui
return true;
}
bool SelectAttributeDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onCancelClicked(nullptr);
return true;
}
return false;
}
/* SelectSkillDialog */
SelectSkillDialog::SelectSkillDialog()
@ -855,6 +1012,16 @@ namespace MWGui
return true;
}
bool SelectSkillDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onCancelClicked(nullptr);
return true;
}
return false;
}
/* DescriptionDialog */
DescriptionDialog::DescriptionDialog()
@ -904,4 +1071,13 @@ namespace MWGui
imageBox->setImageTexture(classImage);
}
bool DescriptionDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A || arg.button == SDL_CONTROLLER_BUTTON_B)
{
onOkClicked(nullptr);
return true;
}
return false;
}
}

View file

@ -42,6 +42,7 @@ namespace MWGui
protected:
void onButtonClicked(MyGUI::Widget* _sender);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
private:
void fitToText(MyGUI::TextBox* widget);
@ -50,6 +51,7 @@ namespace MWGui
MyGUI::TextBox* mText;
MyGUI::Widget* mButtonBar;
std::vector<MyGUI::Button*> mButtons;
int mControllerFocus = 0;
};
// Lets the player choose between 3 ways of creating a class
@ -92,10 +94,14 @@ namespace MWGui
protected:
void onOkClicked(MyGUI::Widget* _sender);
void onBackClicked(MyGUI::Widget* _sender);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
bool mOkButtonFocus = true;
private:
MyGUI::ImageBox* mClassImage;
MyGUI::TextBox* mClassName;
MyGUI::Button* mBackButton;
MyGUI::Button* mOkButton;
ESM::RefId mCurrentClassId;
};
@ -132,6 +138,7 @@ namespace MWGui
void onOkClicked(MyGUI::Widget* _sender);
void onBackClicked(MyGUI::Widget* _sender);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
private:
void updateClasses();
@ -173,6 +180,7 @@ namespace MWGui
protected:
void onSpecializationClicked(MyGUI::Widget* _sender);
void onCancelClicked(MyGUI::Widget* _sender);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
private:
MyGUI::TextBox *mSpecialization0, *mSpecialization1, *mSpecialization2;
@ -206,6 +214,7 @@ namespace MWGui
protected:
void onAttributeClicked(Widgets::MWAttributePtr _sender);
void onCancelClicked(MyGUI::Widget* _sender);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
private:
ESM::RefId mAttributeId;
@ -237,6 +246,7 @@ namespace MWGui
protected:
void onSkillClicked(Widgets::MWSkillPtr _sender);
void onCancelClicked(MyGUI::Widget* _sender);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
private:
ESM::RefId mSkillId;
@ -258,6 +268,7 @@ namespace MWGui
protected:
void onOkClicked(MyGUI::Widget* _sender);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
private:
MyGUI::EditBox* mTextEdit;
@ -329,6 +340,8 @@ namespace MWGui
Widgets::MWAttributePtr mAffectedAttribute;
Widgets::MWSkillPtr mAffectedSkill;
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
};
}
#endif

View file

@ -29,7 +29,7 @@ namespace MWGui
void onOkButtonClicked(MyGUI::Widget* _sender);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
int mOkButtonFocus = true;
bool mOkButtonFocus = true;
};
}

View file

@ -501,6 +501,14 @@ namespace MWGui
winMgr->setKeyFocusWidget(mRaceList);
winMgr->injectKeyPress(MyGUI::KeyCode::ArrowDown, 0, false);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT)
{
onPreviewScroll(nullptr, 5);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)
{
onPreviewScroll(nullptr, -5);
}
return true;
}

View file

@ -3,6 +3,7 @@
#include "windowbase.hpp"
#include <components/esm/refid.hpp>
#include <components/widgets/scrollbar.hpp>
#include <memory>
namespace MWRender
@ -100,7 +101,7 @@ namespace MWGui
MyGUI::ImageBox* mPreviewImage;
MyGUI::ListBox* mRaceList;
MyGUI::ScrollBar* mHeadRotate;
Gui::ScrollBar* mHeadRotate;
MyGUI::Widget* mSkillList;
std::vector<MyGUI::Widget*> mSkillItems;

View file

@ -46,21 +46,29 @@ namespace MWGui
getWidget(button, "NameButton");
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);
trackFocusEvents(button);
mButtons.push_back(button);
getWidget(mRaceWidget, "RaceText");
getWidget(button, "RaceButton");
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);
trackFocusEvents(button);
mButtons.push_back(button);
getWidget(mClassWidget, "ClassText");
getWidget(button, "ClassButton");
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);
trackFocusEvents(button);
mButtons.push_back(button);
getWidget(mBirthSignWidget, "SignText");
getWidget(button, "SignButton");
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);
trackFocusEvents(button);
mButtons.push_back(button);
// Setup dynamic stats
getWidget(mHealth, "Health");
@ -108,10 +116,17 @@ namespace MWGui
MyGUI::Button* backButton;
getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked);
trackFocusEvents(backButton);
mButtons.push_back(backButton);
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
trackFocusEvents(okButton);
mButtons.push_back(okButton);
if (Settings::gui().mControllerMenus)
mButtons[mControllerFocus]->setStateSelected(true);
}
void ReviewDialog::onOpen()
@ -522,4 +537,65 @@ namespace MWGui
MyGUI::IntPoint(0, static_cast<int>(mSkillView->getViewOffset().top + _rel * 0.3)));
}
bool ReviewDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
if (mMouseFocus != nullptr)
return false;
switch(mControllerFocus)
{
case 0:
onNameClicked(mButtons[0]);
break;
case 1:
onRaceClicked(mButtons[1]);
break;
case 2:
onClassClicked(mButtons[2]);
break;
case 3:
onBirthSignClicked(mButtons[3]);
break;
case 4:
onBackClicked(mButtons[4]);
break;
case 5:
onOkClicked(mButtons[5]);
break;
}
return true;
}
else if (arg.button == SDL_CONTROLLER_BUTTON_START)
{
onOkClicked(mButtons[5]);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onBackClicked(mButtons[4]);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP ||
arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT)
{
mButtons[mControllerFocus]->setStateSelected(false);
if (mControllerFocus == 0)
mControllerFocus = mButtons.size() - 1;
else
mControllerFocus--;
mButtons[mControllerFocus]->setStateSelected(true);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN ||
arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)
{
mButtons[mControllerFocus]->setStateSelected(false);
if (mControllerFocus == mButtons.size() - 1)
mControllerFocus = 0;
else
mControllerFocus++;
mButtons[mControllerFocus]->setStateSelected(true);
}
return true;
}
}

View file

@ -72,6 +72,7 @@ namespace MWGui
void onBirthSignClicked(MyGUI::Widget* _sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
private:
void addSkills(const std::vector<ESM::RefId>& skills, const std::string& titleId,
@ -100,6 +101,10 @@ namespace MWGui
std::vector<MyGUI::Widget*> mSkillWidgets; //< Skills and other information
bool mUpdateSkillArea;
// 0 = Name, 1 = Race, 2 = Class, 3 = BirthSign, 4 = Back, 5 = OK
std::vector<MyGUI::Button*> mButtons;
int mControllerFocus = 5;
};
}
#endif