From be1fdf59bb80f963a4f97bfab49f59aca8d73d70 Mon Sep 17 00:00:00 2001 From: Ori Avtalion Date: Wed, 6 Apr 2016 17:22:02 +0300 Subject: [PATCH] GUI: When dialogs gain focus, inform them of the current mouse position Previously, they only reacted to the mouse position once it was moved. This meant that if the cursor was on a button that just gained focus, it did not highlight. Fixes #7101. --- gui/Tooltip.h | 3 ++- gui/dialog.cpp | 2 ++ gui/dialog.h | 2 +- gui/gui-manager.cpp | 40 +++++++++++++++++++++++----------------- gui/gui-manager.h | 8 ++++++-- 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/gui/Tooltip.h b/gui/Tooltip.h index 58b6d8a4298..60688412e60 100644 --- a/gui/Tooltip.h +++ b/gui/Tooltip.h @@ -41,6 +41,8 @@ public: void setup(Dialog *parent, Widget *widget, int x, int y); void drawDialog(); + + virtual void receivedFocus(int x = -1, int y = -1) {} protected: virtual void handleMouseDown(int x, int y, int button, int clickCount) { close(); @@ -64,7 +66,6 @@ protected: } virtual void handleMouseMoved(int x, int y, int button) { close(); - _parent->handleMouseMoved(x + (getAbsX() - _parent->getAbsX()), y + (getAbsY() - _parent->getAbsY()), button); } int _maxWidth; diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 315c24e9bf1..075a3bb5338 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -119,6 +119,8 @@ void Dialog::reflowLayout() { } void Dialog::lostFocus() { + _dragWidget = NULL; + if (_tickleWidget) { _tickleWidget->lostFocus(); } diff --git a/gui/dialog.h b/gui/dialog.h index 593ee134588..0e06effabd2 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -82,7 +82,7 @@ public: virtual void reflowLayout(); virtual void lostFocus(); - virtual void receivedFocus() {} + virtual void receivedFocus(int x = -1, int y = -1) { if (x >= 0 && y >= 0) handleMouseMoved(x, y, 0); } protected: virtual void open(); diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp index 4ddf62b2fe7..3ce8bee0207 100644 --- a/gui/gui-manager.cpp +++ b/gui/gui-manager.cpp @@ -281,15 +281,10 @@ void GuiManager::runLoop() { redraw(); } - _lastMousePosition.x = _lastMousePosition.y = -1; - _lastMousePosition.time = 0; - Common::EventManager *eventMan = _system->getEventManager(); uint32 lastRedraw = 0; const uint32 waitTime = 1000 / 60; - bool tooltipCheck = false; - while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) { redraw(); @@ -336,11 +331,6 @@ void GuiManager::runLoop() { processEvent(event, activeDialog); - if (event.type == Common::EVENT_MOUSEMOVE) { - tooltipCheck = true; - } - - if (lastRedraw + waitTime < _system->getMillis(true)) { lastRedraw = _system->getMillis(true); _theme->updateScreen(); @@ -348,7 +338,7 @@ void GuiManager::runLoop() { } } - if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis(true)) { + if (_lastMousePosition.time + kTooltipDelay < _system->getMillis(true)) { Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y); if (wdg && wdg->hasTooltip() && !(wdg->getFlags() & WIDGET_PRESSED)) { Tooltip *tooltip = new Tooltip(); @@ -415,7 +405,7 @@ void GuiManager::restoreState() { } void GuiManager::openDialog(Dialog *dialog) { - dialog->receivedFocus(); + giveFocusToDialog(dialog); if (!_dialogStack.empty()) getTopDialog()->lostFocus(); @@ -439,8 +429,10 @@ void GuiManager::closeTopDialog() { // Remove the dialog from the stack _dialogStack.pop()->lostFocus(); - if (!_dialogStack.empty()) - getTopDialog()->receivedFocus(); + if (!_dialogStack.empty()) { + Dialog *dialog = getTopDialog(); + giveFocusToDialog(dialog); + } if (_redrawStatus != kRedrawFull) _redrawStatus = kRedrawCloseDialog; @@ -515,6 +507,7 @@ void GuiManager::processEvent(const Common::Event &event, Dialog *const activeDi int button; uint32 time; Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); + switch (event.type) { case Common::EVENT_KEYDOWN: activeDialog->handleKeyDown(event.kbd); @@ -523,12 +516,12 @@ void GuiManager::processEvent(const Common::Event &event, Dialog *const activeDi activeDialog->handleKeyUp(event.kbd); break; case Common::EVENT_MOUSEMOVE: + _globalMousePosition.x = event.mouse.x; + _globalMousePosition.y = event.mouse.y; activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); if (mouse.x != _lastMousePosition.x || mouse.y != _lastMousePosition.y) { - _lastMousePosition.x = mouse.x; - _lastMousePosition.y = mouse.y; - _lastMousePosition.time = _system->getMillis(true); + setLastMousePos(mouse.x, mouse.y); } break; @@ -571,4 +564,17 @@ void GuiManager::processEvent(const Common::Event &event, Dialog *const activeDi } } +void GuiManager::giveFocusToDialog(Dialog *dialog) { + int16 dialogX = _globalMousePosition.x - dialog->_x; + int16 dialogY = _globalMousePosition.y - dialog->_y; + dialog->receivedFocus(dialogX, dialogY); + setLastMousePos(dialogX, dialogY); +} + +void GuiManager::setLastMousePos(int16 x, int16 y) { + _lastMousePosition.x = x; + _lastMousePosition.y = y; + _lastMousePosition.time = _system->getMillis(true); +} + } // End of namespace GUI diff --git a/gui/gui-manager.h b/gui/gui-manager.h index 26c8d6def9d..35779215b27 100644 --- a/gui/gui-manager.h +++ b/gui/gui-manager.h @@ -124,11 +124,12 @@ protected: bool _useStdCursor; // position and time of last mouse click (used to detect double clicks) - struct { + struct MousePos { + MousePos() : x(-1), y(-1), count(0) { time = 0; } int16 x, y; // Position of mouse when the click occurred uint32 time; // Time int count; // How often was it already pressed? - } _lastClick, _lastMousePosition; + } _lastClick, _lastMousePosition, _globalMousePosition; // mouse cursor state int _cursorAnimateCounter; @@ -155,6 +156,9 @@ protected: Dialog *getTopDialog() const; void screenChange(); + + void giveFocusToDialog(Dialog *dialog); + void setLastMousePos(int16 x, int16 y); }; } // End of namespace GUI