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

Merge branch 'bmdhacks-controller-deslect-bug' into 'master'

Controller tooltip display preferences survive mouse movement

See merge request OpenMW/openmw!4858
This commit is contained in:
psi29a 2025-09-09 21:00:56 +00:00
commit 9257beea4e
12 changed files with 97 additions and 33 deletions

View file

@ -392,8 +392,12 @@ namespace MWBase
/// Cycle to the next window to receive controller events /// Cycle to the next window to receive controller events
virtual void cycleActiveControllerWindow(bool next) = 0; virtual void cycleActiveControllerWindow(bool next) = 0;
virtual void setActiveControllerWindow(MWGui::GuiMode mode, int activeIndex) = 0; virtual void setActiveControllerWindow(MWGui::GuiMode mode, int activeIndex) = 0;
virtual bool getControllerTooltip() const = 0; virtual bool getControllerTooltipVisible() const = 0;
virtual void setControllerTooltip(bool enabled) = 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; virtual void updateControllerButtonsOverlay() = 0;
// Used in Lua bindings // Used in Lua bindings

View file

@ -190,7 +190,7 @@ namespace MWGui
{ {
mControllerActiveWindow = active; mControllerActiveWindow = active;
MWBase::Environment::get().getWindowManager()->setControllerTooltip( MWBase::Environment::get().getWindowManager()->setControllerTooltipVisible(
active && Settings::gui().mControllerTooltips); active && Settings::gui().mControllerTooltips);
if (active) if (active)
@ -205,6 +205,7 @@ namespace MWGui
return; return;
int prevFocus = mControllerFocus; int prevFocus = mControllerFocus;
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
switch (button) switch (button)
{ {
@ -218,27 +219,30 @@ namespace MWGui
break; break;
case SDL_CONTROLLER_BUTTON_RIGHTSTICK: case SDL_CONTROLLER_BUTTON_RIGHTSTICK:
// Toggle info tooltip // Toggle info tooltip
MWBase::Environment::get().getWindowManager()->setControllerTooltip( winMgr->setControllerTooltipEnabled(!winMgr->getControllerTooltipEnabled());
!MWBase::Environment::get().getWindowManager()->getControllerTooltip());
updateControllerFocus(-1, mControllerFocus); updateControllerFocus(-1, mControllerFocus);
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_UP: case SDL_CONTROLLER_BUTTON_DPAD_UP:
winMgr->restoreControllerTooltips();
if (mControllerFocus % mRows == 0) if (mControllerFocus % mRows == 0)
mControllerFocus = std::min(mControllerFocus + mRows - 1, mItemCount - 1); mControllerFocus = std::min(mControllerFocus + mRows - 1, mItemCount - 1);
else else
mControllerFocus--; mControllerFocus--;
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
winMgr->restoreControllerTooltips();
if (mControllerFocus % mRows == mRows - 1 || mControllerFocus == mItemCount - 1) if (mControllerFocus % mRows == mRows - 1 || mControllerFocus == mItemCount - 1)
mControllerFocus -= mControllerFocus % mRows; mControllerFocus -= mControllerFocus % mRows;
else else
mControllerFocus++; mControllerFocus++;
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
winMgr->restoreControllerTooltips();
if (mControllerFocus >= mRows) if (mControllerFocus >= mRows)
mControllerFocus -= mRows; mControllerFocus -= mRows;
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
winMgr->restoreControllerTooltips();
if (mControllerFocus + mRows < mItemCount) if (mControllerFocus + mRows < mItemCount)
mControllerFocus += mRows; mControllerFocus += mRows;
else if (mControllerFocus / mRows != (mItemCount - 1) / mRows) else if (mControllerFocus / mRows != (mItemCount - 1) / mRows)
@ -257,7 +261,7 @@ namespace MWGui
void ItemView::updateControllerFocus(int prevFocus, int newFocus) void ItemView::updateControllerFocus(int prevFocus, int newFocus)
{ {
MWBase::Environment::get().getWindowManager()->setCursorVisible( MWBase::Environment::get().getWindowManager()->setCursorVisible(
!MWBase::Environment::get().getWindowManager()->getControllerTooltip()); !MWBase::Environment::get().getWindowManager()->getControllerTooltipVisible());
if (!mItemCount) if (!mItemCount)
return; return;
@ -285,7 +289,10 @@ namespace MWGui
else else
mScrollView->setViewOffset(MyGUI::IntPoint(-42 * (column - 3), 0)); 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); MWBase::Environment::get().getInputManager()->warpMouseToWidget(focused);
} }
} }

View file

@ -151,8 +151,8 @@ namespace MWGui
mSpellButtons[0].first->setStateSelected(true); mSpellButtons[0].first->setStateSelected(true);
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
winMgr->setControllerTooltip(Settings::gui().mControllerTooltips); winMgr->setControllerTooltipVisible(Settings::gui().mControllerTooltips);
if (winMgr->getControllerTooltip()) if (winMgr->getControllerTooltipVisible())
MWBase::Environment::get().getInputManager()->warpMouseToWidget(mSpellButtons[0].first); MWBase::Environment::get().getInputManager()->warpMouseToWidget(mSpellButtons[0].first);
} }
} }
@ -230,6 +230,8 @@ namespace MWGui
bool SpellBuyingWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) bool SpellBuyingWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{ {
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
if (arg.button == SDL_CONTROLLER_BUTTON_A) if (arg.button == SDL_CONTROLLER_BUTTON_A)
{ {
if (mControllerFocus < mSpellButtons.size()) if (mControllerFocus < mSpellButtons.size())
@ -242,11 +244,12 @@ namespace MWGui
else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK) else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK)
{ {
// Toggle info tooltip // Toggle info tooltip
MWBase::Environment::get().getWindowManager()->setControllerTooltip( winMgr->setControllerTooltipEnabled(!winMgr->getControllerTooltipEnabled());
!MWBase::Environment::get().getWindowManager()->getControllerTooltip());
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{ {
winMgr->restoreControllerTooltips();
if (mSpellButtons.size() <= 1) if (mSpellButtons.size() <= 1)
return true; return true;
@ -256,6 +259,8 @@ namespace MWGui
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{ {
winMgr->restoreControllerTooltips();
if (mSpellButtons.size() <= 1) if (mSpellButtons.size() <= 1)
return true; return true;
@ -279,7 +284,7 @@ namespace MWGui
} }
// Warp the mouse to the selected spell to show the tooltip // 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); MWBase::Environment::get().getInputManager()->warpMouseToWidget(mSpellButtons[mControllerFocus].first);
} }

View file

@ -850,7 +850,7 @@ namespace MWGui
if (mAvailableButtons.size() > 0) if (mAvailableButtons.size() > 0)
{ {
mAvailableButtons[0]->setStateSelected(true); mAvailableButtons[0]->setStateSelected(true);
if (MWBase::Environment::get().getWindowManager()->getControllerTooltip()) if (MWBase::Environment::get().getWindowManager()->getControllerTooltipVisible())
MWBase::Environment::get().getInputManager()->warpMouseToWidget(mAvailableButtons[0]); MWBase::Environment::get().getInputManager()->warpMouseToWidget(mAvailableButtons[0]);
} }
} }
@ -1058,7 +1058,7 @@ namespace MWGui
else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK) else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK)
{ {
// Toggle info tooltip // Toggle info tooltip
winMgr->setControllerTooltip(!mRightColumn && !winMgr->getControllerTooltip()); winMgr->setControllerTooltipEnabled(!winMgr->getControllerTooltipEnabled());
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{ {
@ -1102,7 +1102,7 @@ namespace MWGui
if (mAvailableFocus >= 0 && mAvailableFocus < static_cast<int>(mAvailableButtons.size())) if (mAvailableFocus >= 0 && mAvailableFocus < static_cast<int>(mAvailableButtons.size()))
mAvailableButtons[mAvailableFocus]->setStateSelected(true); 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) 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<int>(mEffectButtons.size())) if (mEffectFocus >= 0 && mEffectFocus < static_cast<int>(mEffectButtons.size()))
mEffectButtons[mEffectFocus].first->setStateSelected(true); mEffectButtons[mEffectFocus].first->setStateSelected(true);
winMgr->setControllerTooltip(false); winMgr->setControllerTooltipVisible(false);
} }
else else
return true; return true;
@ -1129,7 +1129,7 @@ namespace MWGui
if (!mRightColumn && mAvailableFocus >= 0 && mAvailableFocus < static_cast<int>(mAvailableButtons.size())) if (!mRightColumn && mAvailableFocus >= 0 && mAvailableFocus < static_cast<int>(mAvailableButtons.size()))
{ {
// Warp the mouse to the selected spell to show the tooltip // Warp the mouse to the selected spell to show the tooltip
if (winMgr->getControllerTooltip()) if (winMgr->getControllerTooltipVisible())
MWBase::Environment::get().getInputManager()->warpMouseToWidget(mAvailableButtons[mAvailableFocus]); MWBase::Environment::get().getInputManager()->warpMouseToWidget(mAvailableButtons[mAvailableFocus]);
} }

