diff options
author | Borja Lorente | 2016-07-02 17:11:42 +0200 |
---|---|---|
committer | Borja Lorente | 2016-08-14 18:45:01 +0200 |
commit | 541702206889519515f20c42dd10aaba70630db1 (patch) | |
tree | a216de637dceb1b6c6a7faea8a9c733e98bf4082 | |
parent | a6e1202a0c95c8124536504cf1dee81970ae74bb (diff) | |
download | scummvm-rg350-541702206889519515f20c42dd10aaba70630db1.tar.gz scummvm-rg350-541702206889519515f20c42dd10aaba70630db1.tar.bz2 scummvm-rg350-541702206889519515f20c42dd10aaba70630db1.zip |
MACVENTURE: Add double click support
-rw-r--r-- | engines/macventure/gui.cpp | 76 | ||||
-rw-r--r-- | engines/macventure/gui.h | 110 | ||||
-rw-r--r-- | engines/macventure/macventure.cpp | 55 | ||||
-rw-r--r-- | engines/macventure/macventure.h | 3 |
4 files changed, 209 insertions, 35 deletions
diff --git a/engines/macventure/gui.cpp b/engines/macventure/gui.cpp index f07b914d26..dc0c4afb09 100644 --- a/engines/macventure/gui.cpp +++ b/engines/macventure/gui.cpp @@ -26,7 +26,7 @@ #include "macventure/macventure.h" #include "macventure/gui.h" -// For the dragged object +#include "common/timer.h" #include "common/system.h" namespace MacVenture { @@ -81,6 +81,12 @@ static const Graphics::MenuData menuSubItems[] = { { 0, NULL, 0, 0, false } }; + +static void cursorTimerHandler(void *refCon) { + Gui *gui = (Gui *)refCon; + gui->processCursorTick(); +} + bool commandsWindowCallback(Graphics::WindowClick, Common::Event &event, void *gui); bool mainGameWindowCallback(Graphics::WindowClick, Common::Event &event, void *gui); bool outConsoleWindowCallback(Graphics::WindowClick, Common::Event &event, void *gui); @@ -99,6 +105,9 @@ Gui::Gui(MacVentureEngine *engine, Common::MacResManager *resman) { _draggedObj.id = 0; _draggedObj.pos = Common::Point(0, 0); + _cursor = new Cursor(this); + g_system->getTimerManager()->installTimerProc(&cursorTimerHandler, 1000000, this, "macVentureCursor"); + initGUI(); } @@ -113,6 +122,9 @@ Gui::~Gui() { if (_exitsData) delete _exitsData; + if (_cursor) + delete _cursor; + Common::HashMap<ObjID, ImageAsset*>::const_iterator it = _assets.begin(); for (; it != _assets.end(); it++) { delete it->_value; @@ -654,7 +666,7 @@ void Gui::drawObjectsInWindow(WindowReference target, Graphics::ManagedSurface * if (_engine->isObjSelected(child)) _assets[child]->blitInto( - surface, pos.x, pos.y, kBlitXOR); + surface, pos.x, pos.y, kBlitOR); // For test surface->frameRect(Common::Rect( @@ -796,6 +808,16 @@ void Gui::updateExit(ObjID obj) { } +WindowReference Gui::findWindowAtPoint(Common::Point point) { + Common::List<WindowData>::iterator it; + for (it = _windowData->begin(); it != _windowData->end(); it++) { + if (it->bounds.contains(point) && it->refcon != kDiplomaWindow) { //HACK, diploma should be cosnidered + return it->refcon; + } + } + return kNoWindow; +} + Common::Point Gui::getWindowSurfacePos(WindowReference reference) { const WindowData &data = getWindowData(reference); BorderBounds border = borderBounds(data.type); @@ -845,7 +867,6 @@ void Gui::checkSelect(ObjID obj, const Common::Event &event, const Common::Rect isRectInsideObject(clickRect, obj)) { selectDraggable(obj, ref, event.mouse); - _engine->handleObjectSelect(obj, (WindowReference)ref, event, false); } } @@ -873,19 +894,22 @@ bool Gui::isRectInsideObject(Common::Rect target, ObjID obj) { void Gui::selectDraggable(ObjID child, WindowReference origin, Common::Point startPos) { if (_engine->isObjClickable(child)) { + _draggedObj.hasMoved = false; _draggedObj.id = child; _draggedObj.mouseOffset = (_engine->getObjPosition(child) + getWindowSurfacePos(origin)) - startPos; _draggedObj.pos = startPos + _draggedObj.mouseOffset; } } -void Gui::handleDragRelease(Common::Point pos) { +void Gui::handleDragRelease(Common::Point pos, bool shiftPressed, bool isDoubleClick) { + WindowReference destinationWindow = findWindowAtPoint(pos); + if (_draggedObj.hasMoved) { + ObjID destObject = getWindowData(destinationWindow).objRef; + _engine->handleObjectDrop(_draggedObj.id, pos, destObject); //change pos to validate + } else { + _engine->handleObjectSelect(_draggedObj.id, destinationWindow, shiftPressed, isDoubleClick); + } _draggedObj.id = 0; - _engine->updateDelta(pos); - _engine->selectControl(kControlOperate); - _engine->activateCommand(kControlOperate); - _engine->refreshReady(); - _engine->preparedToRun(); } Common::Rect Gui::calculateClickRect(Common::Point clickPos, Common::Rect windowBounds) { @@ -1026,9 +1050,13 @@ uint Gui::getObjHeight(ObjID obj) { bool Gui::processEvent(Common::Event &event) { bool processed = false; + + processed |= _cursor->processEvent(event); + if (event.type == Common::EVENT_MOUSEMOVE) { if (_draggedObj.id != 0) { _draggedObj.pos = event.mouse + _draggedObj.mouseOffset; + _draggedObj.hasMoved = true; } processed = true; @@ -1038,12 +1066,6 @@ bool Gui::processEvent(Common::Event &event) { g_system->copyRectToScreen(_screen.getPixels(), _screen.pitch, 0, 0, _screen.w, _screen.h); g_system->updateScreen(); } - else if (event.type == Common::EVENT_LBUTTONUP) { - if (_draggedObj.id != 0) { - handleDragRelease(event.mouse); - } - processed = true; - } processed |= _wm.processEvent(event); return (processed); @@ -1113,7 +1135,7 @@ bool MacVenture::Gui::processSelfEvents(WindowClick click, Common::Event & event return true; if (event.type == Common::EVENT_LBUTTONUP) { - _engine->handleObjectSelect(1, kSelfWindow, event, false); + _engine->handleObjectSelect(1, kSelfWindow, false, false); } return true; } @@ -1143,7 +1165,7 @@ bool MacVenture::Gui::processExitsEvents(WindowClick click, Common::Event & even } } - _engine->handleObjectSelect(data.getData().refcon, kExitsWindow, event, false); + _engine->handleObjectSelect(data.getData().refcon, kExitsWindow, false, false); } return getWindowData(kExitsWindow).visible; } @@ -1183,6 +1205,26 @@ bool Gui::processInventoryEvents(WindowClick click, Common::Event & event) { return true; } +void Gui::processCursorTick() { + _cursor->tick(); + + + + + + handleDragRelease(_draggedObj.pos, false, true); + +} + +void Gui::handleSingleClick(Common::Point pos) { + //handleDragRelease(_draggedObj.pos, false, false); + debug("Single Click"); +} + +void Gui::handleDoubleClick(Common::Point pos) { + debug("Double Click"); +} + /* Ugly switches */ BorderBounds Gui::borderBounds(MVWindowType type) { diff --git a/engines/macventure/gui.h b/engines/macventure/gui.h index f93e8db42b..75bb1e64a5 100644 --- a/engines/macventure/gui.h +++ b/engines/macventure/gui.h @@ -39,6 +39,7 @@ using namespace Graphics::MacWindowConstants; class MacVentureEngine; typedef uint32 ObjID; +class Cursor; class CommandButton; class ImageAsset; @@ -151,6 +152,14 @@ struct DraggedObj { bool hasMoved; }; +enum CursorState { + // HACK, I should define a proper FSM for this + kCursorIdle, + kCursorSingleClick, // Triggered when mouse goes up + kCursorSingleClickAwait, // Triggered when we are in single click and mouse goes down + kCursorSingleClickTrap, // Trap state, for when we are in await, and the timer goes off + kCursorDoubleClick +}; class Gui { @@ -183,12 +192,18 @@ public: bool processDiplomaEvents(WindowClick click, Common::Event &event); bool processInventoryEvents(WindowClick click, Common::Event &event); + void processCursorTick(); + //bool processClickObject(ObjID obj, WindowReference win, Common::Event event, bool canDrag); const WindowData& getWindowData(WindowReference reference); const Graphics::Font& getCurrentFont(); + // Clicks + void handleSingleClick(Common::Point pos); + void handleDoubleClick(Common::Point pos); + // Modifiers void bringToFront(WindowReference window); void setWindowTitle(WindowReference winID, Common::String string); @@ -230,6 +245,8 @@ private: // Attributes Graphics::ManagedSurface _draggedSurface; DraggedObj _draggedObj; + Cursor *_cursor; + private: // Methods // Initializers @@ -257,6 +274,7 @@ private: // Methods void drawWindowTitle(WindowReference target, Graphics::ManagedSurface *surface); // Finders + WindowReference findWindowAtPoint(Common::Point point); Common::Point getWindowSurfacePos(WindowReference reference); WindowData& findWindowData(WindowReference reference); Graphics::MacWindow *findWindow(WindowReference reference); @@ -265,11 +283,101 @@ private: // Methods void checkSelect(ObjID obj, const Common::Event &event, const Common::Rect &clickRect, WindowReference ref); bool isRectInsideObject(Common::Rect target, ObjID obj); void selectDraggable(ObjID child, WindowReference origin, Common::Point startPos); - void handleDragRelease(Common::Point pos); + void handleDragRelease(Common::Point pos, bool shiftPressed, bool isDoubleClick); Common::Rect calculateClickRect(Common::Point clickPos, Common::Rect windowBounds); }; +class Cursor { +enum ClickState { + kCursorIdle = 0, + kCursorSC = 1, + kCursorNoTick = 2, + kCursorSCTrans = 3, + kCursorExecSC = 4, + kCursorExecDC = 5, + kCursorStateCount +}; + +enum CursorInput { // Columns for the FSM transition table + kTickCol = 0, + kButtonDownCol = 1, + kButtonUpCol = 2, + kCursorInputCount +}; + + +ClickState _transitionTable[kCursorStateCount][kCursorInputCount] = { + /* kCursorIdle */ {kCursorIdle, kCursorIdle, kCursorSC }, + /* kCursorSC */ {kCursorExecSC, kCursorSCTrans, kCursorExecDC }, + /* IgnoreTick */ {kCursorNoTick, kCursorNoTick, kCursorExecSC }, + /* SC Transition */ {kCursorNoTick, kCursorNoTick, kCursorExecDC }, + /* Exec SC */ {kCursorIdle, kCursorExecSC, kCursorExecSC }, // Trap state + /* Exec DC */ {kCursorIdle, kCursorExecDC, kCursorExecDC } // Trap state +}; + +public: + Cursor(Gui *gui) { + _gui = gui; + _state = kCursorIdle; + } + + ~Cursor() {} + + void tick() { + executeState(); + changeState(kTickCol); + } + + bool processEvent(const Common::Event &event) { + executeState(); + + if (event.type == Common::EVENT_MOUSEMOVE) { + _pos = event.mouse; + return true; + } + if (event.type == Common::EVENT_LBUTTONDOWN) { + changeState(kButtonDownCol); + return true; + } + if (event.type == Common::EVENT_LBUTTONUP) { + changeState(kButtonUpCol); + return true; + } + + return false; + } + + Common::Point getPos() { + return _pos; + } + +private: + + void changeState(CursorInput input) { + debug("Change cursor state: [%d] -> [%d]", _state, _transitionTable[_state][input]); + _state = _transitionTable[_state][input]; + } + + void executeState() { + if (_state == kCursorExecSC) { + _gui->handleSingleClick(_pos); + changeState(kTickCol); + } else if (_state == kCursorExecDC) { + _gui->handleDoubleClick(_pos); + changeState(kTickCol); + } + } + + +private: + Gui *_gui; + + Common::Point _pos; + ClickState _state; + +}; + class CommandButton { enum { diff --git a/engines/macventure/macventure.cpp b/engines/macventure/macventure.cpp index b26250a5bf..1578c57011 100644 --- a/engines/macventure/macventure.cpp +++ b/engines/macventure/macventure.cpp @@ -280,7 +280,7 @@ bool MacVentureEngine::printTexts() { return false; } -void MacVentureEngine::handleObjectSelect(ObjID objID, WindowReference win, Common::Event event, bool isDoubleClick) { +void MacVentureEngine::handleObjectSelect(ObjID objID, WindowReference win, bool shiftPressed, bool isDoubleClick) { if (win == kExitsWindow) { win = kMainGameWindow; } @@ -289,7 +289,7 @@ void MacVentureEngine::handleObjectSelect(ObjID objID, WindowReference win, Comm const WindowData &windata = _gui->getWindowData(win); - if (event.kbd.flags & Common::KBD_SHIFT) { + if (shiftPressed) { // Do shift ;) } else { if (_selectedControl && _currentSelection.size() > 0 && getInvolvedObjects() > 1) { @@ -311,25 +311,47 @@ void MacVentureEngine::handleObjectSelect(ObjID objID, WindowReference win, Comm if (objID > 0) { int i = findObjectInArray(objID, _currentSelection); - /*if (event.type == Common::EVENT isDoubleClick(event)) { // no double click for now - if (!found) - unSelectAll(); - selectObj(obj); - doubleClickObject(obj, win, event, canDrag); - } else {*/ - if (i >= 0) - unselectAll(); - selectObject(objID); - if (getInvolvedObjects() == 1) - _cmdReady = true; - preparedToRun(); - //singleClickObject(objID, win, event, canDrag); - //} + if (isDoubleClick) { // no double click for now + if (i >= 0) + unselectAll(); + selectObject(objID); + if (!_cmdReady) + { + selectPrimaryObject(objID); + if (_selectedControl == kNoCommand) { + _selectedControl = kActivateObject; + if (_activeControl) + _activeControl = kNoCommand; + _activeControl = kActivateObject; + _cmdReady = true; + } + } + preparedToRun(); + //doubleClickObject(objID, win, event, canDrag); + debug("Double click"); + } else { + if (i >= 0) + unselectAll(); + selectObject(objID); + if (getInvolvedObjects() == 1) + _cmdReady = true; + preparedToRun(); + //singleClickObject(objID, win, event, canDrag); + } } } } } +void MacVentureEngine::handleObjectDrop(ObjID objID, Common::Point delta, ObjID newParent) { + _destObject = newParent; + updateDelta(delta); + selectControl(kControlOperate); + activateCommand(kControlOperate); + refreshReady(); + preparedToRun(); +} + void MacVentureEngine::updateDelta(Common::Point newPos) { Common::Point newDelta = newPos - _deltaPoint; debug(4, "Update delta: Old(%d, %d), New(%d, %d)", @@ -508,6 +530,7 @@ void MacVentureEngine::selectObject(ObjID objID) { _selectedObjs.push_back(objID); highlightExit(objID); } + _deltaPoint = getObjPosition(objID); } void MacVentureEngine::unselectObject(ObjID objID) { diff --git a/engines/macventure/macventure.h b/engines/macventure/macventure.h index cdf9a94a5a..ad13d122f1 100644 --- a/engines/macventure/macventure.h +++ b/engines/macventure/macventure.h @@ -179,7 +179,8 @@ public: void runObjQueue(); bool printTexts(); - void handleObjectSelect(ObjID objID, WindowReference win, Common::Event event, bool isDoubleClick); + void handleObjectSelect(ObjID objID, WindowReference win, bool shiftPressed, bool isDoubleClick); + void handleObjectDrop(ObjID objID, Common::Point delta, ObjID newParent); void updateDelta(Common::Point newPos); void focusObjWin(ObjID objID); void updateWindow(WindowReference winID); |