2016-03-08 22:34:51 -05:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "titanic/input_handler.h"
|
2016-03-18 21:34:04 -04:00
|
|
|
#include "titanic/game_manager.h"
|
2016-04-03 16:16:35 -04:00
|
|
|
#include "titanic/support/screen_manager.h"
|
2016-03-18 21:34:04 -04:00
|
|
|
#include "titanic/titanic.h"
|
2016-03-18 23:15:31 -04:00
|
|
|
#include "titanic/pet_control/pet_control.h"
|
2016-03-08 22:34:51 -05:00
|
|
|
|
|
|
|
namespace Titanic {
|
|
|
|
|
|
|
|
CInputHandler::CInputHandler(CGameManager *owner) :
|
2016-03-18 23:15:31 -04:00
|
|
|
_gameManager(owner), _inputTranslator(nullptr), _dragging(false),
|
|
|
|
_buttonDown(false), _dragItem(nullptr), _lockCount(0), _field24(0) {
|
2016-03-08 22:34:51 -05:00
|
|
|
CScreenManager::_screenManagerPtr->_inputHandler = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CInputHandler::setTranslator(CInputTranslator *translator) {
|
|
|
|
_inputTranslator = translator;
|
|
|
|
}
|
|
|
|
|
2016-03-13 10:28:45 -04:00
|
|
|
void CInputHandler::incLockCount() {
|
|
|
|
++_lockCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CInputHandler::decLockCount() {
|
|
|
|
if (--_lockCount == 0 && _inputTranslator) {
|
|
|
|
warning("TODO");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-24 07:49:59 -04:00
|
|
|
void CInputHandler::handleMessage(CMessage &msg, bool respectLock) {
|
2016-03-18 21:34:04 -04:00
|
|
|
if (!respectLock || _lockCount <= 0) {
|
2016-03-31 22:31:13 -04:00
|
|
|
if (_gameManager->_gameState._mode == GSMODE_SELECTED) {
|
2016-03-18 23:15:31 -04:00
|
|
|
processMessage(&msg);
|
2016-03-18 21:34:04 -04:00
|
|
|
} else if (!msg.isMouseMsg()) {
|
2016-05-09 21:03:21 -04:00
|
|
|
g_vm->_filesManager->loadDrive();
|
2016-03-18 21:34:04 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-24 07:49:59 -04:00
|
|
|
void CInputHandler::processMessage(CMessage *msg) {
|
2016-03-18 23:15:31 -04:00
|
|
|
const CMouseMsg *mouseMsg = dynamic_cast<const CMouseMsg *>(msg);
|
|
|
|
_field24 = 0;
|
|
|
|
dispatchMessage(msg);
|
|
|
|
|
|
|
|
if (_field24) {
|
|
|
|
_field24 = 0;
|
|
|
|
} else if (mouseMsg) {
|
|
|
|
// Keep the game state mouse position up to date
|
|
|
|
if (_mousePos != mouseMsg->_mousePos) {
|
|
|
|
_mousePos = mouseMsg->_mousePos;
|
|
|
|
_gameManager->_gameState.setMousePos(mouseMsg->_mousePos);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set flag for whether a mouse button is currently being pressed
|
|
|
|
if (mouseMsg->isButtonDownMsg())
|
|
|
|
_buttonDown = true;
|
|
|
|
else if (mouseMsg->isButtonUpMsg())
|
|
|
|
_buttonDown = false;
|
|
|
|
|
|
|
|
// Drag events generation
|
|
|
|
if (_dragging) {
|
|
|
|
if (mouseMsg->isMouseMoveMsg()) {
|
|
|
|
if (_dragItem) {
|
|
|
|
CMouseDragMoveMsg moveMsg(_mousePos);
|
|
|
|
moveMsg.execute(_dragItem);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (mouseMsg->isButtonUpMsg() && _dragItem) {
|
|
|
|
// Mouse drag ended
|
2016-04-11 18:53:40 -04:00
|
|
|
CGameObject *target = dragEnd(_mousePos, _dragItem);
|
2016-04-10 17:09:22 -04:00
|
|
|
CMouseDragEndMsg endMsg(_mousePos, target);
|
2016-03-18 23:15:31 -04:00
|
|
|
endMsg.execute(_dragItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
_dragging = false;
|
|
|
|
_dragItem = nullptr;
|
|
|
|
}
|
|
|
|
} else if (_buttonDown) {
|
|
|
|
if (!mouseMsg->isMouseMoveMsg()) {
|
|
|
|
// Save where the drag movement started from
|
|
|
|
_dragStartPos = _mousePos;
|
|
|
|
} else {
|
2016-03-21 20:53:49 -04:00
|
|
|
Point delta = mouseMsg->_mousePos - _dragStartPos;
|
2016-03-18 23:15:31 -04:00
|
|
|
int distance = (int)sqrt(double(delta.x * delta.x + delta.y * delta.y));
|
|
|
|
|
|
|
|
if (distance > 4) {
|
|
|
|
// We've moved far enough with the mouse button held down
|
|
|
|
// to trigger an official dragging operation
|
|
|
|
CMouseDragStartMsg startMsg(_dragStartPos);
|
|
|
|
dispatchMessage(&startMsg);
|
|
|
|
|
|
|
|
// Set the drag item, if any, that a handler will have set on the message
|
|
|
|
_dragItem = startMsg._dragItem;
|
|
|
|
_gameManager->_dragItem = startMsg._dragItem;
|
|
|
|
|
|
|
|
if (_dragItem) {
|
|
|
|
CMouseDragMoveMsg moveMsg(_dragStartPos);
|
|
|
|
dispatchMessage(&moveMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
_dragging = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-24 07:49:59 -04:00
|
|
|
void CInputHandler::dispatchMessage(CMessage *msg) {
|
2016-03-18 23:15:31 -04:00
|
|
|
CPetControl *pet = _gameManager->_project->getPetControl();
|
|
|
|
if (!pet || !msg->execute(pet, nullptr, MSGFLAG_BREAK_IF_HANDLED)) {
|
|
|
|
CViewItem *view = _gameManager->getView();
|
|
|
|
msg->execute(view);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-11 18:53:40 -04:00
|
|
|
CGameObject *CInputHandler::dragEnd(const Point &pt, CTreeItem *dragItem) {
|
2016-04-10 17:09:22 -04:00
|
|
|
CViewItem *view = _gameManager->getView();
|
|
|
|
if (!view)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
// Scan through the view items to find the item being dropped on
|
2016-04-11 18:53:40 -04:00
|
|
|
CGameObject *target = nullptr;
|
2016-04-10 17:09:22 -04:00
|
|
|
for (CTreeItem *treeItem = view->scan(view); treeItem; treeItem = treeItem->scan(view)) {
|
|
|
|
CGameObject *gameObject = static_cast<CGameObject *>(treeItem);
|
|
|
|
if (gameObject && gameObject != dragItem) {
|
|
|
|
if (gameObject->checkPoint(pt))
|
|
|
|
target = gameObject;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (target) {
|
|
|
|
// Check if the cursor is on the PET. If so, pass to the PET
|
|
|
|
// to see what specific element the drag ended on
|
|
|
|
CProjectItem *project = view->getRoot();
|
|
|
|
if (project) {
|
|
|
|
CPetControl *petControl = project->getPetControl();
|
|
|
|
if (petControl && petControl->contains(pt)) {
|
|
|
|
target = petControl->dragEnd(pt);
|
|
|
|
if (!target)
|
|
|
|
target = petControl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return target;
|
2016-03-18 21:34:04 -04:00
|
|
|
}
|
|
|
|
|
2016-04-10 17:09:22 -04:00
|
|
|
} // End of namespace Titanic
|