View file

@ -350,6 +350,7 @@ namespace MWGui
return; return;
int prevFocus = mControllerFocus; int prevFocus = mControllerFocus;
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
switch (button) switch (button)
{ {
@ -363,19 +364,22 @@ namespace MWGui
break; break;
case SDL_CONTROLLER_BUTTON_RIGHTSTICK: case SDL_CONTROLLER_BUTTON_RIGHTSTICK:
// Toggle info tooltip // Toggle info tooltip
MWBase::Environment::get().getWindowManager()->setControllerTooltip( winMgr->setControllerTooltipEnabled(!winMgr->getControllerTooltipEnabled());
!MWBase::Environment::get().getWindowManager()->getControllerTooltip());
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_UP: case SDL_CONTROLLER_BUTTON_DPAD_UP:
winMgr->restoreControllerTooltips();
mControllerFocus--; mControllerFocus--;
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
winMgr->restoreControllerTooltips();
mControllerFocus++; mControllerFocus++;
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
winMgr->restoreControllerTooltips();
mControllerFocus = std::max(0, mControllerFocus - 10); mControllerFocus = std::max(0, mControllerFocus - 10);
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
winMgr->restoreControllerTooltips();
mControllerFocus = std::min(mControllerFocus + 10, static_cast<int>(mButtons.size()) - 1); mControllerFocus = std::min(mControllerFocus + 10, static_cast<int>(mButtons.size()) - 1);
break; break;
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
@ -451,7 +455,10 @@ namespace MWGui
mScrollView->setViewOffset(MyGUI::IntPoint(0, -lineHeight * (line - 5))); 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); MWBase::Environment::get().getInputManager()->warpMouseToWidget(focused);
} }
} }

