1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-10-16 11:16:34 +00:00

Minimal controller support for dialog window

This commit is contained in:
Andrew Lanzone 2025-05-18 22:45:22 -07:00
parent a144793753
commit 0aad0d379a
4 changed files with 152 additions and 0 deletions

View file

@ -88,6 +88,10 @@ namespace MWGui
mBribe10Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mBribe100Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mBribe1000Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mDisableGamepadCursor = Settings::gui().mControllerMenus;
mControllerButtons.a = "#{sSelect}";
mControllerButtons.b = "#{sBack}";
}
void PersuasionDialog::adjustAction(MyGUI::Widget* action, int& totalHeight)
@ -144,6 +148,24 @@ namespace MWGui
else
mMainWidget->setSize(mInitialMainWidgetWidth, mMainWidget->getSize().height);
if (Settings::gui().mControllerMenus)
{
mControllerFocus = 0;
mButtons.clear();
mButtons.push_back(mAdmireButton);
mButtons.push_back(mIntimidateButton);
mButtons.push_back(mTauntButton);
if (mBribe10Button->getEnabled())
mButtons.push_back(mBribe10Button);
if (mBribe100Button->getEnabled())
mButtons.push_back(mBribe100Button);
if (mBribe1000Button->getEnabled())
mButtons.push_back(mBribe1000Button);
for (int i = 0; i < mButtons.size(); i++)
mButtons[i]->setStateSelected(i == 0);
}
WindowModal::onOpen();
}
@ -152,6 +174,34 @@ namespace MWGui
return mAdmireButton;
}
bool PersuasionDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
onPersuade(mButtons[mControllerFocus]);
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
onCancel(mCancelButton);
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{
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)
{
mButtons[mControllerFocus]->setStateSelected(false);
if (mControllerFocus == mButtons.size() - 1)
mControllerFocus = 0;
else
mControllerFocus++;
mButtons[mControllerFocus]->setStateSelected(true);
}
return true;
}
// --------------------------------------------------------------------------------------------------
Response::Response(std::string_view text, std::string_view title, bool needMargin)
@ -335,6 +385,9 @@ namespace MWGui
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord
+= MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
mControllerButtons.a = "#{sAsk}";
mControllerButtons.b = "#{sGoodbye}";
}
void DialogueWindow::onTradeComplete()
@ -488,6 +541,14 @@ namespace MWGui
updateTopics();
updateTopicsPane(); // force update for new services
if (Settings::gui().mControllerMenus && !sameActor)
{
setControllerFocus(mControllerFocus, false);
// Reset focus to very top. Maybe change this to mTopicsList->getItemCount() - mKeywords.size()?
mControllerFocus = 0;
setControllerFocus(mControllerFocus, true);
}
updateDisposition();
restock();
}
@ -601,6 +662,9 @@ namespace MWGui
redrawTopicsList();
updateHistory();
if (Settings::gui().mControllerMenus)
setControllerFocus(mControllerFocus, true);
}
void DialogueWindow::updateHistory(bool scrollbar)
@ -847,4 +911,75 @@ namespace MWGui
&& actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion");
}
void DialogueWindow::setControllerFocus(int index, bool focused)
{
// List is mTopicsList + "Goodbye" button below the list.
if (index < 0 || index > mTopicsList->getItemCount())
return;
if (index == mTopicsList->getItemCount())
{
mGoodbyeButton->setStateSelected(focused);
}
else {
std::string keyword = mTopicsList->getItemNameAt(mControllerFocus);
if (keyword.length() == 0)
return;
MyGUI::Button* button = mTopicsList->getItemWidget(keyword);
button->setStateSelected(focused);
}
if (focused)
{
// Scroll the side bar to keep the active item in view
if (index <= 5)
mTopicsList->setViewOffset(0);
else
mTopicsList->setViewOffset(-20 * (index - 5));
}
}
bool DialogueWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
if (mControllerFocus == mTopicsList->getItemCount())
onGoodbyeActivated();
else
onSelectListItem(mTopicsList->getItemNameAt(mControllerFocus), mControllerFocus);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onGoodbyeActivated();
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{
// Number of items is mTopicsList.length+1 because of "Goodbye" button.
setControllerFocus(mControllerFocus, false);
if (mControllerFocus <= 0)
mControllerFocus = mTopicsList->getItemCount();
else if (mTopicsList->getItemNameAt(mControllerFocus - 1).length() == 0)
mControllerFocus -= 2; // Skip separator
else
mControllerFocus--;
setControllerFocus(mControllerFocus, true);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{
// Number of items is mTopicsList.length+1 because of "Goodbye" button.
setControllerFocus(mControllerFocus, false);
if (mControllerFocus >= mTopicsList->getItemCount())
mControllerFocus = 0;
else if (mControllerFocus == mTopicsList->getItemCount() - 1)
mControllerFocus = mTopicsList->getItemCount();
else if (mTopicsList->getItemNameAt(mControllerFocus + 1).length() == 0)
mControllerFocus += 2; // Skip separator
else
mControllerFocus++;
setControllerFocus(mControllerFocus, true);
}
return true;
}
}

View file

@ -49,6 +49,9 @@ namespace MWGui
MyGUI::Widget* getDefaultKeyFocus() override;
protected:
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
private:
std::unique_ptr<ResponseCallback> mCallback;
@ -65,6 +68,9 @@ namespace MWGui
MyGUI::Widget* mActionsBox;
Gui::AutoSizedTextBox* mGoldLabel;
std::vector<MyGUI::Button*> mButtons;
int mControllerFocus = 0;
void adjustAction(MyGUI::Widget* action, int& totalHeight);
void onCancel(MyGUI::Widget* sender);
@ -186,6 +192,8 @@ namespace MWGui
void onReferenceUnavailable() override;
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
private:
void updateDisposition();
void restock();
@ -220,6 +228,9 @@ namespace MWGui
std::unique_ptr<ResponseCallback> mCallback;
std::unique_ptr<ResponseCallback> mGreetingCallback;
void setControllerFocus(int index, bool focused);
int mControllerFocus = 0;
void updateTopicFormat();
};
}

View file

@ -173,4 +173,9 @@ namespace Gui
{
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
}
void MWList::setViewOffset(int offset)
{
mScrollView->setViewOffset(MyGUI::IntPoint(0, offset));
}
}

View file

@ -48,6 +48,7 @@ namespace Gui
///< get widget for an item name, useful to set up tooltip
void scrollToTop();
void setViewOffset(int offset);
void setPropertyOverride(std::string_view _key, std::string_view _value) override;