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
This commit is contained in:
Torbjörn Andersson 2003-12-19 16:50:03 +00:00
parent 34433d87bb
commit dc0c7bf845
4 changed files with 136 additions and 73 deletions

View File

@ -106,6 +106,8 @@ public:
virtual void onMouseMove(int x, int y) {} virtual void onMouseMove(int x, int y) {}
virtual void onMouseDown(int x, int y) {} virtual void onMouseDown(int x, int y) {}
virtual void onMouseUp(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 onKey(_keyboardEvent *ke) {}
virtual void onTick() {} virtual void onTick() {}
@ -297,34 +299,66 @@ int Dialog::run() {
setResult(1); setResult(1);
} }
for (i = 0; i < _numWidgets; i++) { int oldHit = -1;
bool oldHit = _widgets[i]->isHit(oldMouseX, oldMouseY); int newHit = -1;
bool newHit = _widgets[i]->isHit(newMouseX, newMouseY);
if (!oldHit && newHit) // Find out which widget the mouse was over the last time, and
_widgets[i]->onMouseEnter(); // which it is currently over. This assumes the widgets do not
if (oldHit && !newHit) // overlap.
_widgets[i]->onMouseExit();
if (_gui->_vm->_input->_mouseX != oldMouseX || _gui->_vm->_input->_mouseY != oldMouseY) for (i = 0; i < _numWidgets; i++) {
_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) { if (me) {
switch (me->buttons) { switch (me->buttons) {
case RD_LEFTBUTTONDOWN: case RD_LEFTBUTTONDOWN:
if (newHit) _widgets[newHit]->onMouseDown(newMouseX, newMouseY);
_widgets[i]->onMouseDown(newMouseX, newMouseY);
break; break;
case RD_LEFTBUTTONUP: case RD_LEFTBUTTONUP:
if (newHit) _widgets[newHit]->onMouseUp(newMouseX, newMouseY);
_widgets[i]->onMouseUp(newMouseX, newMouseY); break;
// So that slider widgets will know case RD_WHEELUP:
// when the user releases the mouse _widgets[newHit]->onWheelUp(newMouseX, newMouseY);
// button, even if the cursor is break;
// outside of the slider's hit area. case RD_WHEELDOWN:
_widgets[i]->releaseMouse(newMouseX, newMouseY); _widgets[newHit]->onWheelDown(newMouseX, newMouseY);
break; 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) if (keyboardStatus == RD_OK)
_widgets[i]->onKey(&ke); _widgets[i]->onKey(&ke);
@ -957,11 +991,15 @@ enum {
kLoadDialog kLoadDialog
}; };
// Slot button actions. Note that keyboard input generates positive actions
enum { enum {
kSelectSlot = -1, kSelectSlot = -1,
kDeselectSlot = -2, kDeselectSlot = -2,
kStartEditing = 0, kWheelDown = -3,
kCursorTick = 1 kWheelUp = -4,
kStartEditing = -5,
kCursorTick = -6
}; };
class Slot : public Widget { 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) { virtual void onKey(_keyboardEvent *ke) {
if (_editable) { if (_editable) {
if (ke->keycode == 8) if (ke->keycode == 8)
@ -1206,61 +1252,24 @@ public:
setResult(0); setResult(0);
} else { } else {
Slot *slot = (Slot *) widget; Slot *slot = (Slot *) widget;
int textWidth;
char tmp;
int i;
if (result >= kStartEditing) { switch (result) {
if (result == kStartEditing) { case kWheelUp:
if (_selectedSlot >= 10) onAction(_upButton);
_firstPos = 5; break;
else case kWheelDown:
_firstPos = 4; onAction(_downButton);
break;
strcpy(_editBuffer, slot->getText()); case kSelectSlot:
_editPos = strlen(_editBuffer); case kDeselectSlot:
_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 {
if (result == kSelectSlot) if (result == kSelectSlot)
_selectedSlot = _gui->_baseSlot + (slot->getY() - 72) / 35; _selectedSlot = _gui->_baseSlot + (slot->getY() - 72) / 35;
else if (result == kDeselectSlot) else if (result == kDeselectSlot)
_selectedSlot = -1; _selectedSlot = -1;
int i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
if (widget == _slotButton[i]) if (widget == _slotButton[i])
break; break;
@ -1271,6 +1280,52 @@ public:
_slotButton[j]->setState(0); _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;
} }
} }
} }

View File

@ -25,9 +25,9 @@ namespace Sword2 {
#define MOUSEFLASHFRAME 6 #define MOUSEFLASHFRAME 6
/** /**
* Logs the mouse button event passed in buttons. The button events are * Logs the mouse button event passed in buttons. The button events were
* defined as RD_LEFTBUTTONDOWN, RD_LEFTBUTTONUP, RD_RIGHTBUTTONDOWN and * originaly defined as RD_LEFTBUTTONDOWN, RD_LEFTBUTTONUP, RD_RIGHTBUTTONDOWN
* RD_RIGHTBUTTONUP. * and RD_RIGHTBUTTONUP. ScummVM adds RD_WHEELDOWN and RD_WHEELUP.
*/ */
void Input::logMouseEvent(uint16 buttons) { void Input::logMouseEvent(uint16 buttons) {

View File

@ -83,7 +83,9 @@ enum {
RD_LEFTBUTTONDOWN = 0x01, RD_LEFTBUTTONDOWN = 0x01,
RD_LEFTBUTTONUP = 0x02, RD_LEFTBUTTONUP = 0x02,
RD_RIGHTBUTTONDOWN = 0x04, RD_RIGHTBUTTONDOWN = 0x04,
RD_RIGHTBUTTONUP = 0x08 RD_RIGHTBUTTONUP = 0x08,
RD_WHEELUP = 0x10,
RD_WHEELDOWN = 0x20
}; };
// Sprite defines // Sprite defines

View File

@ -51,6 +51,12 @@ void Input::parseEvents(void) {
case OSystem::EVENT_RBUTTONUP: case OSystem::EVENT_RBUTTONUP:
logMouseEvent(RD_RIGHTBUTTONUP); logMouseEvent(RD_RIGHTBUTTONUP);
break; break;
case OSystem::EVENT_WHEELUP:
logMouseEvent(RD_WHEELUP);
break;
case OSystem::EVENT_WHEELDOWN:
logMouseEvent(RD_WHEELDOWN);
break;
case OSystem::EVENT_QUIT: case OSystem::EVENT_QUIT:
_vm->closeGame(); _vm->closeGame();
break; break;