View file

@ -328,7 +328,7 @@ namespace MWGui
MyGUI::Window* window = mMainWidget->castType<MyGUI::Window>(); MyGUI::Window* window = mMainWidget->castType<MyGUI::Window>();
window->setCoord(x, active ? y : viewSize.height + 1, width, height); window->setCoord(x, active ? y : viewSize.height + 1, width, height);
MWBase::Environment::get().getWindowManager()->setControllerTooltip( MWBase::Environment::get().getWindowManager()->setControllerTooltipVisible(
active && Settings::gui().mControllerTooltips); active && Settings::gui().mControllerTooltips);
} }

View file

@ -95,7 +95,7 @@ namespace MWGui
if (guiMode) if (guiMode)
{ {
if (!winMgr->getCursorVisible() && !winMgr->getControllerTooltip()) if (!winMgr->getCursorVisible() && !winMgr->getControllerTooltipVisible())
return; return;
const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition(); const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition();

View file

@ -519,6 +519,8 @@ namespace MWGui
auto inventoryTabsOverlay = std::make_unique<InventoryTabsOverlay>(); auto inventoryTabsOverlay = std::make_unique<InventoryTabsOverlay>();
mInventoryTabsOverlay = inventoryTabsOverlay.get(); mInventoryTabsOverlay = inventoryTabsOverlay.get();
mWindows.push_back(std::move(inventoryTabsOverlay)); mWindows.push_back(std::move(inventoryTabsOverlay));
mControllerTooltipEnabled = Settings::gui().mControllerTooltips;
mActiveControllerWindows[GM_Inventory] = 1; // Start on Inventory page mActiveControllerWindows[GM_Inventory] = 1; // Start on Inventory page
mInputBlocker = MyGUI::Gui::getInstance().createWidget<MyGUI::Widget>( mInputBlocker = MyGUI::Gui::getInstance().createWidget<MyGUI::Widget>(
@ -1496,7 +1498,7 @@ namespace MWGui
if (Settings::gui().mControllerMenus) if (Settings::gui().mControllerMenus)
{ {
if (mGuiModes.empty()) if (mGuiModes.empty())
setControllerTooltip(false); setControllerTooltipVisible(false);
else else
reapplyActiveControllerWindow(); reapplyActiveControllerWindow();
} }
@ -2640,12 +2642,29 @@ namespace MWGui
return height; return height;
} }
void WindowManager::setControllerTooltip(bool enabled) void WindowManager::setControllerTooltipVisible(bool visible)
{ {
if (!Settings::gui().mControllerMenus) if (!Settings::gui().mControllerMenus)
return; 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() void WindowManager::updateControllerButtonsOverlay()

View file

@ -395,8 +395,11 @@ namespace MWGui
int getControllerMenuHeight() override; int getControllerMenuHeight() override;
void cycleActiveControllerWindow(bool next) override; void cycleActiveControllerWindow(bool next) override;
void setActiveControllerWindow(GuiMode mode, int activeIndex) override; void setActiveControllerWindow(GuiMode mode, int activeIndex) override;
bool getControllerTooltip() const override { return mControllerTooltip; } bool getControllerTooltipVisible() const override { return mControllerTooltipVisible; }
void setControllerTooltip(bool enabled) override; void setControllerTooltipVisible(bool visible) override;
bool getControllerTooltipEnabled() const override { return mControllerTooltipEnabled; }
void setControllerTooltipEnabled(bool enabled) override;
void restoreControllerTooltips() override;
void updateControllerButtonsOverlay() override; void updateControllerButtonsOverlay() override;
// Used in Lua bindings // Used in Lua bindings
@ -511,7 +514,10 @@ namespace MWGui
std::vector<GuiMode> mGuiModes; std::vector<GuiMode> mGuiModes;
// The active window for controller mode for each GUI mode. // The active window for controller mode for each GUI mode.
std::map<GuiMode, int> mActiveControllerWindows; std::map<GuiMode, int> 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(); void reapplyActiveControllerWindow();

View file

@ -259,7 +259,7 @@ namespace MWInput
{ {
// When the inventory tooltip is visible, we don't actually want the A button to // When the inventory tooltip is visible, we don't actually want the A button to
// act like a mouse button; it should act normally. // 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; treatAsMouse = false;
mGamepadGuiCursorEnabled = topWin->isGamepadCursorAllowed(); mGamepadGuiCursorEnabled = topWin->isGamepadCursorAllowed();
@ -368,9 +368,9 @@ namespace MWInput
&& (arg.axis == SDL_CONTROLLER_AXIS_LEFTX || arg.axis == SDL_CONTROLLER_AXIS_LEFTY)) && (arg.axis == SDL_CONTROLLER_AXIS_LEFTX || arg.axis == SDL_CONTROLLER_AXIS_LEFTY))
{ {
// Treat the left stick like a cursor, which is the default behavior. // 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); winMgr->setCursorVisible(true);
} }
else if (mGamepadGuiCursorEnabled) else if (mGamepadGuiCursorEnabled)

View file

@ -32,6 +32,8 @@ namespace MWInput
, mMouseWheel(0) , mMouseWheel(0)
, mMouseLookEnabled(false) , mMouseLookEnabled(false)
, mGuiCursorEnabled(true) , mGuiCursorEnabled(true)
, mLastWarpX(-1)
, mLastWarpY(-1)
, mMouseMoveX(0) , mMouseMoveX(0)
, mMouseMoveY(0) , mMouseMoveY(0)
{ {
@ -72,13 +74,22 @@ namespace MWInput
static_cast<int>(mGuiCursorX), static_cast<int>(mGuiCursorY), mMouseWheel); static_cast<int>(mGuiCursorX), static_cast<int>(mGuiCursorY), mMouseWheel);
winMgr->setCursorActive(true); 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() 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. // Unhide the cursor if it was hidden to show a controller tooltip.
winMgr->setControllerTooltip(false); winMgr->setControllerTooltipVisible(false);
winMgr->setCursorVisible(true); winMgr->setCursorVisible(true);
} }
// Clear warp tracking after processing
mLastWarpX = -1;
mLastWarpY = -1;
} }
if (mMouseLookEnabled && !input->controlsDisabled()) if (mMouseLookEnabled && !input->controlsDisabled())
@ -280,6 +291,9 @@ namespace MWInput
{ {
mGuiCursorX = widgetX; mGuiCursorX = widgetX;
mGuiCursorY = widgetY; mGuiCursorY = widgetY;
// Remember where we warped to so we can ignore movement from this warp
mLastWarpX = widgetX;
mLastWarpY = widgetY;
warpMouse(); warpMouse();
} }
} }

View file

@ -49,6 +49,8 @@ namespace MWInput
int mMouseWheel; int mMouseWheel;
bool mMouseLookEnabled; bool mMouseLookEnabled;
bool mGuiCursorEnabled; bool mGuiCursorEnabled;
float mLastWarpX;
float mLastWarpY;
int mMouseMoveX; int mMouseMoveX;
int mMouseMoveY; int mMouseMoveY;