aboutsummaryrefslogtreecommitdiff
path: root/engines/macventure/gui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/macventure/gui.cpp')
-rw-r--r--engines/macventure/gui.cpp1464
1 files changed, 1464 insertions, 0 deletions
diff --git a/engines/macventure/gui.cpp b/engines/macventure/gui.cpp
new file mode 100644
index 0000000000..dff41b3c23
--- /dev/null
+++ b/engines/macventure/gui.cpp
@@ -0,0 +1,1464 @@
+/* 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 "common/file.h"
+#include "common/system.h"
+#include "common/debug-channels.h"
+#include "common/debug.h"
+#include "image/bmp.h"
+
+#include "macventure/gui.h"
+#include "macventure/dialog.h"
+
+namespace MacVenture {
+
+enum MenuAction;
+
+enum {
+ kCursorWidth = 2,
+ kCursorHeight = 2
+};
+
+enum {
+ kExitButtonWidth = 10,
+ kExitButtonHeight = 10
+};
+
+enum {
+ kMenuHighLevel = -1,
+ kMenuAbout = 0,
+ kMenuFile = 1,
+ kMenuEdit = 2,
+ kMenuSpecial = 3
+};
+
+enum {
+ kCommandNum = 8
+};
+
+enum {
+ kDragThreshold = 5
+};
+
+const bool kLoadStaticMenus = true;
+
+static const Graphics::MenuData menuSubItems[] = {
+ { kMenuHighLevel, "File", 0, 0, false },
+ { kMenuHighLevel, "Edit", 0, 0, false },
+ { kMenuHighLevel, "Special", 0, 0, false },
+ { kMenuHighLevel, "Font", 0, 0, false },
+ { kMenuHighLevel, "FontSize", 0, 0, false },
+
+ //{ kMenuAbout, "About", kMenuActionAbout, 0, true},
+
+ { kMenuFile, "New", kMenuActionNew, 0, true },
+ { kMenuFile, NULL, 0, 0, false },
+ { kMenuFile, "Open...", kMenuActionOpen, 0, true },
+ { kMenuFile, "Save", kMenuActionSave, 0, true },
+ { kMenuFile, "Save as...", kMenuActionSaveAs, 0, true },
+ { kMenuFile, NULL, 0, 0, false },
+ { kMenuFile, "Quit", kMenuActionQuit, 0, true },
+
+ { kMenuEdit, "Undo", kMenuActionUndo, 'Z', false },
+ { kMenuEdit, NULL, 0, 0, false },
+ { kMenuEdit, "Cut", kMenuActionCut, 'K', false },
+ { kMenuEdit, "Copy", kMenuActionCopy, 'C', false },
+ { kMenuEdit, "Paste", kMenuActionPaste, 'V', false },
+ { kMenuEdit, "Clear", kMenuActionClear, 'B', false },
+
+ { kMenuSpecial, "Clean Up", kMenuActionCleanUp, 0, false },
+ { kMenuSpecial, "Mess Up", kMenuActionMessUp, 0, false },
+
+ { 0, NULL, 0, 0, false }
+};
+
+
+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);
+bool selfWindowCallback(Graphics::WindowClick, Common::Event &event, void *gui);
+bool exitsWindowCallback(Graphics::WindowClick, Common::Event &event, void *gui);
+bool diplomaWindowCallback(Graphics::WindowClick, Common::Event &event, void *gui);
+bool inventoryWindowCallback(Graphics::WindowClick, Common::Event &event, void *gui);
+
+void menuCommandsCallback(int action, Common::String &text, void *data);
+
+Gui::Gui(MacVentureEngine *engine, Common::MacResManager *resman) {
+ _engine = engine;
+ _resourceManager = resman;
+ _windowData = NULL;
+ _controlData = NULL;
+ _draggedObj.id = 0;
+ _draggedObj.pos = Common::Point(0, 0);
+ _dialog = NULL;
+
+ _cursor = new Cursor(this);
+
+ _consoleText = new ConsoleText(this);
+ _graphics = NULL;
+
+ initGUI();
+}
+
+Gui::~Gui() {
+
+ if (_windowData)
+ delete _windowData;
+
+ if (_controlData)
+ delete _controlData;
+
+ if (_exitsData)
+ delete _exitsData;
+
+ if (_cursor)
+ delete _cursor;
+
+ if (_consoleText)
+ delete _consoleText;
+
+ if (_dialog)
+ delete _dialog;
+
+ clearAssets();
+
+ if (_graphics)
+ delete _graphics;
+}
+
+void Gui::initGUI() {
+ _screen.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
+ _wm.setScreen(&_screen);
+
+ // Menu
+ _menu = _wm.addMenu();
+ if (!loadMenus())
+ error("GUI: Could not load menus");
+ _menu->setCommandsCallback(menuCommandsCallback, this);
+ _menu->calcDimensions();
+
+ loadGraphics();
+
+ if (!loadWindows())
+ error("GUI: Could not load windows");
+
+ initWindows();
+
+ assignObjReferences();
+
+ if (!loadControls())
+ error("GUI: Could not load controls");
+
+ draw();
+
+}
+
+void Gui::reloadInternals() {
+ clearAssets();
+ loadGraphics();
+}
+
+void Gui::draw() {
+ // Will be performance-improved after the milestone
+ _wm.setFullRefresh(true);
+
+ drawWindows();
+
+ _wm.draw();
+
+ drawDraggedObject();
+ drawDialog();
+ // TODO: When window titles with custom borders are in MacGui, this should be used.
+ //drawWindowTitle(kMainGameWindow, _mainGameWindow->getSurface());
+}
+
+void Gui::drawMenu() {
+ _menu->draw(&_screen);
+}
+
+void Gui::drawTitle() {
+ warning("drawTitle hasn't been tested yet");
+}
+
+void Gui::clearControls() {
+ if (!_controlData)
+ return;
+
+ Common::Array<CommandButton>::iterator it = _controlData->begin();
+ for (; it != _controlData->end(); ++it) {
+ it->unselect();
+ }
+}
+
+void Gui::initWindows() {
+ // Game Controls Window
+ _controlsWindow = _wm.addWindow(false, false, false);
+ _controlsWindow->setDimensions(getWindowData(kCommandsWindow).bounds);
+ _controlsWindow->setActive(false);
+ _controlsWindow->setCallback(commandsWindowCallback, this);
+ loadBorders(_controlsWindow, findWindowData(kCommandsWindow).type);
+
+ // Main Game Window
+ _mainGameWindow = _wm.addWindow(false, false, false);
+ _mainGameWindow->setDimensions(getWindowData(kMainGameWindow).bounds);
+ _mainGameWindow->setActive(false);
+ _mainGameWindow->setCallback(mainGameWindowCallback, this);
+ loadBorders(_mainGameWindow, findWindowData(kMainGameWindow).type);
+
+ // In-game Output Console
+ _outConsoleWindow = _wm.addWindow(true, true, false);
+ // HACK We have to hand-create the dimensions, otherwise they don't fit
+ const WindowData &wd = getWindowData(kOutConsoleWindow);
+ Common::Rect dimensions = wd.bounds;
+ dimensions.setWidth(dimensions.width() - borderBounds(wd.type).rightOffset);
+ _outConsoleWindow->setDimensions(dimensions);
+ _outConsoleWindow->setActive(false);
+ _outConsoleWindow->setCallback(outConsoleWindowCallback, this);
+ loadBorders(_outConsoleWindow, findWindowData(kOutConsoleWindow).type);
+
+ // Self Window
+ _selfWindow = _wm.addWindow(false, true, false);
+ _selfWindow->setDimensions(getWindowData(kSelfWindow).bounds);
+ _selfWindow->setActive(false);
+ _selfWindow->setCallback(selfWindowCallback, this);
+ loadBorders(_selfWindow, findWindowData(kSelfWindow).type);
+
+ // Exits Window
+ _exitsWindow = _wm.addWindow(false, false, false);
+ _exitsWindow->setDimensions(getWindowData(kExitsWindow).bounds);
+ _exitsWindow->setActive(false);
+ _exitsWindow->setCallback(exitsWindowCallback, this);
+ loadBorders(_exitsWindow, findWindowData(kExitsWindow).type);
+}
+
+const WindowData &Gui::getWindowData(WindowReference reference) {
+ return findWindowData(reference);
+}
+
+const Graphics::Font &Gui::getCurrentFont() {
+ return *_wm.getFont("Chicago-12", Graphics::FontManager::kBigGUIFont);
+}
+
+void Gui::bringToFront(WindowReference winID) {
+ findWindow(winID)->setActive(true);
+}
+
+void Gui::setWindowTitle(WindowReference winID, Common::String string) {
+ findWindowData(winID).title = string;
+ findWindowData(winID).titleLength = string.size();
+}
+
+void Gui::updateWindowInfo(WindowReference ref, ObjID objID, const Common::Array<ObjID> &children) {
+ if (ref == kNoWindow) {
+ return;
+ }
+ WindowData &data = findWindowData(ref);
+ data.children.clear();
+ data.objRef = objID;
+ uint32 originx = 0x7fff;
+ uint32 originy = 0x7fff;
+ for (uint i = 0; i < children.size(); i++) {
+ if (children[i] != 1) {
+ ObjID child = children[i];
+ if (ref != kMainGameWindow) {
+ Common::Point childPos = _engine->getObjPosition(child);
+ originx = originx > (uint)childPos.x ? (uint)childPos.x : originx;
+ originy = originy > (uint)childPos.y ? (uint)childPos.y : originy;
+ }
+ data.children.push_back(DrawableObject(child, kBlitBIC));
+ }
+ }
+ if (originx != 0x7fff) {
+ data.bounds.left = originx;
+ }
+ if (originy != 0x7fff) {
+ data.bounds.top = originy;
+ }
+ if (ref != kMainGameWindow) {
+ data.updateScroll = true;
+ }
+}
+
+void Gui::addChild(WindowReference target, ObjID child) {
+ findWindowData(target).children.push_back(DrawableObject(child, kBlitBIC));
+}
+
+void Gui::removeChild(WindowReference target, ObjID child) {
+ WindowData &data = findWindowData(target);
+ uint index = 0;
+ for (;index < data.children.size(); index++) {
+ if (data.children[index].obj == child) {
+ break;
+ }
+ }
+
+ if (index < data.children.size())
+ data.children.remove_at(index);
+}
+
+void Gui::assignObjReferences() {
+ findWindowData(kSelfWindow).objRef = 0;
+}
+
+WindowReference Gui::createInventoryWindow(ObjID objRef) {
+ Graphics::MacWindow *newWindow = _wm.addWindow(true, true, true);
+ WindowData newData;
+ GlobalSettings settings = _engine->getGlobalSettings();
+ newData.refcon = (WindowReference)ABS(_inventoryWindows.size() + kInventoryStart); // This is a HACK
+
+ if (_windowData->back().refcon < 0x80) { // There is already another inventory window
+ newData.bounds = _windowData->back().bounds; // Inventory windows are always last
+ newData.bounds.translate(newData.bounds.left + settings._invOffsetX, newData.bounds.top + settings._invOffsetY);
+ } else {
+ BorderBounds bbs = borderBounds(kInvWindow);
+ newData.bounds = Common::Rect(
+ settings._invLeft - bbs.leftOffset,
+ settings._invTop - bbs.topOffset,
+ settings._invLeft + settings._invWidth,
+ settings._invTop + settings._invHeight);
+ }
+ newData.type = kInvWindow;
+ newData.hasCloseBox = true;
+ newData.visible = true;
+ newData.objRef = objRef;
+ _windowData->push_back(newData);
+
+ newWindow->setDimensions(newData.bounds);
+ newWindow->setCallback(inventoryWindowCallback, this);
+ newWindow->setCloseable(true);
+ loadBorders(newWindow, newData.type);
+ _inventoryWindows.push_back(newWindow);
+
+ debugC(1, kMVDebugGUI, "Create new inventory window. Reference: %d", newData.refcon);
+ return newData.refcon;
+}
+
+void Gui::loadBorders(Graphics::MacWindow *target, MVWindowType type) {
+ loadBorder(target, type, false);
+ loadBorder(target, type, true);
+}
+
+void Gui::loadBorder(Graphics::MacWindow *target, MVWindowType type, bool active) {
+
+ Common::SeekableReadStream *stream = _engine->getBorderFile(type, active);
+
+ if (stream) {
+ BorderBounds bbs = borderBounds(type);
+ target->loadBorder(*stream, active, bbs.leftOffset, bbs.rightOffset, bbs.topOffset, bbs.bottomOffset);
+
+ delete stream;
+ }
+}
+
+void Gui::loadGraphics() {
+ if (_graphics)
+ delete _graphics;
+ _graphics = new Container(_engine->getFilePath(kGraphicPathID));
+}
+
+void Gui::clearAssets() {
+ Common::HashMap<ObjID, ImageAsset*>::const_iterator it = _assets.begin();
+ for (; it != _assets.end(); it++) {
+ delete it->_value;
+ }
+ _assets.clear();
+}
+
+bool Gui::loadMenus() {
+
+ if (kLoadStaticMenus) {
+ // We assume that, if there are static menus, we don't need dynamic ones
+ _menu->addStaticMenus(menuSubItems);
+ return true;
+ }
+
+ Common::MacResIDArray resArray;
+ Common::SeekableReadStream *res;
+ Common::MacResIDArray::const_iterator iter;
+
+ if ((resArray = _resourceManager->getResIDArray(MKTAG('M', 'E', 'N', 'U'))).size() == 0)
+ return false;
+
+ _menu->addMenuSubItem(0, "Abb", kMenuActionAbout, 0, 'A', true);
+
+ int i = 1;
+ for (iter = resArray.begin(); iter != resArray.end(); ++iter) {
+ res = _resourceManager->getResource(MKTAG('M', 'E', 'N', 'U'), *iter);
+ uint16 key;
+ uint16 style;
+ uint8 titleLength;
+ char *title;
+
+ /* Skip menuID, width, height, resourceID, placeholder */
+ for (int skip = 0; skip < 5; skip++) {
+ res->readUint16BE();
+ }
+ titleLength = res->readByte();
+ title = new char[titleLength + 1];
+ res->read(title, titleLength);
+ title[titleLength] = '\0';
+
+ if (titleLength > 1) {
+ _menu->addMenuItem(title);
+
+ // Read submenu items
+ while ((titleLength = res->readByte())) {
+ title = new char[titleLength + 1];
+ res->read(title, titleLength);
+ title[titleLength] = '\0';
+ // Skip icon
+ res->readUint16BE();
+ // Read key
+ key = res->readUint16BE();
+ // Skip mark
+ res->readUint16BE();
+ // Read style
+ style = res->readUint16BE();
+ _menu->addMenuSubItem(i, title, 0, style, key, false);
+ }
+ }
+
+ i++;
+ delete res;
+ }
+
+ return true;
+}
+
+bool Gui::loadWindows() {
+ Common::MacResIDArray resArray;
+ Common::SeekableReadStream *res;
+ Common::MacResIDArray::const_iterator iter;
+
+ _windowData = new Common::List<WindowData>();
+
+ if ((resArray = _resourceManager->getResIDArray(MKTAG('W', 'I', 'N', 'D'))).size() == 0)
+ return false;
+
+ uint32 id = kCommandsWindow;
+ for (iter = resArray.begin(); iter != resArray.end(); ++iter) {
+ res = _resourceManager->getResource(MKTAG('W', 'I', 'N', 'D'), *iter);
+ WindowData data;
+ uint16 top, left, bottom, right;
+ top = res->readUint16BE();
+ left = res->readUint16BE();
+ bottom = res->readUint16BE();
+ right = res->readUint16BE();
+ data.type = (MVWindowType)res->readUint16BE();
+ BorderBounds bbs = borderBounds(data.type);
+ data.bounds = Common::Rect(
+ left - bbs.leftOffset,
+ top - bbs.topOffset,
+ right + bbs.rightOffset,
+ bottom + bbs.bottomOffset);
+
+ data.visible = res->readUint16BE();
+ data.hasCloseBox = res->readUint16BE();
+ data.refcon = (WindowReference)id; id++;
+ res->readUint32BE(); // Skip the true id. For some reason it's reading 0
+ data.titleLength = res->readByte();
+ if (data.titleLength) {
+ char *newTitle = new char[data.titleLength + 1];
+ res->read(newTitle, data.titleLength);
+ newTitle[data.titleLength] = '\0';
+ data.title = Common::String(newTitle);
+ delete[] newTitle;
+ }
+ data.scrollPos = Common::Point(0, 0);
+
+ debugC(1, kMVDebugGUI, "Window loaded: %s", data.title.c_str());
+
+ _windowData->push_back(data);
+
+ delete res;
+ }
+
+ return true;
+}
+
+bool Gui::loadControls() {
+ Common::MacResIDArray resArray;
+ Common::SeekableReadStream *res;
+ Common::MacResIDArray::const_iterator iter;
+
+ _controlData = new Common::Array<CommandButton>();
+ _exitsData = new Common::Array<CommandButton>();
+
+ if ((resArray = _resourceManager->getResIDArray(MKTAG('C', 'N', 'T', 'L'))).size() == 0)
+ return false;
+
+ uint32 id = kControlExitBox;
+ for (iter = resArray.begin(); iter != resArray.end(); ++iter) {
+ res = _resourceManager->getResource(MKTAG('C', 'N', 'T', 'L'), *iter);
+ ControlData data;
+ uint16 top, left, bottom, right;
+ top = res->readUint16BE();
+ left = res->readUint16BE();
+ bottom = res->readUint16BE();
+ right = res->readUint16BE();
+ data.scrollValue = res->readUint16BE();
+ data.visible = res->readByte();
+ res->readByte(); // Unused
+ data.scrollMax = res->readUint16BE();
+ data.scrollMin = res->readUint16BE();
+ data.cdef = res->readUint16BE();
+ data.refcon = (ControlAction)res->readUint32BE();
+ data.type = (ControlType)id; id++;
+ data.titleLength = res->readByte();
+ if (data.titleLength) {
+ char *title = new char[data.titleLength + 1];
+ res->read(title, data.titleLength);
+ title[data.titleLength] = '\0';
+ data.title = Common::String(title);
+ delete[] title;
+ }
+ if (data.type != kControlExitBox) {
+ BorderBounds bbs = borderBounds(getWindowData(kCommandsWindow).type);
+ // We just want to move the button, not change it's size
+ data.bounds = Common::Rect(left + bbs.leftOffset, top + bbs.topOffset, right + bbs.leftOffset, bottom + bbs.topOffset);
+ } else {
+ data.bounds = Common::Rect(left, top, right, bottom);
+ }
+
+
+ _controlData->push_back(CommandButton(data, this));
+
+ delete res;
+ }
+
+ return true;
+}
+
+void Gui::drawWindows() {
+
+ drawCommandsWindow();
+ drawMainGameWindow();
+ drawSelfWindow();
+ drawInventories();
+ drawExitsWindow();
+ drawConsoleWindow();
+
+}
+
+void Gui::drawCommandsWindow() {
+ if (_engine->needsClickToContinue()) {
+ Graphics::ManagedSurface *srf = _controlsWindow->getSurface();
+ WindowData data = getWindowData(kCommandsWindow);
+ srf->fillRect(Common::Rect(0, 0, srf->w, srf->h), kColorWhite);
+ getCurrentFont().drawString(
+ srf,
+ _engine->getCommandsPausedString(),
+ 0,
+ (srf->h / 2) - getCurrentFont().getFontHeight(),
+ data.bounds.right - data.bounds.left,
+ kColorBlack,
+ Graphics::kTextAlignCenter);
+ } else {
+ Common::Array<CommandButton>::const_iterator it = _controlData->begin();
+ for (; it != _controlData->end(); ++it) {
+ CommandButton button = *it;
+ if (button.getData().type != kControlExitBox)
+ button.draw(*_controlsWindow->getSurface());
+ }
+ }
+}
+
+void Gui::drawMainGameWindow() {
+ const WindowData &data = getWindowData(kMainGameWindow);
+ BorderBounds border = borderBounds(data.type);
+ ObjID objRef = data.objRef;
+
+ _mainGameWindow->setDirty(true);
+
+ if (data.objRef > 0 && data.objRef < 2000) {
+ ensureAssetLoaded(objRef);
+
+ _assets[objRef]->blitInto(
+ _mainGameWindow->getSurface(),
+ border.leftOffset,
+ border.topOffset,
+ kBlitDirect);
+ }
+
+ drawObjectsInWindow(data, _mainGameWindow->getSurface());
+
+ if (DebugMan.isDebugChannelEnabled(kMVDebugGUI)) {
+ Graphics::MacWindow *win = findWindow(data.refcon);
+ Common::Rect innerDims = win->getInnerDimensions();
+ int x = win->getDimensions().left;
+ int y = win->getDimensions().top;
+ innerDims.translate(-x, -y);
+ win->getSurface()->frameRect(innerDims, kColorGreen);
+ }
+
+ findWindow(kMainGameWindow)->setDirty(true);
+}
+
+void Gui::drawSelfWindow() {
+ drawObjectsInWindow(getWindowData(kSelfWindow), _selfWindow->getSurface());
+ if (_engine->isObjSelected(1)) {
+ invertWindowColors(kSelfWindow);
+ }
+ findWindow(kSelfWindow)->setDirty(true);
+}
+
+void Gui::drawInventories() {
+
+ Graphics::ManagedSurface *srf;
+ for (uint i = 0; i < _inventoryWindows.size(); i++) {
+ const WindowData &data = getWindowData((WindowReference)(kInventoryStart + i));
+ Graphics::MacWindow *win = findWindow(data.refcon);
+ srf = win->getSurface();
+ srf->clear(kColorGreen);
+ srf->fillRect(srf->getBounds(), kColorWhite);
+ drawObjectsInWindow(data, srf);
+
+ if (DebugMan.isDebugChannelEnabled(kMVDebugGUI)) {
+ Common::Rect innerDims = win->getInnerDimensions();
+ int x = win->getDimensions().left;
+ int y = win->getDimensions().top;
+ innerDims.translate(-x, -y);
+ srf->frameRect(innerDims, kColorGreen);
+ }
+
+ findWindow(data.refcon)->setDirty(true);
+ }
+
+}
+
+void Gui::drawExitsWindow() {
+
+ Graphics::ManagedSurface *srf = _exitsWindow->getSurface();
+ BorderBounds border = borderBounds(getWindowData(kExitsWindow).type);
+
+ srf->fillRect(Common::Rect(
+ border.leftOffset,
+ border.topOffset,
+ srf->w + border.rightOffset,
+ srf->h + border.bottomOffset), kColorWhite);
+
+ Common::Array<CommandButton>::const_iterator it = _exitsData->begin();
+ for (; it != _exitsData->end(); ++it) {
+ CommandButton button = *it;
+ button.draw(*_exitsWindow->getSurface());
+ }
+
+ findWindow(kExitsWindow)->setDirty(true);
+}
+
+void Gui::drawConsoleWindow() {
+
+ Graphics::ManagedSurface *srf = _outConsoleWindow->getSurface();
+ BorderBounds bounds = borderBounds(getWindowData(kOutConsoleWindow).type);
+ _consoleText->renderInto(srf, bounds, kConsoleLeftOffset);
+}
+
+void Gui::drawObjectsInWindow(const WindowData &targetData, Graphics::ManagedSurface *surface) {
+ BorderBounds border = borderBounds(targetData.type);
+ Common::Point pos;
+ ObjID child;
+ BlitMode mode;
+
+ if (targetData.children.size() == 0) {
+ return;
+ }
+
+ Graphics::ManagedSurface composeSurface;
+ createInnerSurface(&composeSurface, surface, border);
+ assert(composeSurface.w <= surface->w &&
+ composeSurface.h <= surface->h);
+ composeSurface.clear(kColorGreen);
+
+ for (uint i = 0; i < targetData.children.size(); i++) {
+ child = targetData.children[i].obj;
+ mode = (BlitMode)targetData.children[i].mode;
+ pos = _engine->getObjPosition(child);
+ pos -= targetData.scrollPos;
+ ensureAssetLoaded(child);
+
+ _assets[child]->blitInto(
+ &composeSurface,
+ pos.x,
+ pos.y,
+ mode);
+
+ if (_engine->isObjVisible(child)) {
+ if (_engine->isObjSelected(child) ||
+ child == _draggedObj.id) {
+
+ _assets[child]->blitInto(
+ &composeSurface, pos.x, pos.y, kBlitOR);
+ }
+ }
+
+ if (DebugMan.isDebugChannelEnabled(kMVDebugGUI)) {
+ Common::Rect testBounds = _engine->getObjBounds(child);
+ testBounds.translate(-targetData.scrollPos.x, -targetData.scrollPos.y);
+ surface->frameRect(testBounds, kColorGreen);
+ }
+ }
+ Common::Point composePosition = Common::Point(border.leftOffset, border.topOffset);
+ surface->transBlitFrom(composeSurface, composePosition, kColorGreen);
+}
+
+void Gui::drawWindowTitle(WindowReference target, Graphics::ManagedSurface *surface) {
+ // TODO: Implement when MacGui supports titles in windows with custom borders.
+}
+
+void Gui::drawDraggedObject() {
+ if (_draggedObj.id != 0 &&
+ _engine->isObjVisible(_draggedObj.id)) {
+ ensureAssetLoaded(_draggedObj.id);
+ ImageAsset *asset = _assets[_draggedObj.id];
+
+ // In case of overflow from the right/top
+ uint w = asset->getWidth() + MIN((int16)0, _draggedObj.pos.x);
+ uint h = asset->getHeight() + MIN((int16)0, _draggedObj.pos.y);
+
+ // In case of overflow from the bottom/left
+ if (_draggedObj.pos.x > 0 && _draggedObj.pos.x + w > kScreenWidth) {
+ w = kScreenWidth - _draggedObj.pos.x;
+ }
+ if (_draggedObj.pos.y > 0 && _draggedObj.pos.y + h > kScreenHeight) {
+ h = kScreenHeight - _draggedObj.pos.y;
+ }
+
+ Common::Point target = _draggedObj.pos;
+ if (target.x < 0) {
+ target.x = 0;
+ }
+ if (target.y < 0) {
+ target.y = 0;
+ }
+
+ _draggedSurface.create(w, h, _screen.format);
+ _draggedSurface.blitFrom(
+ _screen,
+ Common::Rect(
+ target.x,
+ target.y,
+ target.x + _draggedSurface.w,
+ target.y + _draggedSurface.h),
+ Common::Point(0, 0));
+ asset->blitInto(&_draggedSurface, MIN((int16)0, _draggedObj.pos.x), MIN((int16)0, _draggedObj.pos.y), kBlitBIC);
+
+ g_system->copyRectToScreen(
+ _draggedSurface.getBasePtr(0, 0),
+ _draggedSurface.pitch,
+ target.x,
+ target.y,
+ _draggedSurface.w,
+ _draggedSurface.h
+ );
+ }
+}
+
+void Gui::drawDialog() {
+ if (_dialog) {
+ _dialog->draw();
+ }
+}
+
+void Gui::updateWindow(WindowReference winID, bool containerOpen) {
+ if (winID == kNoWindow) {
+ return;
+ }
+ if (winID == kSelfWindow || containerOpen) {
+ WindowData &data = findWindowData(winID);
+ if (winID == kCommandsWindow) {
+ Common::Array<CommandButton>::iterator it = _controlData->begin();
+ for (; it != _controlData->end(); ++it) {
+ it->unselect();
+ }
+ }
+ Common::Array<DrawableObject> &children = data.children;
+ for (uint i = 0; i < children.size(); i++) {
+ uint flag = 0;
+ ObjID child = children[i].obj;
+ BlitMode mode = kBlitDirect;
+ bool off = !_engine->isObjVisible(child);
+ if (flag || !off || !_engine->isObjClickable(child)) {
+ mode = kBlitBIC;
+ if (off || flag) {
+ mode = kBlitXOR;
+ } else if (!off && _engine->isObjSelected(child)) {
+ mode = kBlitOR;
+ }
+ children[i] = DrawableObject(child, mode);
+ } else {
+ children[i] = DrawableObject(child, kBlitXOR);
+ }
+ }
+ if (winID == kMainGameWindow) {
+ drawMainGameWindow();
+ } else {
+ Graphics::MacWindow *winRef = findWindow(winID);
+ winRef->getSurface()->fillRect(data.bounds, kColorGray);
+ }
+ if (data.type == kZoomDoc && data.updateScroll) {
+ warning("Unimplemented: update scroll");
+ }
+ }
+}
+
+void Gui::clearExits() {
+ _exitsData->clear();
+}
+
+void Gui::unselectExits() {
+ Common::Array<CommandButton>::const_iterator it = _exitsData->begin();
+ for (; it != _exitsData->end(); ++it) {
+ CommandButton button = *it;
+ button.unselect();
+ }
+}
+
+void Gui::updateExit(ObjID obj) {
+ if (!_engine->isObjExit(obj)) {
+ return;
+ }
+ BorderBounds border = borderBounds(getWindowData(kExitsWindow).type);
+
+ int ctl = -1;
+ int i = 0;
+ Common::Array<CommandButton>::const_iterator it = _exitsData->begin();
+ for (;it != _exitsData->end(); it++) {
+ if (it->getData().refcon == obj)
+ ctl = i;
+ else
+ i++;
+ }
+
+ if (ctl != -1)
+ _exitsData->remove_at(ctl);
+
+ if (!_engine->isHiddenExit(obj) &&
+ _engine->getParent(obj) == _engine->getParent(1)) {
+ ControlData data;
+ data.titleLength = 0;
+ data.refcon = (ControlAction)obj; // Objects can be exits (actions)
+ Common::Point pos = _engine->getObjExitPosition(obj);
+ pos.x += border.leftOffset;
+ pos.y += border.topOffset;
+ data.bounds = Common::Rect(pos.x, pos.y, pos.x + kExitButtonWidth, pos.y + kExitButtonHeight);
+ data.visible = true;
+
+ _exitsData->push_back(CommandButton(data, this));
+ }
+}
+
+void Gui::printText(const Common::String &text) {
+ debugC(1, kMVDebugGUI, "Print Text: %s", text.c_str());
+ _consoleText->printLine(text, _outConsoleWindow->getDimensions().width());
+}
+
+void Gui::showPrebuiltDialog(PrebuiltDialogs type) {
+ closeDialog();
+ _dialog = new Dialog(this, type);
+}
+
+bool Gui::isDialogOpen() {
+ return _dialog != NULL;
+}
+
+void Gui::setTextInput(Common::String str) {
+ _engine->setTextInput(str);
+}
+
+
+void Gui::closeDialog() {
+ delete _dialog;
+ _dialog = NULL;
+}
+
+void Gui::getTextFromUser() {
+ if (_dialog) {
+ delete _dialog;
+ }
+ showPrebuiltDialog(kSpeakDialog);
+}
+
+void Gui::loadGame() {
+ _engine->scummVMSaveLoadDialog(false);
+}
+
+void Gui::saveGame() {
+ _engine->scummVMSaveLoadDialog(true);
+}
+
+void Gui::newGame() {
+ _engine->newGame();
+}
+
+void Gui::quitGame() {
+ _engine->requestQuit();
+}
+
+void Gui::createInnerSurface(Graphics::ManagedSurface *innerSurface, Graphics::ManagedSurface *outerSurface, const BorderBounds &borders) {
+ innerSurface->create(
+ outerSurface->w - borders.leftOffset - borders.rightOffset,
+ outerSurface->h - borders.topOffset - borders.bottomOffset,
+ outerSurface->format);
+}
+
+void Gui::moveDraggedObject(Common::Point target) {
+ ensureAssetLoaded(_draggedObj.id);
+ _draggedObj.pos = target + _draggedObj.mouseOffset;
+
+ // TODO FInd more elegant way of making pow2
+ _draggedObj.hasMoved = (_draggedObj.startPos.sqrDist(_draggedObj.pos) >= (kDragThreshold * kDragThreshold));
+
+ debugC(4, kMVDebugGUI, "Dragged obj position: (%d, %d), mouse offset: (%d, %d), hasMoved: %d, dist: %d, threshold: %d",
+ _draggedObj.pos.x, _draggedObj.pos.y,
+ _draggedObj.mouseOffset.x, _draggedObj.mouseOffset.y,
+ _draggedObj.hasMoved,
+ _draggedObj.startPos.sqrDist(_draggedObj.pos),
+ kDragThreshold * kDragThreshold
+ );
+
+}
+
+WindowReference Gui::findWindowAtPoint(Common::Point point) {
+ Common::List<WindowData>::iterator it;
+ Graphics::MacWindow *win;
+ for (it = _windowData->begin(); it != _windowData->end(); it++) {
+ win = findWindow(it->refcon);
+ if (win && it->refcon != kDiplomaWindow) { //HACK, diploma should be cosnidered
+ if (win->getDimensions().contains(point)) {
+ return it->refcon;
+ }
+ }
+ }
+ return kNoWindow;
+}
+
+Common::Point Gui::getGlobalScrolledSurfacePosition(WindowReference reference) {
+ const WindowData &data = getWindowData(reference);
+ BorderBounds border = borderBounds(data.type);
+ Graphics::MacWindow *win = findWindow(reference);
+ if (!win) {
+ return Common::Point(0, 0);
+ }
+ return Common::Point(
+ win->getDimensions().left + border.leftOffset - data.scrollPos.x,
+ win->getDimensions().top + border.topOffset - data.scrollPos.y);
+}
+
+WindowData &Gui::findWindowData(WindowReference reference) {
+ assert(_windowData);
+
+ Common::List<WindowData>::iterator iter = _windowData->begin();
+ while (iter->refcon != reference && iter != _windowData->end()) {
+ iter++;
+ }
+
+ if (iter->refcon == reference)
+ return *iter;
+
+ error("GUI: Could not locate the desired window data");
+}
+
+Graphics::MacWindow *Gui::findWindow(WindowReference reference) {
+ if (reference < 0x80 && reference >= kInventoryStart) { // It's an inventory window
+ return _inventoryWindows[reference - kInventoryStart];
+ }
+ switch (reference) {
+ case MacVenture::kNoWindow:
+ return NULL;
+ case MacVenture::kCommandsWindow:
+ return _controlsWindow;
+ case MacVenture::kMainGameWindow:
+ return _mainGameWindow;
+ case MacVenture::kOutConsoleWindow:
+ return _outConsoleWindow;
+ case MacVenture::kSelfWindow:
+ return _selfWindow;
+ case MacVenture::kExitsWindow:
+ return _exitsWindow;
+ case MacVenture::kDiplomaWindow:
+ return _diplomaWindow;
+ default:
+ return NULL;
+ }
+ return NULL;
+}
+
+void Gui::ensureInventoryOpen(WindowReference reference, ObjID id) {
+ assert(reference < 0x80 && reference >= kInventoryStart);
+ if (reference - kInventoryStart == (int)_inventoryWindows.size()) {
+ createInventoryWindow(id);
+ }
+}
+
+WindowReference Gui::getObjWindow(ObjID objID) {
+ switch (objID) {
+ case 0xfffc: return kExitsWindow;
+ case 0xfffd: return kSelfWindow;
+ case 0xfffe: return kOutConsoleWindow;
+ case 0xffff: return kCommandsWindow;
+ }
+
+ return findObjWindow(objID);
+}
+
+WindowReference Gui::findObjWindow(ObjID objID) {
+ // This is a bit of a HACK, we take advantage of the consecutive nature of references
+ for (uint i = kCommandsWindow; i <= kDiplomaWindow; i++) {
+ const WindowData &data = getWindowData((WindowReference)i);
+ if (data.objRef == objID) {
+ return data.refcon;
+ }
+ }
+
+ for (uint i = kInventoryStart; i < _inventoryWindows.size() + kInventoryStart; i++) {
+ const WindowData &data = getWindowData((WindowReference)i);
+ if (data.objRef == objID) {
+ return data.refcon;
+ }
+ }
+
+ return kNoWindow;
+}
+
+void Gui::checkSelect(const WindowData &data, Common::Point pos, const Common::Rect &clickRect, WindowReference ref) {
+ ObjID child = 0;
+ for (Common::Array<DrawableObject>::const_iterator it = data.children.begin(); it != data.children.end(); it++) {
+ if (canBeSelected((*it).obj, clickRect, ref)) {
+ child = (*it).obj;
+ }
+ }
+ if (child != 0) {
+ selectDraggable(child, ref, pos);
+ bringToFront(ref);
+ }
+}
+
+bool Gui::canBeSelected(ObjID obj, const Common::Rect &clickRect, WindowReference ref) {
+ return (_engine->isObjClickable(obj) &&
+ isRectInsideObject(clickRect, obj));
+}
+
+bool Gui::isRectInsideObject(Common::Rect target, ObjID obj) {
+ ensureAssetLoaded(obj);
+ Common::Rect bounds = _engine->getObjBounds(obj);
+ Common::Rect intersection = bounds.findIntersectingRect(target);
+ // We translate it to the image's coord system
+ intersection = Common::Rect(
+ intersection.left - bounds.left,
+ intersection.top - bounds.top,
+ intersection.left - bounds.left + intersection.width(),
+ intersection.top - bounds.top + intersection.height());
+
+ return _assets[obj]->isRectInside(intersection);
+}
+
+void Gui::selectDraggable(ObjID child, WindowReference origin, Common::Point click) {
+ if (_engine->isObjClickable(child) && _draggedObj.id == 0) {
+ _draggedObj.hasMoved = false;
+ _draggedObj.id = child;
+ _draggedObj.startWin = origin;
+ Common::Point localizedClick = click - getGlobalScrolledSurfacePosition(origin);
+ _draggedObj.mouseOffset = _engine->getObjPosition(child) - localizedClick;
+ _draggedObj.pos = click + _draggedObj.mouseOffset;
+ _draggedObj.startPos = _draggedObj.pos;
+ }
+}
+
+void Gui::handleDragRelease(bool shiftPressed, bool isDoubleClick) {
+ if (_draggedObj.id != 0) {
+ WindowReference destinationWindow = findWindowAtPoint(_draggedObj.pos);
+ if (destinationWindow == kNoWindow) {
+ return;
+ }
+ if (_draggedObj.hasMoved) {
+ const WindowData &destinationWindowData = getWindowData(destinationWindow);
+ ObjID destObject = destinationWindowData.objRef;
+ Common::Point dropPosition = _draggedObj.pos - _draggedObj.startPos;
+ dropPosition = localizeTravelledDistance(dropPosition, _draggedObj.startWin, destinationWindow);
+ debugC(3, kMVDebugGUI, "Drop the object %d at obj %d, pos (%d, %d)", _draggedObj.id, destObject, dropPosition.x, dropPosition.y);
+
+ _engine->handleObjectDrop(_draggedObj.id, dropPosition, destObject);
+ }
+ _engine->handleObjectSelect(_draggedObj.id, destinationWindow, shiftPressed, isDoubleClick);
+ _draggedObj.id = 0;
+ _draggedObj.hasMoved = false;
+ }
+}
+
+Common::Rect Gui::calculateClickRect(Common::Point clickPos, Common::Rect windowBounds) {
+ int left = clickPos.x - windowBounds.left;
+ int top = clickPos.y - windowBounds.top;
+ return Common::Rect(left - kCursorWidth, top - kCursorHeight, left + kCursorWidth, top + kCursorHeight);
+}
+
+Common::Point Gui::localizeTravelledDistance(Common::Point point, WindowReference origin, WindowReference target) {
+ if (origin != target) {
+ // ori.local to global
+ point += getGlobalScrolledSurfacePosition(origin);
+ if (findWindow(target)) {
+ // dest.globalToLocal
+ point -= getGlobalScrolledSurfacePosition(target);
+ }
+ }
+ return point;
+}
+
+void Gui::removeInventoryWindow(WindowReference ref) {
+ _inventoryWindows.remove_at(ref - kInventoryStart);
+ bool found = false;
+ Common::List<WindowData>::iterator it;
+ for (it = _windowData->begin(); it != _windowData->end() && !found; it++) {
+ if (it->refcon == ref) {
+ _windowData->erase(it);
+ found = true;
+ }
+ }
+}
+
+
+/* HANDLERS */
+void Gui::handleMenuAction(MenuAction action) {
+ switch (action) {
+ case MacVenture::kMenuActionAbout:
+ warning("Unimplemented MacVenture Menu Action: About");
+ break;
+ case MacVenture::kMenuActionNew:
+ _engine->newGame();
+ break;
+ case MacVenture::kMenuActionOpen:
+ loadGame();
+ break;
+ case MacVenture::kMenuActionSave:
+ saveGame();
+ break;
+ case MacVenture::kMenuActionSaveAs:
+ saveGame();
+ break;
+ case MacVenture::kMenuActionQuit:
+ _engine->requestQuit();
+ break;
+ case MacVenture::kMenuActionUndo:
+ warning("Unimplemented MacVenture Menu Action: Undo");
+ break;
+ case MacVenture::kMenuActionCut:
+ warning("Unimplemented MacVenture Menu Action: Cut");
+ break;
+ case MacVenture::kMenuActionCopy:
+ warning("Unimplemented MacVenture Menu Action: Copy");
+ break;
+ case MacVenture::kMenuActionPaste:
+ warning("Unimplemented MacVenture Menu Action: Paste");
+ break;
+ case MacVenture::kMenuActionClear:
+ warning("Unimplemented MacVenture Menu Action: Clear");
+ break;
+ case MacVenture::kMenuActionCleanUp:
+ warning("Unimplemented MacVenture Menu Action: Clean Up");
+ break;
+ case MacVenture::kMenuActionMessUp:
+ warning("Unimplemented MacVenture Menu Action: Mess Up");
+ break;
+ case MacVenture::kMenuActionCommand:
+ warning("Unimplemented MacVenture Menu Action: GENERIC");
+ break;
+ default:
+ break;
+ }
+}
+
+/* CALLBACKS */
+
+bool commandsWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+ return g->processCommandEvents(click, event);
+}
+
+bool mainGameWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+ return g->processMainGameEvents(click, event);
+}
+
+bool outConsoleWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+ return g->processOutConsoleEvents(click, event);
+}
+
+bool selfWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+
+ return g->processSelfEvents(click, event);
+}
+
+bool exitsWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+
+ return g->processExitsEvents(click, event);
+}
+
+bool diplomaWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+
+ return g->processDiplomaEvents(click, event);
+}
+
+bool inventoryWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+
+ return g->processInventoryEvents(click, event);
+}
+
+void menuCommandsCallback(int action, Common::String &text, void *data) {
+ Gui *g = (Gui *)data;
+
+ g->handleMenuAction((MenuAction)action);
+}
+
+
+void Gui::invertWindowColors(WindowReference winID) {
+ Graphics::ManagedSurface *srf = findWindow(winID)->getSurface();
+ for (uint y = 0; y < srf->h; y++) {
+ for (uint x = 0; x < srf->w; x++) {
+ byte p = *(byte *)srf->getBasePtr(x, y);
+ *(byte *)srf->getBasePtr(x, y) =
+ (p == kColorWhite) ? kColorBlack : kColorGray;
+ }
+ }
+}
+
+bool Gui::tryCloseWindow(WindowReference winID) {
+ WindowData data = findWindowData(winID);
+ Graphics::MacWindow *win = findWindow(winID);
+ _wm.removeWindow(win);
+ if (winID < 0x80) {
+ removeInventoryWindow(winID);
+ }
+ return true;
+}
+
+Common::Point Gui::getObjMeasures(ObjID obj) {
+ ensureAssetLoaded(obj);
+ int w = _assets[obj]->getWidth();
+ int h = _assets[obj]->getHeight();
+ return Common::Point(w, h);
+}
+
+bool Gui::processEvent(Common::Event &event) {
+ bool processed = false;
+
+ processed |= _cursor->processEvent(event);
+
+ if (_dialog && _dialog->processEvent(event)) {
+ return true;
+ }
+
+ if (event.type == Common::EVENT_MOUSEMOVE) {
+ if (_draggedObj.id != 0) {
+ moveDraggedObject(event.mouse);
+ }
+ processed = true;
+ }
+
+ processed |= _wm.processEvent(event);
+ return (processed);
+}
+
+bool Gui::processCommandEvents(WindowClick click, Common::Event &event) {
+ if (event.type == Common::EVENT_LBUTTONUP) {
+ if (_engine->needsClickToContinue()) {
+ _engine->selectControl(kClickToContinue);
+ return true;
+ }
+
+ Common::Point position(
+ event.mouse.x - _controlsWindow->getDimensions().left,
+ event.mouse.y - _controlsWindow->getDimensions().top);
+
+ CommandButton data;
+ if (!_controlData)
+ return false;
+
+ Common::Array<CommandButton>::iterator it = _controlData->begin();
+ for (; it != _controlData->end(); ++it) {
+ if (it->isInsideBounds(position)) {
+ it->select();
+ data = *it;
+ } else {
+ it->unselect();
+ }
+ }
+
+ _engine->selectControl(data.getData().refcon);
+ _engine->refreshReady();
+ _engine->preparedToRun();
+ }
+ return false;
+}
+
+bool MacVenture::Gui::processMainGameEvents(WindowClick click, Common::Event &event) {
+ if (_engine->needsClickToContinue())
+ return true;
+
+ return false;
+}
+
+bool MacVenture::Gui::processOutConsoleEvents(WindowClick click, Common::Event &event) {
+ if (_engine->needsClickToContinue())
+ return true;
+
+ if (click == kBorderScrollUp && event.type == Common::EVENT_LBUTTONDOWN) {
+ _consoleText->scrollUp();
+ return true;
+ }
+ if (click == kBorderScrollDown && event.type == Common::EVENT_LBUTTONDOWN) {
+ _consoleText->scrollDown();
+ return true;
+ }
+
+ return getWindowData(kOutConsoleWindow).visible;
+}
+
+bool MacVenture::Gui::processSelfEvents(WindowClick click, Common::Event &event) {
+ if (_engine->needsClickToContinue())
+ return true;
+
+ if (event.type == Common::EVENT_LBUTTONUP) {
+ _engine->handleObjectSelect(1, kSelfWindow, false, false);
+ }
+ return true;
+}
+
+bool MacVenture::Gui::processExitsEvents(WindowClick click, Common::Event &event) {
+ if (event.type == Common::EVENT_LBUTTONUP) {
+ if (_engine->needsClickToContinue()) {
+ return true;
+ }
+
+ Common::Point position(
+ event.mouse.x - _exitsWindow->getDimensions().left,
+ event.mouse.y - _exitsWindow->getDimensions().top);
+
+ CommandButton button;
+ if (!_exitsData)
+ return false;
+
+ Common::Array<CommandButton>::iterator it = _exitsData->begin();
+ for (; it != _exitsData->end(); ++it) {
+ if (it->isInsideBounds(position)) {
+ it->select();
+ button = *it;
+ _engine->handleObjectSelect(button.getData().refcon, kExitsWindow, false, false);
+ return true;
+ } else {
+ it->unselect();
+ }
+ }
+
+ }
+ return getWindowData(kExitsWindow).visible;
+}
+
+bool MacVenture::Gui::processDiplomaEvents(WindowClick click, Common::Event &event) {
+ if (_engine->needsClickToContinue())
+ return true;
+
+ return getWindowData(kDiplomaWindow).visible;
+}
+
+bool Gui::processInventoryEvents(WindowClick click, Common::Event &event) {
+ if (event.type == Common::EVENT_LBUTTONDOWN && click == kBorderCloseButton) {
+ WindowReference ref = findWindowAtPoint(event.mouse);
+ if (ref == kNoWindow) {
+ return false;
+ }
+
+ if (click == kBorderCloseButton) {
+ removeInventoryWindow(ref);
+ return true;
+ }
+ }
+
+ if (_engine->needsClickToContinue())
+ return true;
+
+ if (event.type == Common::EVENT_LBUTTONDOWN) {
+ // Find the appropriate window
+ WindowReference ref = findWindowAtPoint(event.mouse);
+ if (ref == kNoWindow) {
+ return false;
+ }
+
+ WindowData &data = findWindowData((WindowReference) ref);
+
+ if (click == kBorderScrollUp) {
+ data.scrollPos.y = MAX(0, data.scrollPos.y - kScrollAmount);
+ }
+ if (click == kBorderScrollDown) {
+ data.scrollPos.y += kScrollAmount;
+ }
+ if (click == kBorderScrollLeft) {
+ data.scrollPos.x = MAX(0, data.scrollPos.x - kScrollAmount);
+ }
+ if (click == kBorderScrollRight) {
+ data.scrollPos.x += kScrollAmount;
+ }
+ }
+ return true;
+}
+
+void Gui::selectForDrag(Common::Point cursorPosition) {
+ WindowReference ref = findWindowAtPoint(cursorPosition);
+ if (ref == kNoWindow) {
+ return;
+ }
+
+ Graphics::MacWindow *win = findWindow(ref);
+ WindowData &data = findWindowData((WindowReference) ref);
+
+ Common::Rect clickRect = calculateClickRect(cursorPosition + data.scrollPos, win->getDimensions());
+ checkSelect(data, cursorPosition, clickRect, (WindowReference)ref);
+}
+
+void Gui::handleSingleClick() {
+ debugC(2, kMVDebugGUI, "Registered Single Click");
+ // HACK THERE HAS TO BE A MORE ELEGANT WAY
+ if (_dialog) {
+ return;
+ }
+ handleDragRelease(false, false);
+}
+
+void Gui::handleDoubleClick() {
+ debugC(2, kMVDebugGUI, "Registered Double Click");
+ if (_dialog) {
+ return;
+ }
+ handleDragRelease(false, true);
+}
+
+void Gui::ensureAssetLoaded(ObjID obj) {
+ if (!_assets.contains(obj)) {
+ _assets[obj] = new ImageAsset(obj, _graphics);
+ }
+}
+
+
+} // End of namespace MacVenture