diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 3a7c84c384..2e0e9a7b7d 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -392,8 +392,12 @@ namespace MWBase /// Cycle to the next window to receive controller events virtual void cycleActiveControllerWindow(bool next) = 0; virtual void setActiveControllerWindow(MWGui::GuiMode mode, int activeIndex) = 0; - virtual bool getControllerTooltip() const = 0; - virtual void setControllerTooltip(bool enabled) = 0; + virtual bool getControllerTooltipVisible() const = 0; + virtual void setControllerTooltipVisible(bool visible) = 0; + virtual bool getControllerTooltipEnabled() const = 0; + virtual void setControllerTooltipEnabled(bool enabled) = 0; + /// Restore tooltip visibility if user has them enabled but they were hidden by mouse movement + virtual void restoreControllerTooltips() = 0; virtual void updateControllerButtonsOverlay() = 0; // Used in Lua bindings diff --git a/apps/openmw/mwgui/itemview.cpp b/apps/openmw/mwgui/itemview.cpp index ba43082d42..89d764c845 100644 --- a/apps/openmw/mwgui/itemview.cpp +++ b/apps/openmw/mwgui/itemview.cpp @@ -190,7 +190,7 @@ namespace MWGui { mControllerActiveWindow = active; - MWBase::Environment::get().getWindowManager()->setControllerTooltip( + MWBase::Environment::get().getWindowManager()->setControllerTooltipVisible( active && Settings::gui().mControllerTooltips); if (active) @@ -205,6 +205,7 @@ namespace MWGui return; int prevFocus = mControllerFocus; + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); switch (button) { @@ -218,27 +219,30 @@ namespace MWGui break; case SDL_CONTROLLER_BUTTON_RIGHTSTICK: // Toggle info tooltip - MWBase::Environment::get().getWindowManager()->setControllerTooltip( - !MWBase::Environment::get().getWindowManager()->getControllerTooltip()); + winMgr->setControllerTooltipEnabled(!winMgr->getControllerTooltipEnabled()); updateControllerFocus(-1, mControllerFocus); break; case SDL_CONTROLLER_BUTTON_DPAD_UP: + winMgr->restoreControllerTooltips(); if (mControllerFocus % mRows == 0) mControllerFocus = std::min(mControllerFocus + mRows - 1, mItemCount - 1); else mControllerFocus--; break; case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + winMgr->restoreControllerTooltips(); if (mControllerFocus % mRows == mRows - 1 || mControllerFocus == mItemCount - 1) mControllerFocus -= mControllerFocus % mRows; else mControllerFocus++; break; case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + winMgr->restoreControllerTooltips(); if (mControllerFocus >= mRows) mControllerFocus -= mRows; break; case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + winMgr->restoreControllerTooltips(); if (mControllerFocus + mRows < mItemCount) mControllerFocus += mRows; else if (mControllerFocus / mRows != (mItemCount - 1) / mRows) @@ -257,7 +261,7 @@ namespace MWGui void ItemView::updateControllerFocus(int prevFocus, int newFocus) { MWBase::Environment::get().getWindowManager()->setCursorVisible( - !MWBase::Environment::get().getWindowManager()->getControllerTooltip()); + !MWBase::Environment::get().getWindowManager()->getControllerTooltipVisible()); if (!mItemCount) return; @@ -285,7 +289,10 @@ namespace MWGui else mScrollView->setViewOffset(MyGUI::IntPoint(-42 * (column - 3), 0)); - if (MWBase::Environment::get().getWindowManager()->getControllerTooltip()) + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); + winMgr->restoreControllerTooltips(); + + if (winMgr->getControllerTooltipVisible()) MWBase::Environment::get().getInputManager()->warpMouseToWidget(focused); } } diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index 7ace160350..a1e5fecd1e 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -151,8 +151,8 @@ namespace MWGui mSpellButtons[0].first->setStateSelected(true); MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); - winMgr->setControllerTooltip(Settings::gui().mControllerTooltips); - if (winMgr->getControllerTooltip()) + winMgr->setControllerTooltipVisible(Settings::gui().mControllerTooltips); + if (winMgr->getControllerTooltipVisible()) MWBase::Environment::get().getInputManager()->warpMouseToWidget(mSpellButtons[0].first); } } @@ -230,6 +230,8 @@ namespace MWGui bool SpellBuyingWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) { + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); + if (arg.button == SDL_CONTROLLER_BUTTON_A) { if (mControllerFocus < mSpellButtons.size()) @@ -242,11 +244,12 @@ namespace MWGui else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK) { // Toggle info tooltip - MWBase::Environment::get().getWindowManager()->setControllerTooltip( - !MWBase::Environment::get().getWindowManager()->getControllerTooltip()); + winMgr->setControllerTooltipEnabled(!winMgr->getControllerTooltipEnabled()); } else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) { + winMgr->restoreControllerTooltips(); + if (mSpellButtons.size() <= 1) return true; @@ -256,6 +259,8 @@ namespace MWGui } else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) { + winMgr->restoreControllerTooltips(); + if (mSpellButtons.size() <= 1) return true; @@ -279,7 +284,7 @@ namespace MWGui } // Warp the mouse to the selected spell to show the tooltip - if (MWBase::Environment::get().getWindowManager()->getControllerTooltip()) + if (MWBase::Environment::get().getWindowManager()->getControllerTooltipVisible()) MWBase::Environment::get().getInputManager()->warpMouseToWidget(mSpellButtons[mControllerFocus].first); } diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 6d27b4e4d2..bd4728928b 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -850,7 +850,7 @@ namespace MWGui if (mAvailableButtons.size() > 0) { mAvailableButtons[0]->setStateSelected(true); - if (MWBase::Environment::get().getWindowManager()->getControllerTooltip()) + if (MWBase::Environment::get().getWindowManager()->getControllerTooltipVisible()) MWBase::Environment::get().getInputManager()->warpMouseToWidget(mAvailableButtons[0]); } } @@ -1058,7 +1058,7 @@ namespace MWGui else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK) { // Toggle info tooltip - winMgr->setControllerTooltip(!mRightColumn && !winMgr->getControllerTooltip()); + winMgr->setControllerTooltipEnabled(!winMgr->getControllerTooltipEnabled()); } else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) { @@ -1102,7 +1102,7 @@ namespace MWGui if (mAvailableFocus >= 0 && mAvailableFocus < static_cast(mAvailableButtons.size())) mAvailableButtons[mAvailableFocus]->setStateSelected(true); - winMgr->setControllerTooltip(Settings::gui().mControllerTooltips); + winMgr->setControllerTooltipVisible(Settings::gui().mControllerTooltips); } else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT && !mRightColumn && mEffectButtons.size() > 0) { @@ -1112,7 +1112,7 @@ namespace MWGui if (mEffectFocus >= 0 && mEffectFocus < static_cast(mEffectButtons.size())) mEffectButtons[mEffectFocus].first->setStateSelected(true); - winMgr->setControllerTooltip(false); + winMgr->setControllerTooltipVisible(false); } else return true; @@ -1129,7 +1129,7 @@ namespace MWGui if (!mRightColumn && mAvailableFocus >= 0 && mAvailableFocus < static_cast(mAvailableButtons.size())) { // Warp the mouse to the selected spell to show the tooltip - if (winMgr->getControllerTooltip()) + if (winMgr->getControllerTooltipVisible()) MWBase::Environment::get().getInputManager()->warpMouseToWidget(mAvailableButtons[mAvailableFocus]); } diff --git a/apps/openmw/mwgui/spellview.cpp b/apps/openmw/mwgui/spellview.cpp index ac923586dd..8c64c92ce6 100644 --- a/apps/openmw/mwgui/spellview.cpp +++ b/apps/openmw/mwgui/spellview.cpp @@ -350,6 +350,7 @@ namespace MWGui return; int prevFocus = mControllerFocus; + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); switch (button) { @@ -363,19 +364,22 @@ namespace MWGui break; case SDL_CONTROLLER_BUTTON_RIGHTSTICK: // Toggle info tooltip - MWBase::Environment::get().getWindowManager()->setControllerTooltip( - !MWBase::Environment::get().getWindowManager()->getControllerTooltip()); + winMgr->setControllerTooltipEnabled(!winMgr->getControllerTooltipEnabled()); break; case SDL_CONTROLLER_BUTTON_DPAD_UP: + winMgr->restoreControllerTooltips(); mControllerFocus--; break; case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + winMgr->restoreControllerTooltips(); mControllerFocus++; break; case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + winMgr->restoreControllerTooltips(); mControllerFocus = std::max(0, mControllerFocus - 10); break; case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + winMgr->restoreControllerTooltips(); mControllerFocus = std::min(mControllerFocus + 10, static_cast(mButtons.size()) - 1); break; case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: @@ -451,7 +455,10 @@ namespace MWGui mScrollView->setViewOffset(MyGUI::IntPoint(0, -lineHeight * (line - 5))); } - if (MWBase::Environment::get().getWindowManager()->getControllerTooltip()) + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); + winMgr->restoreControllerTooltips(); + + if (winMgr->getControllerTooltipVisible()) MWBase::Environment::get().getInputManager()->warpMouseToWidget(focused); } } diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 3b088ae518..01b4a94e93 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -328,7 +328,7 @@ namespace MWGui MyGUI::Window* window = mMainWidget->castType(); window->setCoord(x, active ? y : viewSize.height + 1, width, height); - MWBase::Environment::get().getWindowManager()->setControllerTooltip( + MWBase::Environment::get().getWindowManager()->setControllerTooltipVisible( active && Settings::gui().mControllerTooltips); } diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 7fd048a778..3abd238344 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -95,7 +95,7 @@ namespace MWGui if (guiMode) { - if (!winMgr->getCursorVisible() && !winMgr->getControllerTooltip()) + if (!winMgr->getCursorVisible() && !winMgr->getControllerTooltipVisible()) return; const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition(); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 960933ed51..15b5b20258 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -519,6 +519,8 @@ namespace MWGui auto inventoryTabsOverlay = std::make_unique(); mInventoryTabsOverlay = inventoryTabsOverlay.get(); mWindows.push_back(std::move(inventoryTabsOverlay)); + + mControllerTooltipEnabled = Settings::gui().mControllerTooltips; mActiveControllerWindows[GM_Inventory] = 1; // Start on Inventory page mInputBlocker = MyGUI::Gui::getInstance().createWidget( @@ -1496,7 +1498,7 @@ namespace MWGui if (Settings::gui().mControllerMenus) { if (mGuiModes.empty()) - setControllerTooltip(false); + setControllerTooltipVisible(false); else reapplyActiveControllerWindow(); } @@ -2640,12 +2642,29 @@ namespace MWGui return height; } - void WindowManager::setControllerTooltip(bool enabled) + void WindowManager::setControllerTooltipVisible(bool visible) { if (!Settings::gui().mControllerMenus) return; - mControllerTooltip = enabled; + mControllerTooltipVisible = visible; + } + + void WindowManager::setControllerTooltipEnabled(bool enabled) + { + if (!Settings::gui().mControllerMenus) + return; + + mControllerTooltipEnabled = enabled; + // When user toggles the setting, also update visibility + mControllerTooltipVisible = enabled; + } + + void WindowManager::restoreControllerTooltips() + { + // Restore tooltip visibility if user has them enabled but they were hidden by mouse movement + if (mControllerTooltipEnabled && !mControllerTooltipVisible) + setControllerTooltipVisible(true); } void WindowManager::updateControllerButtonsOverlay() diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index a62432e687..a9acaffcf0 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -395,8 +395,11 @@ namespace MWGui int getControllerMenuHeight() override; void cycleActiveControllerWindow(bool next) override; void setActiveControllerWindow(GuiMode mode, int activeIndex) override; - bool getControllerTooltip() const override { return mControllerTooltip; } - void setControllerTooltip(bool enabled) override; + bool getControllerTooltipVisible() const override { return mControllerTooltipVisible; } + void setControllerTooltipVisible(bool visible) override; + bool getControllerTooltipEnabled() const override { return mControllerTooltipEnabled; } + void setControllerTooltipEnabled(bool enabled) override; + void restoreControllerTooltips() override; void updateControllerButtonsOverlay() override; // Used in Lua bindings @@ -511,7 +514,10 @@ namespace MWGui std::vector mGuiModes; // The active window for controller mode for each GUI mode. std::map mActiveControllerWindows; - bool mControllerTooltip = false; + // Current tooltip visibility state (can be disabled by mouse movement) + bool mControllerTooltipVisible = false; + // User preference for tooltips (persists across mouse/controller switches) + bool mControllerTooltipEnabled = false; void reapplyActiveControllerWindow(); diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index c0a7dbbae0..b88c17edda 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -259,7 +259,7 @@ namespace MWInput { // When the inventory tooltip is visible, we don't actually want the A button to // act like a mouse button; it should act normally. - if (treatAsMouse && arg.button == SDL_CONTROLLER_BUTTON_A && winMgr->getControllerTooltip()) + if (treatAsMouse && arg.button == SDL_CONTROLLER_BUTTON_A && winMgr->getControllerTooltipVisible()) treatAsMouse = false; mGamepadGuiCursorEnabled = topWin->isGamepadCursorAllowed(); @@ -368,9 +368,9 @@ namespace MWInput && (arg.axis == SDL_CONTROLLER_AXIS_LEFTX || arg.axis == SDL_CONTROLLER_AXIS_LEFTY)) { // Treat the left stick like a cursor, which is the default behavior. - if (winMgr->getControllerTooltip()) + if (winMgr->getControllerTooltipVisible()) { - winMgr->setControllerTooltip(false); + winMgr->setControllerTooltipVisible(false); winMgr->setCursorVisible(true); } else if (mGamepadGuiCursorEnabled) diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index b17b92e118..ced69fbe79 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -32,6 +32,8 @@ namespace MWInput , mMouseWheel(0) , mMouseLookEnabled(false) , mGuiCursorEnabled(true) + , mLastWarpX(-1) + , mLastWarpY(-1) , mMouseMoveX(0) , mMouseMoveY(0) { @@ -72,13 +74,22 @@ namespace MWInput static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); winMgr->setCursorActive(true); + + // Check if this movement is from our recent mouse warp + bool isFromWarp = (mLastWarpX >= 0 && mLastWarpY >= 0 && std::abs(mGuiCursorX - mLastWarpX) < 0.5f + && std::abs(mGuiCursorY - mLastWarpY) < 0.5f); + if (Settings::gui().mControllerMenus && !winMgr->getCursorVisible() - && (std::abs(arg.xrel) > 1 || std::abs(arg.yrel) > 1)) + && (std::abs(arg.xrel) > 1 || std::abs(arg.yrel) > 1) && !isFromWarp) { // Unhide the cursor if it was hidden to show a controller tooltip. - winMgr->setControllerTooltip(false); + winMgr->setControllerTooltipVisible(false); winMgr->setCursorVisible(true); } + + // Clear warp tracking after processing + mLastWarpX = -1; + mLastWarpY = -1; } if (mMouseLookEnabled && !input->controlsDisabled()) @@ -280,6 +291,9 @@ namespace MWInput { mGuiCursorX = widgetX; mGuiCursorY = widgetY; + // Remember where we warped to so we can ignore movement from this warp + mLastWarpX = widgetX; + mLastWarpY = widgetY; warpMouse(); } } diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index 0a9c4eccd7..323703b56f 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -49,6 +49,8 @@ namespace MWInput int mMouseWheel; bool mMouseLookEnabled; bool mGuiCursorEnabled; + float mLastWarpX; + float mLastWarpY; int mMouseMoveX; int mMouseMoveY;