diff options
Diffstat (limited to 'engines/wage/gui.cpp')
-rw-r--r-- | engines/wage/gui.cpp | 389 |
1 files changed, 189 insertions, 200 deletions
diff --git a/engines/wage/gui.cpp b/engines/wage/gui.cpp index 387731cc18..b9635fb086 100644 --- a/engines/wage/gui.cpp +++ b/engines/wage/gui.cpp @@ -50,12 +50,15 @@ #include "graphics/cursorman.h" #include "graphics/fonts/bdf.h" #include "graphics/palette.h" +#include "graphics/primitives.h" #include "wage/wage.h" #include "wage/design.h" #include "wage/entities.h" -#include "wage/menu.h" #include "wage/gui.h" +#include "wage/macwindow.h" +#include "wage/macwindowmanager.h" +#include "wage/menu.h" #include "wage/world.h" namespace Wage { @@ -64,7 +67,8 @@ static const byte palette[] = { 0, 0, 0, // Black 0x80, 0x80, 0x80, // Gray 0xff, 0xff, 0xff, // White - 0x00, 0xff, 0x00 // Green + 0x00, 0xff, 0x00, // Green + 0x00, 0xcf, 0x00 // Green2 }; static byte fillPatterns[][8] = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, // kPatternSolid @@ -139,22 +143,25 @@ static void cursorTimerHandler(void *refCon) { gui->_cursorDirty = true; } +static bool sceneWindowCallback(WindowClick click, Common::Event &event, void *gui); +static bool consoleWindowCallback(WindowClick click, Common::Event &event, void *gui); + Gui::Gui(WageEngine *engine) { _engine = engine; _scene = NULL; _sceneDirty = true; _consoleDirty = true; - _bordersDirty = true; _menuDirty = true; _cursorDirty = false; _consoleFullRedraw = true; _screen.create(g_system->getWidth(), g_system->getHeight(), Graphics::PixelFormat::createFormatCLUT8()); + _wm.setScreen(&_screen); + _scrollPos = 0; _consoleLineHeight = 8; // Dummy value which makes sense _consoleNumLines = 24; // Dummy value _builtInFonts = false; - _sceneIsActive = false; _cursorX = 0; _cursorY = 0; @@ -167,7 +174,7 @@ Gui::Gui(WageEngine *engine) { _inputTextLineNum = 0; - g_system->getPaletteManager()->setPalette(palette, 0, 4); + g_system->getPaletteManager()->setPalette(palette, 0, ARRAYSIZE(palette) / 3); CursorMan.replaceCursorPalette(palette, 0, 4); CursorMan.replaceCursor(macCursorArrow, 11, 16, 1, 1, 3); @@ -182,6 +189,12 @@ Gui::Gui(WageEngine *engine) { g_system->getTimerManager()->installTimerProc(&cursorTimerHandler, 200000, this, "wageCursor"); _menu = new Menu(this); + + _sceneWindow = _wm.add(false); + _sceneWindow->setCallback(sceneWindowCallback, this); + + _consoleWindow = _wm.add(true); + _consoleWindow->setCallback(consoleWindowCallback, this); } Gui::~Gui() { @@ -237,38 +250,30 @@ void Gui::draw() { return; } - if (_scene != _engine->_world->_player->_currentScene || _sceneDirty) { - _scene = _engine->_world->_player->_currentScene; - - drawDesktop(); + if (!_engine->_world->_player->_currentScene) + return; + if (_scene != _engine->_world->_player->_currentScene) { _sceneDirty = true; - _consoleDirty = true; - _menuDirty = true; - _consoleFullRedraw = true; - - _scene->paint(&_screen, _scene->_designBounds->left, _scene->_designBounds->top); - _sceneArea.left = _scene->_designBounds->left + kBorderWidth - 2; - _sceneArea.top = _scene->_designBounds->top + kBorderWidth - 2; - _sceneArea.setWidth(_scene->_designBounds->width() - 2 * kBorderWidth); - _sceneArea.setHeight(_scene->_designBounds->height() - 2 * kBorderWidth); + _scene = _engine->_world->_player->_currentScene; - _consoleTextArea.left = _scene->_textBounds->left + kBorderWidth - 2; - _consoleTextArea.top = _scene->_textBounds->top + kBorderWidth - 2; - _consoleTextArea.setWidth(_scene->_textBounds->width() - 2 * kBorderWidth); - _consoleTextArea.setHeight(_scene->_textBounds->height() - 2 * kBorderWidth); + _sceneWindow->setDimensions(*_scene->_designBounds); + _sceneWindow->setTitle(_scene->_name); + _sceneWindow->setDirty(true); + _consoleWindow->setDimensions(*_scene->_textBounds); + _consoleWindow->setDirty(true); } - if (_scene && (_bordersDirty || _sceneDirty)) - paintBorder(&_screen, _sceneArea, kWindowScene); + if (_sceneDirty) { + drawDesktop(); + _wm.setFullRefresh(true); + } - // Render console - if (_consoleDirty || _consoleFullRedraw) - renderConsole(&_screen, _consoleTextArea); + drawScene(); + drawConsole(); - if (_bordersDirty || _consoleDirty || _consoleFullRedraw) - paintBorder(&_screen, _consoleTextArea, kWindowConsole); + _wm.draw(); if (_menuDirty) _menu->render(); @@ -282,133 +287,156 @@ void Gui::draw() { _sceneDirty = false; _consoleDirty = false; - _bordersDirty = false; _menuDirty = false; _consoleFullRedraw = false; } -void Gui::drawBox(Graphics::Surface *g, int x, int y, int w, int h) { - Common::Rect r(x, y, x + w + 1, y + h + 1); +void Gui::drawScene() { + if (!_sceneDirty) + return; + + _scene->paint(_sceneWindow->getSurface(), 0, 0); + _sceneWindow->setDirty(true); + + _sceneDirty = true; + _consoleDirty = true; + _menuDirty = true; + _consoleFullRedraw = true; - g->fillRect(r, kColorWhite); - g->frameRect(r, kColorBlack); + _consoleTextArea.left = _scene->_textBounds->left + kBorderWidth - 2; + _consoleTextArea.top = _scene->_textBounds->top + kBorderWidth - 2; + _consoleTextArea.setWidth(_scene->_textBounds->width() - 2 * kBorderWidth); + _consoleTextArea.setHeight(_scene->_textBounds->height() - 2 * kBorderWidth); } -void Gui::fillRect(Graphics::Surface *g, int x, int y, int w, int h) { - Common::Rect r(x, y, x + w, y + h); +static bool sceneWindowCallback(WindowClick click, Common::Event &event, void *g) { + Gui *gui = (Gui *)g; - g->fillRect(r, kColorBlack); + return gui->processSceneEvents(click, event); } -#define ARROW_W 12 -#define ARROW_H 6 -const int arrowPixels[ARROW_H][ARROW_W] = { - {0,0,0,0,0,1,1,0,0,0,0,0}, - {0,0,0,0,1,1,1,1,0,0,0,0}, - {0,0,0,1,1,1,1,1,1,0,0,0}, - {0,0,1,1,1,1,1,1,1,1,0,0}, - {0,1,1,1,1,1,1,1,1,1,1,0}, - {1,1,1,1,1,1,1,1,1,1,1,1}}; - -void Gui::paintBorder(Graphics::Surface *g, Common::Rect &r, WindowType windowType) { - bool active = false, scrollable = false, closeable = false, closeBoxPressed = false, drawTitle = false; - const int size = kBorderWidth; - int x = r.left - size; - int y = r.top - size; - int width = r.width() + 2 * size; - int height = r.height() + 2 * size; - - switch (windowType) { - case kWindowScene: - active = _sceneIsActive; - scrollable = false; - closeable = _sceneIsActive; - closeBoxPressed = false; - drawTitle = true; - break; - case kWindowConsole: - active = !_sceneIsActive; - scrollable = true; - closeable = !_sceneIsActive; - closeBoxPressed = false; - drawTitle = false; - break; +bool Gui::processSceneEvents(WindowClick click, Common::Event &event) { + if (_cursorIsArrow == false) { + CursorMan.replaceCursor(macCursorArrow, 11, 16, 1, 1, 3); + _cursorIsArrow = true; } - drawBox(g, x, y, size, size); - drawBox(g, x + width - size - 1, y, size, size); - drawBox(g, x + width - size - 1, y + height - size - 1, size, size); - drawBox(g, x, y + height - size - 1, size, size); - drawBox(g, x + size, y + 2, width - 2 * size - 1, size - 4); - drawBox(g, x + size, y + height - size + 1, width - 2 * size - 1, size - 4); - drawBox(g, x + 2, y + size, size - 4, height - 2 * size - 1); - drawBox(g, x + width - size + 1, y + size, size - 4, height - 2 * size - 1); - - if (active) { - fillRect(g, x + size, y + 5, width - 2 * size - 1, 8); - fillRect(g, x + size, y + height - 13, width - 2 * size - 1, 8); - fillRect(g, x + 5, y + size, 8, height - 2 * size - 1); - if (!scrollable) { - fillRect(g, x + width - 13, y + size, 8, height - 2 * size - 1); - } else { - int x1 = x + width - 15; - int y1 = y + size + 1; - for (int yy = 0; yy < ARROW_H; yy++) { - for (int xx = 0; xx < ARROW_W; xx++) { - if (arrowPixels[yy][xx] != 0) { - g->hLine(x1 + xx, y1 + yy, x1 + xx, kColorBlack); - } else { - g->hLine(x1 + xx, y1 + yy, x1 + xx, kColorWhite); - } - } - } - fillRect(g, x + width - 13, y + size + ARROW_H, 8, height - 2 * size - 1 - ARROW_H * 2); - y1 += height - 2 * size - ARROW_H - 2; - for (int yy = 0; yy < ARROW_H; yy++) { - for (int xx = 0; xx < ARROW_W; xx++) { - if (arrowPixels[ARROW_H - yy - 1][xx] != 0) { - g->hLine(x1 + xx, y1 + yy, x1 + xx, kColorBlack); - } else { - g->hLine(x1 + xx, y1 + yy, x1 + xx, kColorWhite); - } - } - } - } - if (closeable) { - if (closeBoxPressed) { - fillRect(g, x + 6, y + 6, 6, 6); - } else { - drawBox(g, x + 5, y + 5, 7, 7); - } - } + if (click == kBorderInner && event.type == Common::EVENT_LBUTTONUP) { + Designed *obj = _scene->lookUpEntity(event.mouse.x - _sceneWindow->getDimensions().left, + event.mouse.y - _sceneWindow->getDimensions().top); + + if (obj != nullptr) + _engine->processTurn(NULL, obj); + + return true; } - if (drawTitle) { - const Graphics::Font *font = getTitleFont(); - int yOff = _builtInFonts ? 3 : 1; + return false; +} + +// Render console +void Gui::drawConsole() { + if (!_consoleDirty && !_consoleFullRedraw && !_sceneDirty) + return; - int w = font->getStringWidth(_scene->_name) + 10; - int maxWidth = width - size * 2 - 7; - if (w > maxWidth) - w = maxWidth; - drawBox(g, x + (width - w) / 2, y, w, size); - font->drawString(g, _scene->_name, x + (width - w) / 2 + 5, y + yOff, w, kColorBlack); + renderConsole(_consoleWindow->getSurface(), Common::Rect(kBorderWidth - 2, kBorderWidth - 2, + _scene->_textBounds->width() - kBorderWidth, _scene->_textBounds->height() - kBorderWidth)); + _consoleWindow->setDirty(true); +} + +static bool consoleWindowCallback(WindowClick click, Common::Event &event, void *g) { + Gui *gui = (Gui *)g; + + return gui->processConsoleEvents(click, event); +} + +bool Gui::processConsoleEvents(WindowClick click, Common::Event &event) { + if (click != kBorderInner && _cursorIsArrow == false) { + CursorMan.replaceCursor(macCursorArrow, 11, 16, 1, 1, 3); + _cursorIsArrow = true; } - if (x < 0) { - width += x; - x = 0; + if (click == kBorderScrollUp || click == kBorderScrollDown) { + if (event.type == Common::EVENT_LBUTTONDOWN) { + int textFullSize = _lines.size() * _consoleLineHeight + _consoleTextArea.height(); + float scrollPos = (float)_scrollPos / textFullSize; + float scrollSize = (float)_consoleTextArea.height() / textFullSize; + + _consoleWindow->setScroll(scrollPos, scrollSize); + + return true; + } else if (event.type == Common::EVENT_LBUTTONUP) { + int oldScrollPos = _scrollPos; + + switch (click) { + case kBorderScrollUp: + _scrollPos = MAX<int>(0, _scrollPos - _consoleLineHeight); + undrawCursor(); + _cursorY -= (_scrollPos - oldScrollPos); + _consoleDirty = true; + _consoleFullRedraw = true; + break; + case kBorderScrollDown: + _scrollPos = MIN<int>((_lines.size() - 2) * _consoleLineHeight, _scrollPos + _consoleLineHeight); + undrawCursor(); + _cursorY -= (_scrollPos - oldScrollPos); + _consoleDirty = true; + _consoleFullRedraw = true; + break; + default: + return false; + } + + return true; + } + + return false; } - if (y < 0) { - height += y; - y = 0; + + if (click == kBorderInner) { + if (event.type == Common::EVENT_LBUTTONDOWN) { + startMarking(event.mouse.x, event.mouse.y); + + return true; + } else if (event.type == Common::EVENT_LBUTTONUP) { + if (_inTextSelection) { + _inTextSelection = false; + + if (_selectionEndY == -1 || + (_selectionEndX == _selectionStartX && _selectionEndY == _selectionStartY)) { + _selectionStartY = _selectionEndY = -1; + _consoleFullRedraw = true; + _menu->enableCommand(kMenuEdit, kMenuActionCopy, false); + } else { + _menu->enableCommand(kMenuEdit, kMenuActionCopy, true); + + bool cutAllowed = false; + + if (_selectionStartY == _selectionEndY && _selectionStartY == (int)_lines.size() - 1) + cutAllowed = true; + + _menu->enableCommand(kMenuEdit, kMenuActionCut, cutAllowed); + _menu->enableCommand(kMenuEdit, kMenuActionClear, cutAllowed); + } + } + + return true; + } else if (event.type == Common::EVENT_MOUSEMOVE) { + if (_inTextSelection) { + updateTextSelection(event.mouse.x, event.mouse.y); + return true; + } + + if (_cursorIsArrow) { + CursorMan.replaceCursor(macCursorBeam, 11, 16, 3, 8, 3); + _cursorIsArrow = false; + } + } + + return false; } - if (x + width > _screen.w) - width = _screen.w - x; - if (y + height > _screen.h) - height = _screen.h - y; - g_system->copyRectToScreen(g->getBasePtr(x, y), g->pitch, x, y, width, height); + return false; } void Gui::loadFonts() { @@ -474,21 +502,6 @@ void Gui::mouseMove(int x, int y) { return; } - - if (_inTextSelection) { - updateTextSelection(x, y); - return; - } - - if (_consoleTextArea.contains(x, y)) { - if (_cursorIsArrow) { - CursorMan.replaceCursor(macCursorBeam, 11, 16, 3, 8, 3); - _cursorIsArrow = false; - } - } else if (_cursorIsArrow == false) { - CursorMan.replaceCursor(macCursorArrow, 11, 16, 1, 1, 3); - _cursorIsArrow = true; - } } void Gui::pushArrowCursor() { @@ -499,69 +512,45 @@ void Gui::popCursor() { CursorMan.popCursor(); } -Designed *Gui::mouseUp(int x, int y) { - if (_menu->_menuActivated) { - if (_menu->mouseRelease(x, y)) { - _sceneDirty = true; - _consoleDirty = true; - _bordersDirty = true; - _menuDirty = true; - } - - return NULL; - } - - if (_inTextSelection) { - _inTextSelection = false; - - if (_selectionEndY == -1 || - (_selectionEndX == _selectionStartX && _selectionEndY == _selectionStartY)) { - _selectionStartY = _selectionEndY = -1; - _consoleFullRedraw = true; - _menu->enableCommand(kMenuEdit, kMenuActionCopy, false); - } else { - _menu->enableCommand(kMenuEdit, kMenuActionCopy, true); +bool Gui::processEvent(Common::Event &event) { + if (_wm.processEvent(event)) + return true; - bool cutAllowed = false; - - if (_selectionStartY == _selectionEndY && _selectionStartY == (int)_lines.size() - 1) - cutAllowed = true; + switch (event.type) { + case Common::EVENT_MOUSEMOVE: + mouseMove(event.mouse.x, event.mouse.y); + break; + case Common::EVENT_LBUTTONDOWN: + mouseDown(event.mouse.x, event.mouse.y); + break; + case Common::EVENT_LBUTTONUP: + mouseUp(event.mouse.x, event.mouse.y); + break; - _menu->enableCommand(kMenuEdit, kMenuActionCut, cutAllowed); - _menu->enableCommand(kMenuEdit, kMenuActionClear, cutAllowed); - } + default: + return false; } - if (_sceneArea.contains(x, y)) { - if (!_sceneIsActive) { - _sceneIsActive = true; - _bordersDirty = true; - } + return true; +} - for (ObjList::const_iterator it = _scene->_objs.begin(); it != _scene->_objs.end(); ++it) { - if ((*it)->_design->isPointOpaque(x - _sceneArea.left + kBorderWidth, y - _sceneArea.top + kBorderWidth)) - return *it; +void Gui::mouseUp(int x, int y) { + if (_menu->_menuActivated) { + if (_menu->mouseRelease(x, y)) { + _sceneDirty = true; + _consoleDirty = true; + _menuDirty = true; } - for (ChrList::const_iterator it = _scene->_chrs.begin(); it != _scene->_chrs.end(); ++it) { - if ((*it)->_design->isPointOpaque(x - _sceneArea.left + kBorderWidth, y - _sceneArea.top + kBorderWidth)) - return *it; - } - } else if (_consoleTextArea.contains(x, y)) { - if (_sceneIsActive) { - _sceneIsActive = false; - _bordersDirty = true; - } + return; } - return NULL; + return; } void Gui::mouseDown(int x, int y) { if (_menu->mouseClick(x, y)) { _menuDirty = true; - } else if (_consoleTextArea.contains(x, y)) { - startMarking(x, y); } } |