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.
This commit is contained in:
Ori Avtalion 2016-04-06 17:22:02 +03:00
parent 8fa543f58f
commit be1fdf59bb
5 changed files with 34 additions and 21 deletions

View File

@ -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;

View File

@ -119,6 +119,8 @@ void Dialog::reflowLayout() {
}
void Dialog::lostFocus() {
_dragWidget = NULL;
if (_tickleWidget) {
_tickleWidget->lostFocus();
}

View File

@ -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();

View File

@ -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

View File

@ -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