diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 37de0abeab..eeb46edce0 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -44,7 +44,7 @@ add_openmw_dir (mwgui tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview draganddrop timeadvancer jailscreen itemchargeview keyboardnavigation textcolours statswatcher - postprocessorhud settings + postprocessorhud settings controllerbuttonsoverlay ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index e00837265f..5302270ee0 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -386,6 +386,7 @@ namespace MWBase virtual MWGui::WindowBase* getActiveControllerWindow() = 0; /// Cycle to the next window to receive controller events virtual void cycleActiveControllerWindow(bool next) = 0; + virtual void updateControllerButtonsOverlay() = 0; // Used in Lua bindings virtual const std::vector& getGuiModeStack() const = 0; diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index b121c1978b..bc6b37df50 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -273,6 +273,11 @@ namespace MWGui mSpellArea->setViewOffset(MyGUI::IntPoint(0, 0)); } + std::string BirthDialog::getButtonStr() + { + return "(A) #{sSelect} (X) #{sDone} (B) #{sBack}"; + } + bool BirthDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) @@ -290,6 +295,10 @@ namespace MWGui { onBackClicked(mBackButton); } + else if (arg.button == SDL_CONTROLLER_BUTTON_X) + { + onOkClicked(mOkButton); + } else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) { MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); diff --git a/apps/openmw/mwgui/birth.hpp b/apps/openmw/mwgui/birth.hpp index 8a7190b934..841ff872b0 100644 --- a/apps/openmw/mwgui/birth.hpp +++ b/apps/openmw/mwgui/birth.hpp @@ -38,6 +38,8 @@ namespace MWGui */ EventHandle_WindowBase eventDone; + std::string getButtonStr() override; + protected: void onSelectBirth(MyGUI::ListBox* _sender, size_t _index); diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index 79cfb9fa88..6f6a6187b9 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -222,6 +222,14 @@ namespace MWGui } } + std::string BookWindow::getButtonStr() + { + if (mTakeButton->getVisible()) + return "(A) #{sTake} (LB) #{sPrev} (RB) #{sNext} (B) #{sClose}"; + else + return "(LB) #{sPrev} (RB) #{sNext} (B) #{sClose}"; + } + bool BookWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) diff --git a/apps/openmw/mwgui/bookwindow.hpp b/apps/openmw/mwgui/bookwindow.hpp index 062c6e9dbd..f6b1fa7bc9 100644 --- a/apps/openmw/mwgui/bookwindow.hpp +++ b/apps/openmw/mwgui/bookwindow.hpp @@ -21,6 +21,7 @@ namespace MWGui bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; std::string_view getWindowIdForLua() const override { return "Book"; } + std::string getButtonStr() override; protected: void onNextPageButtonClicked(MyGUI::Widget* sender); diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index a7b5b36aa5..7c9d7c724e 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -77,6 +77,11 @@ namespace MWGui center(); } + std::string GenerateClassResultDialog::getButtonStr() + { + return "(A) #{sSelect} (B) #{sBack}"; + } + bool GenerateClassResultDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) @@ -312,6 +317,11 @@ namespace MWGui setClassImage(mClassImage, mCurrentClassId); } + std::string PickClassDialog::getButtonStr() + { + return "(A) #{sSelect} (X) #{sDone} (B) #{sBack}"; + } + bool PickClassDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) @@ -329,6 +339,10 @@ namespace MWGui { onBackClicked(mBackButton); } + else if (arg.button == SDL_CONTROLLER_BUTTON_X) + { + onOkClicked(mOkButton); + } else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) { MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); @@ -476,6 +490,11 @@ namespace MWGui } } + std::string InfoBoxDialog::getButtonStr() + { + return "(A) #{sSelect}"; + } + bool InfoBoxDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) @@ -699,6 +718,11 @@ namespace MWGui MyGUI::UString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); } + std::string CreateClassDialog::getButtonStr() + { + return "(A) #{sSelect} (X) #{sDone} (B) #{sCancel}"; + } + bool CreateClassDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) @@ -718,6 +742,10 @@ namespace MWGui { onBackClicked(mButtons[1]); } + else if (arg.button == SDL_CONTROLLER_BUTTON_X) + { + onOkClicked(mButtons[2]); + } else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP || arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) { @@ -942,6 +970,11 @@ namespace MWGui return true; } + std::string SelectSpecializationDialog::getButtonStr() + { + return "(A) #{sSelect} (B) #{sCancel}"; + } + bool SelectSpecializationDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_B) @@ -1004,6 +1037,11 @@ namespace MWGui return true; } + std::string SelectAttributeDialog::getButtonStr() + { + return "(A) #{sSelect} (B) #{sCancel}"; + } + bool SelectAttributeDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_B) @@ -1078,6 +1116,11 @@ namespace MWGui return true; } + std::string SelectSkillDialog::getButtonStr() + { + return "(A) #{sSelect} (B) #{sCancel}"; + } + bool SelectSkillDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_B) diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index e2566ce6c0..af18e5d660 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -40,6 +40,8 @@ namespace MWGui */ EventHandle_Int eventButtonSelected; + std::string getButtonStr() override; + protected: void onButtonClicked(MyGUI::Widget* _sender); bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; @@ -91,6 +93,8 @@ namespace MWGui */ EventHandle_WindowBase eventDone; + std::string getButtonStr() override; + protected: void onOkClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender); @@ -132,6 +136,8 @@ namespace MWGui */ EventHandle_WindowBase eventDone; + std::string getButtonStr() override; + protected: void onSelectClass(MyGUI::ListBox* _sender, size_t _index); void onAccept(MyGUI::ListBox* _sender, size_t _index); @@ -183,6 +189,8 @@ namespace MWGui */ EventHandle_Void eventItemSelected; + std::string getButtonStr() override; + protected: void onSpecializationClicked(MyGUI::Widget* _sender); void onCancelClicked(MyGUI::Widget* _sender); @@ -217,6 +225,8 @@ namespace MWGui */ EventHandle_Void eventItemSelected; + std::string getButtonStr() override; + protected: void onAttributeClicked(Widgets::MWAttributePtr _sender); void onCancelClicked(MyGUI::Widget* _sender); @@ -249,6 +259,8 @@ namespace MWGui */ EventHandle_Void eventItemSelected; + std::string getButtonStr() override; + protected: void onSkillClicked(Widgets::MWSkillPtr _sender); void onCancelClicked(MyGUI::Widget* _sender); @@ -310,6 +322,8 @@ namespace MWGui */ EventHandle_WindowBase eventDone; + std::string getButtonStr() override; + protected: void onOkClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender); diff --git a/apps/openmw/mwgui/confirmationdialog.cpp b/apps/openmw/mwgui/confirmationdialog.cpp index b284db16b2..8fa4afab16 100644 --- a/apps/openmw/mwgui/confirmationdialog.cpp +++ b/apps/openmw/mwgui/confirmationdialog.cpp @@ -72,6 +72,11 @@ namespace MWGui eventOkClicked(); } + std::string ConfirmationDialog::getButtonStr() + { + return "(A) #{sOk} (B) #{sCancel}"; + } + bool ConfirmationDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) diff --git a/apps/openmw/mwgui/confirmationdialog.hpp b/apps/openmw/mwgui/confirmationdialog.hpp index 9b26e3a3c9..2e2f7df0af 100644 --- a/apps/openmw/mwgui/confirmationdialog.hpp +++ b/apps/openmw/mwgui/confirmationdialog.hpp @@ -20,6 +20,8 @@ namespace MWGui EventHandle_Void eventOkClicked; EventHandle_Void eventCancelClicked; + std::string getButtonStr() override; + private: MyGUI::EditBox* mMessage; MyGUI::Button* mOkButton; diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index c47000d753..05e56d10ee 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -352,6 +352,14 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); } + std::string ContainerWindow::getButtonStr() + { + if (mDisposeCorpseButton->getVisible()) + return "(A) #{sTake} (X) #{sTakeAll} (LB) #{sDisposeofCorpse} (Y) #{sInfo} [LT] #{sInventory} (B) #{sClose}"; + else + return "(A) #{sTake} (X) #{sTakeAll} (Y) #{sInfo} [LT] #{sInventory} (B) #{sClose}"; + } + bool ContainerWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) diff --git a/apps/openmw/mwgui/container.hpp b/apps/openmw/mwgui/container.hpp index f7f4ef3c31..22f5f2425a 100644 --- a/apps/openmw/mwgui/container.hpp +++ b/apps/openmw/mwgui/container.hpp @@ -40,6 +40,7 @@ namespace MWGui std::string_view getWindowIdForLua() const override { return "Container"; } + std::string getButtonStr() override; void setActiveControllerWindow(bool active) override; private: diff --git a/apps/openmw/mwgui/controllerbuttonsoverlay.cpp b/apps/openmw/mwgui/controllerbuttonsoverlay.cpp new file mode 100644 index 0000000000..2e7ec3ffcd --- /dev/null +++ b/apps/openmw/mwgui/controllerbuttonsoverlay.cpp @@ -0,0 +1,26 @@ +#include "controllerbuttonsoverlay.hpp" + +#include +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" + +namespace MWGui +{ + ControllerButtonsOverlay::ControllerButtonsOverlay() + : WindowBase("openmw_controllerbuttons.layout") + { + getWidget(mButtonStr, "ButtonStr"); + } + + void ControllerButtonsOverlay::setButtonStr(const std::string& buttonStr) + { + mButtonStr->setCaptionWithReplacing(buttonStr); + + // int height = mMessage->getTextSize().height + 60; + // int width = mMessage->getTextSize().width + 24; + // mMainWidget->setSize(width, height); + // mMessage->setSize(mMessage->getWidth(), mMessage->getTextSize().height + 24); + } +} diff --git a/apps/openmw/mwgui/controllerbuttonsoverlay.hpp b/apps/openmw/mwgui/controllerbuttonsoverlay.hpp new file mode 100644 index 0000000000..c2a9b110bf --- /dev/null +++ b/apps/openmw/mwgui/controllerbuttonsoverlay.hpp @@ -0,0 +1,20 @@ +#ifndef MWGUI_CONTROLLERBUTTONSOVERLAY_H +#define MWGUI_CONTROLLERBUTTONSOVERLAY_H + +#include "windowbase.hpp" + +namespace MWGui +{ + class ControllerButtonsOverlay : public WindowBase + { + public: + ControllerButtonsOverlay(); + + void setButtonStr(const std::string& buttonStr); + + private: + MyGUI::TextBox* mButtonStr; + }; +} + +#endif diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 907de6f515..029104d27c 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -309,6 +309,8 @@ namespace notifyQuests(getWidget(QuestsList)); else notifyTopics(getWidget(TopicsList)); + + MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay(); } void pushBook(Book& book, unsigned int page) @@ -340,6 +342,7 @@ namespace { setVisible(CloseBTN, mStates.size() < 2); setVisible(JournalBTN, mStates.size() >= 2); + MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay(); } void updateShowingPages() @@ -382,6 +385,8 @@ namespace setText(PageOneNum, page + 1); setText(PageTwoNum, page + 2); + + MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay(); } void notifyKeyPress(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character) @@ -409,6 +414,7 @@ namespace mTopicsMode = false; MWBase::Environment::get().getWindowManager()->playSound(ESM::RefId::stringRefId("book page")); + MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay(); } void notifyTopicSelected(const std::string& topicIdString, int id) @@ -441,6 +447,7 @@ namespace mOptionsMode = false; MWBase::Environment::get().getWindowManager()->playSound(ESM::RefId::stringRefId("book page")); + MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay(); } void notifyOptions(MyGUI::Widget* _sender) @@ -662,6 +669,16 @@ namespace } } + std::string getButtonStr() override + { + if (mOptionsMode) + return "(A) #{sSelect} (X) Quests (Y) #{sTopics} (B) #{sBack}"; + else if (mStates.size() > 1) + return "(A) #{sSelect} (LB) #{sPrev} (RB) #{sNext} (X) Quests (Y) #{sTopics} (B) #{sBack}"; + else + return "(A) #{sSelect} (LB) #{sPrev} (RB) #{sNext} (X) Quests (Y) #{sTopics} (B) #{sClose}"; + } + bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override { if (arg.button == SDL_CONTROLLER_BUTTON_A) // A: Mouse click or Select diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index cfcb63e4d5..62740c030d 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -207,6 +207,11 @@ namespace MWGui } } + std::string MainMenu::getButtonStr() + { + return ""; + } + bool MainMenu::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { // REMOVEME diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index 453a16b5e4..aa4cba4257 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -55,6 +55,8 @@ namespace MWGui bool exit() override; + std::string getButtonStr() override; + private: const VFS::Manager* mVFS; diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index be0f284b04..00c49e44d0 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -439,6 +439,11 @@ namespace MWGui return mButtonPressed; } + std::string InteractiveMessageBox::getButtonStr() + { + return "InteractiveMessageBox (A) #{sOk}"; + } + bool InteractiveMessageBox::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index e6128ee0d1..3bc3127828 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -103,6 +103,7 @@ namespace MWGui bool mMarkedToDelete; + std::string getButtonStr() override; bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; private: diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 1ff5cc4784..c26d42f0f7 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -463,6 +463,11 @@ namespace MWGui } } + std::string RaceDialog::getButtonStr() + { + return "(A) #{sSelect} (Y) #{sSex} (LB) #{sHair} (RB) #{sFace} (X) #{sDone} (B) #{sBack}"; + } + bool RaceDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) @@ -481,6 +486,10 @@ namespace MWGui onBackClicked(mBackButton); } else if (arg.button == SDL_CONTROLLER_BUTTON_X) + { + onOkClicked(mOkButton); + } + else if (arg.button == SDL_CONTROLLER_BUTTON_Y) { onSelectNextGender(nullptr); } diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index c3b322ba8b..b5eafb51f1 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -65,6 +65,8 @@ namespace MWGui */ EventHandle_WindowBase eventDone; + std::string getButtonStr() override; + protected: void onPreviewScroll(MyGUI::Widget* _sender, int _delta); void onHeadRotate(MyGUI::ScrollBar* _sender, size_t _position); diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index b113ace2be..40be524daf 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -537,6 +537,11 @@ namespace MWGui MyGUI::IntPoint(0, static_cast(mSkillView->getViewOffset().top + _rel * 0.3))); } + std::string ReviewDialog::getButtonStr() + { + return "(A) #{sSelect} (X) #{sDone} (B) #{sBack}"; + } + bool ReviewDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) @@ -567,14 +572,14 @@ namespace MWGui } 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_X) + { + onOkClicked(mButtons[5]); + } else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP || arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) { diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index fe53787fe3..e14bf834cd 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -62,6 +62,8 @@ namespace MWGui EventHandle_Int eventActivateDialog; + std::string getButtonStr() override; + protected: void onOkClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender); diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index 37ed137b23..9db28afc10 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -504,6 +504,14 @@ namespace MWGui mScreenshot->setRenderItemTexture(mScreenshotTexture.get()); } + std::string SaveGameDialog::getButtonStr() + { + if (mSaving) + return "(A) #{sSelect} (B) #{sClose}"; + else + return "(A) #{sSelect} (Y) Select Character (B) #{sClose}"; + } + bool SaveGameDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) @@ -521,6 +529,16 @@ namespace MWGui { onCancelButtonClicked(mCancelButton); } + else if (arg.button == SDL_CONTROLLER_BUTTON_Y) + { + uint32_t index = mCharacterSelection->getIndexSelected(); + if (index >= mCharacterSelection->getItemCount() - 1) + index = 0; + else + index++; + mCharacterSelection->setIndexSelected(index); + mUsingGamepadGuiCursor = false; + } else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) { MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); @@ -543,26 +561,6 @@ namespace MWGui mCancelButton->setStateSelected(!mOkButtonFocus); mUsingGamepadGuiCursor = false; } - else if (arg.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER) - { - uint32_t index = mCharacterSelection->getIndexSelected(); - if (index <= 0) - index = mCharacterSelection->getItemCount() - 1; - else - index--; - mCharacterSelection->setIndexSelected(index); - mUsingGamepadGuiCursor = false; - } - else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) - { - uint32_t index = mCharacterSelection->getIndexSelected(); - if (index >= mCharacterSelection->getItemCount() - 1) - index = 0; - else - index++; - mCharacterSelection->setIndexSelected(index); - mUsingGamepadGuiCursor = false; - } return true; } diff --git a/apps/openmw/mwgui/savegamedialog.hpp b/apps/openmw/mwgui/savegamedialog.hpp index 2561fc60f6..e9872a0d49 100644 --- a/apps/openmw/mwgui/savegamedialog.hpp +++ b/apps/openmw/mwgui/savegamedialog.hpp @@ -24,6 +24,8 @@ namespace MWGui void setLoadOrSave(bool load); + std::string getButtonStr() override; + private: void confirmDeleteSave(); diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index 7c7ad338ce..5b7ef4238a 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -126,6 +126,14 @@ namespace MWGui BookWindowBase::onClose(); } + std::string ScrollWindow::getButtonStr() + { + if (mTakeButton->getVisible()) + return "(A) #{sTake} (RS) #{sScrolldown} (B) #{sClose}"; + else + return "(A) #{sTake} (RS) #{sScrolldown} (B) #{sClose}"; + } + bool ScrollWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) diff --git a/apps/openmw/mwgui/scrollwindow.hpp b/apps/openmw/mwgui/scrollwindow.hpp index fa3ca5b25d..4e447707d0 100644 --- a/apps/openmw/mwgui/scrollwindow.hpp +++ b/apps/openmw/mwgui/scrollwindow.hpp @@ -25,6 +25,8 @@ namespace MWGui std::string_view getWindowIdForLua() const override { return "Scroll"; } + std::string getButtonStr() override; + protected: void onCloseButtonClicked(MyGUI::Widget* _sender); void onTakeButtonClicked(MyGUI::Widget* _sender); diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 7f8d98ee05..201204bc74 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -468,7 +468,7 @@ namespace MWGui void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender) { - setVisible(false); + MWBase::Environment::get().getWindowManager()->toggleSettingsWindow(); } void SettingsWindow::onResolutionSelected(MyGUI::ListBox* _sender, size_t index) @@ -1129,6 +1129,11 @@ namespace MWGui mControlsBox->setViewOffset(MyGUI::IntPoint(0, 0)); } + std::string SettingsWindow::getButtonStr() + { + return "(A) #{sSelect} (LB) #{sPrev} Tab (RB) #{sNext} Tab (B) #{sOk}"; + } + bool SettingsWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_B) diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 555468d806..e8d7f248cb 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -26,6 +26,7 @@ namespace MWGui void onResChange(int, int) override; + std::string getButtonStr() override; bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; protected: diff --git a/apps/openmw/mwgui/textinput.cpp b/apps/openmw/mwgui/textinput.cpp index 44e0defef6..e6352c928e 100644 --- a/apps/openmw/mwgui/textinput.cpp +++ b/apps/openmw/mwgui/textinput.cpp @@ -83,6 +83,11 @@ namespace MWGui mTextEdit->setCaption(text); } + std::string TextInputDialog::getButtonStr() + { + return "(A) #{sOk}"; + } + bool TextInputDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) diff --git a/apps/openmw/mwgui/textinput.hpp b/apps/openmw/mwgui/textinput.hpp index ad7896ff27..67ca8ba757 100644 --- a/apps/openmw/mwgui/textinput.hpp +++ b/apps/openmw/mwgui/textinput.hpp @@ -24,6 +24,8 @@ namespace MWGui */ EventHandle_WindowBase eventDone; + std::string getButtonStr() override; + protected: void onOkClicked(MyGUI::Widget* _sender); void onTextAccepted(MyGUI::EditBox* _sender); diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 5b92699982..9886f036e4 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -332,6 +332,19 @@ namespace MWGui } } + std::string WaitDialog::getButtonStr() + { + if (mSleeping) + { + if (mUntilHealedButton->getVisible()) + return "(X) #{sUntilHealed} (A) #{sRest} (B) #{sCancel}"; + else + return "(A) #{sRest} (B) #{sCancel}"; + } + else + return "(A) #{sWait} (B) #{sCancel}"; + } + bool WaitDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { if (arg.button == SDL_CONTROLLER_BUTTON_A) diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp index 0d6d2a82d2..77593c3049 100644 --- a/apps/openmw/mwgui/waitdialog.hpp +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -47,6 +47,8 @@ namespace MWGui std::string_view getWindowIdForLua() const override { return "WaitDialog"; } + std::string getButtonStr() override; + protected: MyGUI::TextBox* mDateTimeText; MyGUI::TextBox* mRestText; diff --git a/apps/openmw/mwgui/windowbase.cpp b/apps/openmw/mwgui/windowbase.cpp index d01822f704..a3d1b27fb4 100644 --- a/apps/openmw/mwgui/windowbase.cpp +++ b/apps/openmw/mwgui/windowbase.cpp @@ -147,6 +147,7 @@ void WindowModal::onOpen() void WindowModal::onClose() { MWBase::Environment::get().getWindowManager()->removeCurrentModal(this); + MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay(); MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); } diff --git a/apps/openmw/mwgui/windowbase.hpp b/apps/openmw/mwgui/windowbase.hpp index fd1c743c62..cd4d2874ca 100644 --- a/apps/openmw/mwgui/windowbase.hpp +++ b/apps/openmw/mwgui/windowbase.hpp @@ -62,6 +62,7 @@ namespace MWGui // REMOVEME // virtual bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) = 0; // virtual bool onControllerThumbstickEvent(const SDL_ControllerAxisEvent& arg) = 0; + virtual std::string getButtonStr() { return ""; } virtual void setActiveControllerWindow(bool active) { mActiveControllerWindow = active; } protected: diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index d52a71a417..b9df5b0b4e 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -181,6 +181,7 @@ namespace MWGui , mPostProcessorHud(nullptr) , mJailScreen(nullptr) , mContainerWindow(nullptr) + , mControllerButtonsOverlay(nullptr) , mTranslationDataStorage(translationDataStorage) , mInputBlocker(nullptr) , mHudEnabled(true) @@ -505,6 +506,10 @@ namespace MWGui mWindows.push_back(std::move(postProcessorHud)); trackWindow(mPostProcessorHud, makePostprocessorWindowSettingValues()); + auto controllerButtonsOverlay = std::make_unique(); + mControllerButtonsOverlay = controllerButtonsOverlay.get(); + mWindows.push_back(std::move(controllerButtonsOverlay)); + mInputBlocker = MyGUI::Gui::getInstance().createWidget( {}, 0, 0, w, h, MyGUI::Align::Stretch, "InputBlocker"); @@ -662,6 +667,9 @@ namespace MWGui && !(mForceHidden & GW_Inventory) && (mAllowed & GW_Inventory)); mSpellWindow->setVisible( mSpellWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Magic) && (mAllowed & GW_Magic)); + + if (Settings::gui().mControllerMenus && mControllerButtonsOverlay) + mControllerButtonsOverlay->setVisible(false); return; } else if (getMode() != GM_Inventory) @@ -691,6 +699,8 @@ namespace MWGui mStatsWindow->setVisible(eff & GW_Stats); } + updateControllerButtonsOverlay(); + switch (mode) { // FIXME: refactor chargen windows to use modes properly (or not use them at all) @@ -720,6 +730,7 @@ namespace MWGui return; dialog->setVisible(false); mGarbageDialogs.push_back(std::move(dialog)); + updateControllerButtonsOverlay(); } void WindowManager::exitCurrentGuiMode() @@ -871,10 +882,13 @@ namespace MWGui { GuiMode mode = mGuiModes.back(); GuiModeState& state = mGuiModeStates[mode]; + if (state.mWindows.size() == 0) + return nullptr; + int activeIndex = std::clamp(mActiveControllerWindows[mode], 0, (int)state.mWindows.size() - 1); // REMOVEME - Log(Debug::Error) << "getActiveControllerWindow: " << state.mWindows.size() << " windows in state, mActiveControllerWindows[mode] = " << mActiveControllerWindows[mode]; + Log(Debug::Error) << "getActiveControllerWindow: " << state.mWindows.size() << " windows in state, mActiveControllerWindows[mode] = " << mActiveControllerWindows[mode] << ", activeIndex=" << activeIndex; // If the active window is no longer visible, find the next visible window. if (!state.mWindows[activeIndex]->isVisible()) @@ -1001,6 +1015,9 @@ namespace MWGui if (isSettingsWindowVisible()) mSettingsWindow->onFrame(frameDuration); + if (mControllerButtonsOverlay && mControllerButtonsOverlay->isVisible()) + mControllerButtonsOverlay->onFrame(frameDuration); + if (!gameRunning) return; @@ -2046,6 +2063,7 @@ namespace MWGui if (!window->exit()) return; window->setVisible(false); + updateControllerButtonsOverlay(); } } @@ -2059,6 +2077,8 @@ namespace MWGui mKeyboardNavigation->setModalWindow(input->mMainWidget); mKeyboardNavigation->setDefaultFocus(input->mMainWidget, input->getDefaultKeyFocus()); + + updateControllerButtonsOverlay(); } void WindowManager::removeCurrentModal(WindowModal* input) @@ -2526,4 +2546,34 @@ namespace MWGui } return res; } + + void WindowManager::updateControllerButtonsOverlay() + { + if (!Settings::gui().mControllerMenus ||!mControllerButtonsOverlay) + return; + + WindowBase* topWin = this->getActiveControllerWindow(); + if (!topWin || !topWin->isVisible()) + { + // REMOVEME + Log(Debug::Error) << "WindowManager::updateControllerButtonsOverlay: hiding overlay"; + mControllerButtonsOverlay->setVisible(false); + return; + } + + std::string buttonStr = topWin->getButtonStr(); + // REMOVEME + Log(Debug::Error) << "WindowManager::updateControllerButtonsOverlay: showing overlay: " << buttonStr; + if (buttonStr.length() > 0) + { + mControllerButtonsOverlay->setButtonStr(buttonStr); + mControllerButtonsOverlay->setVisible(true); + } + else + { + // REMOVEME + Log(Debug::Error) << "WindowManager::updateControllerButtonsOverlay: ...psych, hiding it"; + mControllerButtonsOverlay->setVisible(false); + } + } } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index a1c01f6fa6..5dbf3c4689 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -25,6 +25,7 @@ #include #include "charactercreation.hpp" +#include "controllerbuttonsoverlay.hpp" #include "draganddrop.hpp" #include "mapwindow.hpp" #include "messagebox.hpp" @@ -118,6 +119,7 @@ namespace MWGui class PostProcessorHud; class JailScreen; class KeyboardNavigation; + class ControllerButtonsOverlay; class WindowManager : public MWBase::WindowManager { @@ -389,6 +391,7 @@ namespace MWGui WindowBase* getActiveControllerWindow() override; void cycleActiveControllerWindow(bool next) override; + void updateControllerButtonsOverlay() override; // Used in Lua bindings const std::vector& getGuiModeStack() const override { return mGuiModes; } @@ -457,6 +460,7 @@ namespace MWGui PostProcessorHud* mPostProcessorHud; JailScreen* mJailScreen; ContainerWindow* mContainerWindow; + ControllerButtonsOverlay* mControllerButtonsOverlay; std::vector> mWindows; diff --git a/files/data/CMakeLists.txt b/files/data/CMakeLists.txt index 0290519806..97b49d1002 100644 --- a/files/data/CMakeLists.txt +++ b/files/data/CMakeLists.txt @@ -147,6 +147,7 @@ set(BUILTIN_DATA_FILES mygui/openmw_console.layout mygui/openmw_console.skin.xml mygui/openmw_container_window.layout + mygui/openmw_controllerbuttons.layout mygui/openmw_count_window.layout mygui/openmw_dialogue_window.layout mygui/openmw_dialogue_window.skin.xml diff --git a/files/data/mygui/openmw_controllerbuttons.layout b/files/data/mygui/openmw_controllerbuttons.layout new file mode 100644 index 0000000000..d12785f0fc --- /dev/null +++ b/files/data/mygui/openmw_controllerbuttons.layout @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/files/data/mygui/openmw_layers.xml b/files/data/mygui/openmw_layers.xml index 459db3fcb9..597ba0de4c 100644 --- a/files/data/mygui/openmw_layers.xml +++ b/files/data/mygui/openmw_layers.xml @@ -20,6 +20,7 @@ +