From dc0c7bf845be37df7a069f3f1610ab5c42f4bff4 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Fri, 19 Dec 2003 16:50:03 +0000 Subject: Implemented scroll wheel handling for save/load dialogs. (This turned up a few other hitherto harmless bugs, which I've hopefully managed to fix.) svn-id: r11762 --- sword2/controls.cpp | 193 ++++++++++++++++++++++++++++++----------------- sword2/driver/_mouse.cpp | 6 +- sword2/driver/driver96.h | 4 +- sword2/driver/rdwin.cpp | 6 ++ 4 files changed, 136 insertions(+), 73 deletions(-) diff --git a/sword2/controls.cpp b/sword2/controls.cpp index 8e500d5e7c..f05083260e 100644 --- a/sword2/controls.cpp +++ b/sword2/controls.cpp @@ -106,6 +106,8 @@ public: virtual void onMouseMove(int x, int y) {} virtual void onMouseDown(int x, int y) {} virtual void onMouseUp(int x, int y) {} + virtual void onWheelUp(int x, int y) {} + virtual void onWheelDown(int x, int y) {} virtual void onKey(_keyboardEvent *ke) {} virtual void onTick() {} @@ -297,34 +299,66 @@ int Dialog::run() { setResult(1); } + int oldHit = -1; + int newHit = -1; + + // Find out which widget the mouse was over the last time, and + // which it is currently over. This assumes the widgets do not + // overlap. + for (i = 0; i < _numWidgets; i++) { - bool oldHit = _widgets[i]->isHit(oldMouseX, oldMouseY); - bool newHit = _widgets[i]->isHit(newMouseX, newMouseY); - - if (!oldHit && newHit) - _widgets[i]->onMouseEnter(); - if (oldHit && !newHit) - _widgets[i]->onMouseExit(); - if (_gui->_vm->_input->_mouseX != oldMouseX || _gui->_vm->_input->_mouseY != oldMouseY) - _widgets[i]->onMouseMove(newMouseX, newMouseY); + if (_widgets[i]->isHit(oldMouseX, oldMouseY)) + oldHit = i; + if (_widgets[i]->isHit(newMouseX, newMouseY)) + newHit = i; + } + + // Was the mouse inside a widget the last time? + + if (oldHit >= 0) { + if (newHit != oldHit) + _widgets[oldHit]->onMouseExit(); + } + + // Is the mouse currently in a widget? + + if (newHit >= 0) { + if (newHit != oldHit) + _widgets[newHit]->onMouseEnter(); if (me) { switch (me->buttons) { case RD_LEFTBUTTONDOWN: - if (newHit) - _widgets[i]->onMouseDown(newMouseX, newMouseY); + _widgets[newHit]->onMouseDown(newMouseX, newMouseY); break; case RD_LEFTBUTTONUP: - if (newHit) - _widgets[i]->onMouseUp(newMouseX, newMouseY); - // So that slider widgets will know - // when the user releases the mouse - // button, even if the cursor is - // outside of the slider's hit area. - _widgets[i]->releaseMouse(newMouseX, newMouseY); + _widgets[newHit]->onMouseUp(newMouseX, newMouseY); + break; + case RD_WHEELUP: + _widgets[newHit]->onWheelUp(newMouseX, newMouseY); + break; + case RD_WHEELDOWN: + _widgets[newHit]->onWheelDown(newMouseX, newMouseY); break; } } + } + + // Some events are passed to the widgets regardless of where + // the mouse cursor is. + + for (i = 0; i < _numWidgets; i++) { + if (me && me->buttons == RD_LEFTBUTTONUP) { + // So that slider widgets will know when the + // user releases the mouse button, even if the + // cursor is outside of the slider's hit area. + _widgets[i]->releaseMouse(newMouseX, newMouseY); + } + + // This is to make it easier to drag the slider widget + + if (newMouseX != oldMouseX || newMouseY != oldMouseY) + _widgets[i]->onMouseMove(newMouseX, newMouseY); if (keyboardStatus == RD_OK) _widgets[i]->onKey(&ke); @@ -957,11 +991,15 @@ enum { kLoadDialog }; +// Slot button actions. Note that keyboard input generates positive actions + enum { kSelectSlot = -1, kDeselectSlot = -2, - kStartEditing = 0, - kCursorTick = 1 + kWheelDown = -3, + kWheelUp = -4, + kStartEditing = -5, + kCursorTick = -6 }; class Slot : public Widget { @@ -1031,6 +1069,14 @@ public: } } + virtual void onWheelUp(int x, int y) { + _parent->onAction(this, kWheelUp); + } + + virtual void onWheelDown(int x, int y) { + _parent->onAction(this, kWheelDown); + } + virtual void onKey(_keyboardEvent *ke) { if (_editable) { if (ke->keycode == 8) @@ -1206,61 +1252,24 @@ public: setResult(0); } else { Slot *slot = (Slot *) widget; + int textWidth; + char tmp; + int i; - if (result >= kStartEditing) { - if (result == kStartEditing) { - if (_selectedSlot >= 10) - _firstPos = 5; - else - _firstPos = 4; - - strcpy(_editBuffer, slot->getText()); - _editPos = strlen(_editBuffer); - _cursorTick = 0; - _editBuffer[_editPos] = '_'; - _editBuffer[_editPos + 1] = 0; - slot->setEditable(true); - drawEditBuffer(slot); - } else if (result == kCursorTick) { - _cursorTick++; - if (_cursorTick == 7) { - _editBuffer[_editPos] = ' '; - drawEditBuffer(slot); - } else if (_cursorTick == 14) { - _cursorTick = 0; - _editBuffer[_editPos] = '_'; - drawEditBuffer(slot); - } - } else if (result == 8) { - if (_editPos > _firstPos) { - _editBuffer[_editPos - 1] = _editBuffer[_editPos]; - _editBuffer[_editPos--] = 0; - drawEditBuffer(slot); - } - } else { - int textWidth; - char tmp; - - tmp = _editBuffer[_editPos]; - _editBuffer[_editPos] = 0; - textWidth = _fr2->getTextWidth(_editBuffer); - _editBuffer[_editPos] = tmp; - - if (textWidth < 340 && _editPos < SAVE_DESCRIPTION_LEN - 2) { - _editBuffer[_editPos + 1] = _editBuffer[_editPos]; - _editBuffer[_editPos + 2] = 0; - _editBuffer[_editPos++] = result; - drawEditBuffer(slot); - } - } - } else { + switch (result) { + case kWheelUp: + onAction(_upButton); + break; + case kWheelDown: + onAction(_downButton); + break; + case kSelectSlot: + case kDeselectSlot: if (result == kSelectSlot) _selectedSlot = _gui->_baseSlot + (slot->getY() - 72) / 35; else if (result == kDeselectSlot) _selectedSlot = -1; - int i; - for (i = 0; i < 8; i++) if (widget == _slotButton[i]) break; @@ -1271,6 +1280,52 @@ public: _slotButton[j]->setState(0); } } + break; + case kStartEditing: + if (_selectedSlot >= 10) + _firstPos = 5; + else + _firstPos = 4; + + strcpy(_editBuffer, slot->getText()); + _editPos = strlen(_editBuffer); + _cursorTick = 0; + _editBuffer[_editPos] = '_'; + _editBuffer[_editPos + 1] = 0; + slot->setEditable(true); + drawEditBuffer(slot); + break; + case kCursorTick: + _cursorTick++; + if (_cursorTick == 7) { + _editBuffer[_editPos] = ' '; + drawEditBuffer(slot); + } else if (_cursorTick == 14) { + _cursorTick = 0; + _editBuffer[_editPos] = '_'; + drawEditBuffer(slot); + } + break; + case 8: + if (_editPos > _firstPos) { + _editBuffer[_editPos - 1] = _editBuffer[_editPos]; + _editBuffer[_editPos--] = 0; + drawEditBuffer(slot); + } + break; + default: + tmp = _editBuffer[_editPos]; + _editBuffer[_editPos] = 0; + textWidth = _fr2->getTextWidth(_editBuffer); + _editBuffer[_editPos] = tmp; + + if (textWidth < 340 && _editPos < SAVE_DESCRIPTION_LEN - 2) { + _editBuffer[_editPos + 1] = _editBuffer[_editPos]; + _editBuffer[_editPos + 2] = 0; + _editBuffer[_editPos++] = result; + drawEditBuffer(slot); + } + break; } } } diff --git a/sword2/driver/_mouse.cpp b/sword2/driver/_mouse.cpp index d516c81093..a53feb448c 100644 --- a/sword2/driver/_mouse.cpp +++ b/sword2/driver/_mouse.cpp @@ -25,9 +25,9 @@ namespace Sword2 { #define MOUSEFLASHFRAME 6 /** - * Logs the mouse button event passed in buttons. The button events are - * defined as RD_LEFTBUTTONDOWN, RD_LEFTBUTTONUP, RD_RIGHTBUTTONDOWN and - * RD_RIGHTBUTTONUP. + * Logs the mouse button event passed in buttons. The button events were + * originaly defined as RD_LEFTBUTTONDOWN, RD_LEFTBUTTONUP, RD_RIGHTBUTTONDOWN + * and RD_RIGHTBUTTONUP. ScummVM adds RD_WHEELDOWN and RD_WHEELUP. */ void Input::logMouseEvent(uint16 buttons) { diff --git a/sword2/driver/driver96.h b/sword2/driver/driver96.h index 8c35ef9ed1..b30370e3eb 100644 --- a/sword2/driver/driver96.h +++ b/sword2/driver/driver96.h @@ -83,7 +83,9 @@ enum { RD_LEFTBUTTONDOWN = 0x01, RD_LEFTBUTTONUP = 0x02, RD_RIGHTBUTTONDOWN = 0x04, - RD_RIGHTBUTTONUP = 0x08 + RD_RIGHTBUTTONUP = 0x08, + RD_WHEELUP = 0x10, + RD_WHEELDOWN = 0x20 }; // Sprite defines diff --git a/sword2/driver/rdwin.cpp b/sword2/driver/rdwin.cpp index 4442c79c3d..142e7059c5 100644 --- a/sword2/driver/rdwin.cpp +++ b/sword2/driver/rdwin.cpp @@ -51,6 +51,12 @@ void Input::parseEvents(void) { case OSystem::EVENT_RBUTTONUP: logMouseEvent(RD_RIGHTBUTTONUP); break; + case OSystem::EVENT_WHEELUP: + logMouseEvent(RD_WHEELUP); + break; + case OSystem::EVENT_WHEELDOWN: + logMouseEvent(RD_WHEELDOWN); + break; case OSystem::EVENT_QUIT: _vm->closeGame(); break; -- cgit v1.2.3