From c4bcb0882f6e8f7fba5c89b9a561bb91fb662f1a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 9 Nov 2018 18:34:04 -0800 Subject: GLK: Merge Clipboard and WindowMask into a new Selection class --- engines/gargoyle/clipboard.cpp | 51 ------ engines/gargoyle/clipboard.h | 48 ----- engines/gargoyle/events.cpp | 16 +- engines/gargoyle/gargoyle.cpp | 11 +- engines/gargoyle/gargoyle.h | 4 +- engines/gargoyle/module.mk | 2 +- engines/gargoyle/selection.cpp | 312 ++++++++++++++++++++++++++++++++ engines/gargoyle/selection.h | 119 ++++++++++++ engines/gargoyle/window_graphics.cpp | 8 +- engines/gargoyle/window_mask.cpp | 287 ----------------------------- engines/gargoyle/window_mask.h | 82 --------- engines/gargoyle/window_text_buffer.cpp | 30 +-- engines/gargoyle/window_text_grid.cpp | 10 +- engines/gargoyle/windows.h | 2 +- 14 files changed, 472 insertions(+), 510 deletions(-) delete mode 100644 engines/gargoyle/clipboard.cpp delete mode 100644 engines/gargoyle/clipboard.h create mode 100644 engines/gargoyle/selection.cpp create mode 100644 engines/gargoyle/selection.h delete mode 100644 engines/gargoyle/window_mask.cpp delete mode 100644 engines/gargoyle/window_mask.h (limited to 'engines') diff --git a/engines/gargoyle/clipboard.cpp b/engines/gargoyle/clipboard.cpp deleted file mode 100644 index 81ef12f5da..0000000000 --- a/engines/gargoyle/clipboard.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* 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 "gargoyle/clipboard.h" -#include "gargoyle/gargoyle.h" -#include "gargoyle/windows.h" -#include "common/system.h" - -namespace Gargoyle { - -void Clipboard::store(const uint32 *text, size_t len) { - // TODO -} - -void Clipboard::send(ClipSource source) { - // TODO -} - -void Clipboard::receive(ClipSource source) { - Windows &windows = *g_vm->_windows; - - if (g_system->hasTextInClipboard()) { - Common::String text = g_system->getTextFromClipboard(); - for (uint idx = 0; idx < text.size(); ++idx) { - uint c = text[idx]; - if (c != '\r' && c != '\n' && c != '\b' && c != '\t') - windows.inputHandleKey(c); - } - } -} - -} // End of namespace Gargoyle diff --git a/engines/gargoyle/clipboard.h b/engines/gargoyle/clipboard.h deleted file mode 100644 index 18519c736d..0000000000 --- a/engines/gargoyle/clipboard.h +++ /dev/null @@ -1,48 +0,0 @@ -/* 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. - * - */ - -#ifndef GARGOYLE_CLIPBOARD_H -#define GARGOYLE_CLIPBOARD_H - -#include "common/array.h" - -namespace Gargoyle { - -enum ClipSource { PRIMARY = 0, CLIPBOARD = 1 }; - -/** - * Handles selection of text, and copying to and from the clipboard - */ -class Clipboard { -private: - Common::Array _text; -public: - void store(const uint32 *text, size_t len); - - void send(ClipSource source); - - void receive(ClipSource source); -}; - -} // End of namespace Gargoyle - -#endif diff --git a/engines/gargoyle/events.cpp b/engines/gargoyle/events.cpp index 4618df4107..bc56407ee8 100644 --- a/engines/gargoyle/events.cpp +++ b/engines/gargoyle/events.cpp @@ -21,10 +21,10 @@ */ #include "gargoyle/events.h" -#include "gargoyle/clipboard.h" #include "gargoyle/conf.h" #include "gargoyle/gargoyle.h" #include "gargoyle/screen.h" +#include "gargoyle/selection.h" #include "gargoyle/windows.h" #include "graphics/cursorman.h" @@ -217,15 +217,15 @@ void Events::handleKeyDown(const Common::KeyState &ks) { if (ks.keycode == Common::KEYCODE_a) windows.inputHandleKey(keycode_Home); else if (ks.keycode == Common::KEYCODE_c) - clipboard.send(CLIPBOARD); + clipboard.clipboardSend(CLIPBOARD); else if (ks.keycode == Common::KEYCODE_e) windows.inputHandleKey(keycode_End); else if (ks.keycode == Common::KEYCODE_u) windows.inputHandleKey(keycode_Escape); else if (ks.keycode == Common::KEYCODE_v) - clipboard.receive(CLIPBOARD); + clipboard.clipboardReceive(CLIPBOARD); else if (ks.keycode == Common::KEYCODE_x) - clipboard.send(CLIPBOARD); + clipboard.clipboardSend(CLIPBOARD); else if (ks.keycode == Common::KEYCODE_LEFT || ks.keycode == Common::KEYCODE_KP4) windows.inputHandleKey(keycode_SkipWordLeft); else if (ks.keycode == Common::KEYCODE_RIGHT || ks.keycode == Common::KEYCODE_KP6) @@ -281,9 +281,9 @@ void Events::handleMouseMove(const Point &pos) { // TODO: Properly handle commented out lines if (g_vm->_copySelect) { //gdk_window_set_cursor((GTK_WIDGET(widget)->window), gdk_ibeam); - g_vm->_windowMask->moveSelection(pos); + g_vm->_selection->moveSelection(pos); } else { - if (g_vm->_windowMask->getHyperlink(pos)) { + if (g_vm->_selection->getHyperlink(pos)) { //gdk_window_set_cursor((GTK_WIDGET(widget)->window), gdk_hand); } else { //gdk_window_set_cursor((GTK_WIDGET(widget)->window), nullptr); @@ -296,7 +296,7 @@ void Events::handleButtonDown(bool isLeft, const Point &pos) { setCursor(CURSOR_IBEAM); g_vm->_windows->inputHandleClick(pos); } else { - g_vm->_clipboard->receive(PRIMARY); + g_vm->_clipboard->clipboardReceive(PRIMARY); } } @@ -304,7 +304,7 @@ void Events::handleButtonUp(bool isLeft, const Point &pos) { if (isLeft) { setCursor(CURSOR_ARROW); g_vm->_copySelect = false; - g_vm->_clipboard->send(PRIMARY); + g_vm->_clipboard->clipboardSend(PRIMARY); } } diff --git a/engines/gargoyle/gargoyle.cpp b/engines/gargoyle/gargoyle.cpp index 59a39b44aa..9c00937185 100644 --- a/engines/gargoyle/gargoyle.cpp +++ b/engines/gargoyle/gargoyle.cpp @@ -29,14 +29,13 @@ #include "graphics/scaler.h" #include "graphics/thumbnail.h" #include "gargoyle/gargoyle.h" -#include "gargoyle/clipboard.h" #include "gargoyle/conf.h" #include "gargoyle/events.h" #include "gargoyle/picture.h" #include "gargoyle/screen.h" +#include "gargoyle/selection.h" #include "gargoyle/streams.h" #include "gargoyle/windows.h" -#include "gargoyle/window_mask.h" namespace Gargoyle { @@ -44,8 +43,8 @@ GargoyleEngine *g_vm; GargoyleEngine::GargoyleEngine(OSystem *syst, const GargoyleGameDescription *gameDesc) : _gameDescription(gameDesc), Engine(syst), _random("Gargoyle"), _clipboard(nullptr), - _conf(nullptr), _events(nullptr), _picList(nullptr), _screen(nullptr), _windows(nullptr), - _windowMask(nullptr), _copySelect(false), _terminated(false), + _conf(nullptr), _events(nullptr), _picList(nullptr), _screen(nullptr), + _selection(nullptr), _windows(nullptr), _copySelect(false), _terminated(false), gli_unregister_obj(nullptr), gli_register_arr(nullptr), gli_unregister_arr(nullptr) { g_vm = this; } @@ -56,9 +55,9 @@ GargoyleEngine::~GargoyleEngine() { delete _events; delete _picList; delete _screen; + delete _selection; delete _streams; delete _windows; - delete _windowMask; } void GargoyleEngine::initialize() { @@ -75,9 +74,9 @@ void GargoyleEngine::initialize() { _clipboard = new Clipboard(); _events = new Events(); _picList = new PicList(); + _selection = new Selection(); _streams = new Streams(); _windows = new Windows(_screen); - _windowMask = new WindowMask(); } void GargoyleEngine::initGraphicsMode() { diff --git a/engines/gargoyle/gargoyle.h b/engines/gargoyle/gargoyle.h index f65ce943f1..793a353d08 100644 --- a/engines/gargoyle/gargoyle.h +++ b/engines/gargoyle/gargoyle.h @@ -38,9 +38,9 @@ class Conf; class Events; class PicList; class Screen; +class Selection; class Streams; class Windows; -class WindowMask; enum InterpreterType { INTERPRETER_ADVSYS = 0, @@ -109,9 +109,9 @@ public: Events *_events; PicList *_picList; Screen *_screen; + Selection *_selection; Streams *_streams; Windows *_windows; - WindowMask *_windowMask; bool _copySelect; bool _terminated; void (*gli_unregister_obj)(void *obj, glui32 objclass, gidispatch_rock_t objrock); diff --git a/engines/gargoyle/module.mk b/engines/gargoyle/module.mk index f4422b0b31..bf4138aadc 100644 --- a/engines/gargoyle/module.mk +++ b/engines/gargoyle/module.mk @@ -1,7 +1,6 @@ MODULE := engines/gargoyle MODULE_OBJS := \ - clipboard.o \ conf.o \ detection.o \ events.o \ @@ -10,6 +9,7 @@ MODULE_OBJS := \ glk.o \ picture.o \ screen.o \ + selection.o \ streams.o \ time.o \ unicode.o \ diff --git a/engines/gargoyle/selection.cpp b/engines/gargoyle/selection.cpp new file mode 100644 index 0000000000..2b72c1e6fc --- /dev/null +++ b/engines/gargoyle/selection.cpp @@ -0,0 +1,312 @@ +/* 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 "gargoyle/selection.h" +#include "gargoyle/conf.h" +#include "gargoyle/gargoyle.h" +#include "gargoyle/windows.h" +#include "common/system.h" + +namespace Gargoyle { + +void Clipboard::clipboardStore(const uint32 *text, size_t len) { + // TODO +} + +void Clipboard::clipboardSend(ClipSource source) { + // TODO +} + +void Clipboard::clipboardReceive(ClipSource source) { + Windows &windows = *g_vm->_windows; + + if (g_system->hasTextInClipboard()) { + Common::String text = g_system->getTextFromClipboard(); + for (uint idx = 0; idx < text.size(); ++idx) { + uint c = text[idx]; + if (c != '\r' && c != '\n' && c != '\b' && c != '\t') + windows.inputHandleKey(c); + } + } +} + +/*--------------------------------------------------------------------------*/ + +WindowMask::WindowMask() : _hor(0), _ver(0), _links(nullptr) { + _last.x = _last.y = 0; + resize(g_system->getWidth(), g_system->getHeight()); +} + +void WindowMask::resize(size_t x, size_t y) { + // Deallocate old storage + for (size_t i = 0; i < _hor; i++) { + if (_links[i]) + delete _links[i]; + } + + delete _links; + + _hor = x + 1; + _ver = y + 1; + + // allocate new storage + _links = new glui32 *[_hor]; + if (!_links) { + warning("resize_mask: out of memory"); + _hor = _ver = 0; + return; + } + + for (size_t i = 0; i < _hor; i++) { + _links[i] = new glui32[_ver]; + if (!_links[i]) { + warning("resize_mask: could not allocate new memory"); + return; + } + } + + _select.left = 0; + _select.top = 0; + _select.right = 0; + _select.bottom = 0; +} + +void WindowMask::putHyperlink(glui32 linkval, uint x0, uint y0, uint x1, uint y1) { + uint i, k; + size_t tx0 = x0 < x1 ? x0 : x1; + size_t tx1 = x0 < x1 ? x1 : x0; + size_t ty0 = y0 < y1 ? y0 : y1; + size_t ty1 = y0 < y1 ? y1 : y0; + + if (!_hor || !_ver) { + warning("putHyperlink: struct not initialized"); + return; + } + + if (tx0 >= _hor + || tx1 >= _hor + || ty0 >= _ver || ty1 >= _ver + || !_links[tx0] || !_links[tx1]) { + warning("putHyperlink: invalid range given"); + return; + } + + for (i = tx0; i < tx1; i++) { + for (k = ty0; k < ty1; k++) + _links[i][k] = linkval; + } +} + +glui32 WindowMask::getHyperlink(const Point &pos) const { + if (!_hor || !_ver) { + warning("getHyperlink: struct not initialized"); + return 0; + } + + if (pos.x >= (int16)_hor || pos.y >= (int16)_ver || !_links[pos.x]) { + warning("getHyperlink: invalid range given"); + return 0; + } + + return _links[pos.x][pos.y]; +} + +/*--------------------------------------------------------------------------*/ + +void Selection::startSelection(const Point &pos) { + int tx, ty; + + if (!_hor || !_ver) { + warning("startSelection: mask not initialized"); + return; + } + + tx = MIN(pos.x, (int16)_hor); + ty = MIN(pos.y, (int16)_ver); + + _select.left = _last.x = tx; + _select.top = _last.y = ty; + _select.right = 0; + _select.bottom = 0; + + g_vm->_windows->selectionChanged(); +} + +void Selection::moveSelection(const Point &pos) { + int tx, ty; + + if (ABS(pos.x - _last.x) < 5 && ABS(pos.y - _last.y) < 5) + return; + + if (!_hor || !_ver) { + warning("moveSelection: mask not initialized"); + return; + } + + tx = MIN(pos.x, (int16)_hor); + ty = MIN(pos.y, (int16)_ver); + + _select.right = _last.x = tx; + _select.bottom = _last.y = ty; + + g_vm->_windows->selectionChanged(); +} + +void Selection::clearSelection() { + if (!_select.isEmpty()) + Windows::_forceRedraw = true; + + _select = Rect(); + g_vm->_windows->clearClaimSelect(); +} + +bool Selection::checkSelection(const Rect &r) const { + Rect select(MIN(_select.left, _select.right), MAX(_select.left, _select.right), + MIN(_select.top, _select.bottom), MAX(_select.top, _select.bottom)); + if (select.isEmpty()) + return false; + + return select.intersects(r); +} + +bool Selection::getSelection(const Rect &r, int *rx0, int *rx1) const { + uint row, upper, lower, above, below; + bool row_selected, found_left, found_right; + int from_right, from_below, is_above, is_below; + uint cx0, cx1, cy0, cy1; + uint x0 = r.left, y0 = r.top, x1 = r.right, y1 = r.bottom; + + row = (y0 + y1) / 2; + upper = row - (row - y0) / 2; + lower = row + (y1 - row) / 2; + above = upper - (g_conf->_leading) / 2; + below = lower + (g_conf->_leading) / 2; + + cx0 = MIN(_select.left, _select.right); + cx1 = MAX(_select.left, _select.right); + cy0 = MIN(_select.top, _select.bottom); + cy1 = MAX(_select.top, _select.bottom); + + row_selected = false; + + if ((cy0 >= upper && cy0 <= lower) + || (cy1 >= upper && cy1 <= lower)) + row_selected = true; + + if (row >= cy0 && row <= cy1) + row_selected = true; + + if (!row_selected) + return false; + + from_right = (_select.left != (int16)cx0); + from_below = (_select.top != (int16)cy0); + is_above = (above >= cy0 && above <= cy1); + is_below = (below >= cy0 && below <= cy1); + + *rx0 = 0; + *rx1 = 0; + + found_left = false; + found_right = false; + + if (is_above && is_below) { + *rx0 = x0; + *rx1 = x1; + found_left = true; + found_right = true; + } else if (!is_above && is_below) { + if (from_below) { + if (from_right) { + *rx0 = cx0; + *rx1 = x1; + found_left = true; + found_right = true; + } else { + *rx0 = cx1; + *rx1 = x1; + found_left = true; + found_right = true; + } + } else { + if (from_right) { + *rx0 = cx1; + *rx1 = x1; + found_left = true; + found_right = true; + } else { + *rx1 = x1; + found_right = true; + } + } + } else if (is_above && !is_below) { + if (from_below) { + if (from_right) { + *rx0 = x0; + *rx1 = cx1; + found_left = true; + found_right = true; + } else { + *rx0 = x0; + *rx1 = cx0; + found_left = true; + found_right = true; + } + } else { + if (from_right) { + if (x0 > cx0) + return false; + *rx0 = x0; + *rx1 = cx0; + found_left = true; + found_right = true; + } else { + *rx0 = x0; + found_left = true; + } + } + } + + if (found_left && found_right) + return true; + + for (uint i = x0; i <= x1; i++) { + if (i >= cx0 && i <= cx1) { + if (!found_left) { + *rx0 = i; + found_left = true; + if (found_right) + return true; + } else { + if (!found_right) + *rx1 = i; + } + } + } + + if (rx0 && !rx1) + *rx1 = x1; + + return (rx0 && rx1); +} + +} // End of namespace Gargoyle diff --git a/engines/gargoyle/selection.h b/engines/gargoyle/selection.h new file mode 100644 index 0000000000..bc56319256 --- /dev/null +++ b/engines/gargoyle/selection.h @@ -0,0 +1,119 @@ +/* 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. + * + */ + +#ifndef GARGOYLE_SELECTION_H +#define GARGOYLE_SELECTION_H + +#include "gargoyle/glk_types.h" +#include "gargoyle/utils.h" +#include "common/array.h" +#include "common/rect.h" + +namespace Gargoyle { + +enum ClipSource { PRIMARY = 0, CLIPBOARD = 1 }; + +class Window; + +/** + * Acts as interface to and from the system's clipboard storage + */ +class Clipboard { +private: + Common::Array _text; +public: + /** + * Makes a copy of selected text in preparation for the user copying it + * to the clpboard + */ + void clipboardStore(const uint32 *text, size_t len); + + /** + * Send previously designated text to the clipboard + */ + void clipboardSend(ClipSource source); + + /** + * Receive text from the clipboard, and paste it into the current window + */ + void clipboardReceive(ClipSource source); +}; + +/** + * Manages hyperlinks for the screen + */ +class WindowMask { +public: + size_t _hor, _ver; + glui32 **_links; + Rect _select; + Point _last; +public: + /** + * Constructor + */ + WindowMask(); + + /** + * Resize the links array + */ + void resize(size_t x, size_t y); + + void putHyperlink(glui32 linkval, uint x0, uint y0, uint x1, uint y1); + + glui32 getHyperlink(const Point &pos) const; +}; + +/** + * Overall manager for selecting areas on the screen, copying to/from the clipboard, + * and managing hyperlinks + */ +class Selection : public Clipboard, public WindowMask { +public: + /** + * Start selecting an area of the screen + * @param pos Position to start selection area at + */ + void startSelection(const Point &pos); + + /** + * Move the end point of the selection area + * @param pos Position to end selection area at + */ + void moveSelection(const Point &pos); + + /** + * Remove any previously selected area + */ + void clearSelection(); + + /** + * Checks whether the passed area intersects the selection area + */ + bool checkSelection(const Rect &r) const; + + bool getSelection(const Rect &r, int *rx0, int *rx1) const; +}; + +} // End of namespace Gargoyle + +#endif diff --git a/engines/gargoyle/window_graphics.cpp b/engines/gargoyle/window_graphics.cpp index 3286876cb7..a0d8b6ddba 100644 --- a/engines/gargoyle/window_graphics.cpp +++ b/engines/gargoyle/window_graphics.cpp @@ -147,7 +147,7 @@ void GraphicsWindow::eraseRect(bool whole, const Rect &box) { hy1 = _bbox.top + y1; /* zero out hyperlinks for these coordinates */ - g_vm->_windowMask->putHyperlink(0, hx0, hy0, hx1, hy1); + g_vm->_selection->putHyperlink(0, hx0, hy0, hx1, hy1); _surface->fillRect(Rect(x0, y0, x1, y1), MKTAG(_bgnd[0], _bgnd[1], _bgnd[2], 0)); touch(); @@ -177,7 +177,7 @@ void GraphicsWindow::fillRect(glui32 color, const Rect &box) { hy1 = _bbox.top + y1; /* zero out hyperlinks for these coordinates */ - g_vm->_windowMask->putHyperlink(0, hx0, hy0, hx1, hy1); + g_vm->_selection->putHyperlink(0, hx0, hy0, hx1, hy1); _surface->fillRect(Rect(x0, y0, x1, y1), MKTAG(col[0], col[1], col[2], 0)); touch(); @@ -229,7 +229,7 @@ void GraphicsWindow::drawPicture(Picture *src, int x0, int y0, int width, int h hy1 = _bbox.top + y1; /* zero out or set hyperlink for these coordinates */ - g_vm->_windowMask->putHyperlink(linkval, hx0, hy0, hx1, hy1); + g_vm->_selection->putHyperlink(linkval, hx0, hy0, hx1, hy1); w = sx1 - sx0; h = sy1 - sy0; @@ -259,7 +259,7 @@ void GraphicsWindow::click(const Point &newPos) { } if (_hyperRequest) { - glui32 linkval = g_vm->_windowMask->getHyperlink(newPos); + glui32 linkval = g_vm->_selection->getHyperlink(newPos); if (linkval) { g_vm->_events->store(evtype_Hyperlink, this, linkval, 0); _hyperRequest = false; diff --git a/engines/gargoyle/window_mask.cpp b/engines/gargoyle/window_mask.cpp deleted file mode 100644 index 495abc68af..0000000000 --- a/engines/gargoyle/window_mask.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* 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 "gargoyle/window_mask.h" -#include "gargoyle/conf.h" -#include "gargoyle/gargoyle.h" -#include "gargoyle/windows.h" -#include "common/system.h" - -namespace Gargoyle { - -WindowMask::WindowMask() : _hor(0), _ver(0), _links(nullptr) { - _last.x = _last.y = 0; - resize(g_system->getWidth(), g_system->getHeight()); -} - -void WindowMask::resize(size_t x, size_t y) { - // Deallocate old storage - for (size_t i = 0; i < _hor; i++) { - if (_links[i]) - delete _links[i]; - } - - delete _links; - - _hor = x + 1; - _ver = y + 1; - - // allocate new storage - _links = new glui32 *[_hor]; - if (!_links) { - warning("resize_mask: out of memory"); - _hor = _ver = 0; - return; - } - - for (size_t i = 0; i < _hor; i++) { - _links[i] = new glui32[_ver]; - if (!_links[i]) { - warning("resize_mask: could not allocate new memory"); - return; - } - } - - _select.left = 0; - _select.top = 0; - _select.right = 0; - _select.bottom = 0; -} - -void WindowMask::putHyperlink(glui32 linkval, uint x0, uint y0, uint x1, uint y1) { - uint i, k; - size_t tx0 = x0 < x1 ? x0 : x1; - size_t tx1 = x0 < x1 ? x1 : x0; - size_t ty0 = y0 < y1 ? y0 : y1; - size_t ty1 = y0 < y1 ? y1 : y0; - - if (!_hor || !_ver) { - warning("putHyperlink: struct not initialized"); - return; - } - - if (tx0 >= _hor - || tx1 >= _hor - || ty0 >= _ver || ty1 >= _ver - || !_links[tx0] || !_links[tx1]) { - warning("putHyperlink: invalid range given"); - return; - } - - for (i = tx0; i < tx1; i++) { - for (k = ty0; k < ty1; k++) - _links[i][k] = linkval; - } -} - -glui32 WindowMask::getHyperlink(const Point &pos) const { - if (!_hor || !_ver) { - warning("getHyperlink: struct not initialized"); - return 0; - } - - if (pos.x >= (int16)_hor || pos.y >= (int16)_ver || !_links[pos.x]) { - warning("getHyperlink: invalid range given"); - return 0; - } - - return _links[pos.x][pos.y]; -} - -void WindowMask::startSelection(const Point &pos) { - int tx, ty; - - if (!_hor || !_ver) { - warning("startSelection: mask not initialized"); - return; - } - - tx = MIN(pos.x, (int16)_hor); - ty = MIN(pos.y, (int16)_ver); - - _select.left = _last.x = tx; - _select.top = _last.y = ty; - _select.right = 0; - _select.bottom = 0; - - g_vm->_windows->selectionChanged(); -} - -void WindowMask::moveSelection(const Point &pos) { - int tx, ty; - - if (ABS(pos.x - _last.x) < 5 && ABS(pos.y - _last.y) < 5) - return; - - if (!_hor || !_ver) { - warning("moveSelection: mask not initialized"); - return; - } - - tx = MIN(pos.x, (int16)_hor); - ty = MIN(pos.y, (int16)_ver); - - _select.right = _last.x = tx; - _select.bottom = _last.y = ty; - - g_vm->_windows->selectionChanged(); -} - -void WindowMask::clearSelection() { - if (!_select.isEmpty()) - Windows::_forceRedraw = true; - - _select = Rect(); - g_vm->_windows->clearClaimSelect(); -} - -bool WindowMask::checkSelection(const Rect &r) const { - Rect select(MIN(_select.left, _select.right), MAX(_select.left, _select.right), - MIN(_select.top, _select.bottom), MAX(_select.top, _select.bottom)); - if (select.isEmpty()) - return false; - - return select.intersects(r); -} - -bool WindowMask::getSelection(const Rect &r, int *rx0, int *rx1) const { - uint row, upper, lower, above, below; - bool row_selected, found_left, found_right; - int from_right, from_below, is_above, is_below; - uint cx0, cx1, cy0, cy1; - uint x0 = r.left, y0 = r.top, x1 = r.right, y1 = r.bottom; - - row = (y0 + y1) / 2; - upper = row - (row - y0) / 2; - lower = row + (y1 - row) / 2; - above = upper - (g_conf->_leading) / 2; - below = lower + (g_conf->_leading) / 2; - - cx0 = MIN(_select.left, _select.right); - cx1 = MAX(_select.left, _select.right); - cy0 = MIN(_select.top, _select.bottom); - cy1 = MAX(_select.top, _select.bottom); - - row_selected = false; - - if ((cy0 >= upper && cy0 <= lower) - || (cy1 >= upper && cy1 <= lower)) - row_selected = true; - - if (row >= cy0 && row <= cy1) - row_selected = true; - - if (!row_selected) - return false; - - from_right = (_select.left != (int16)cx0); - from_below = (_select.top != (int16)cy0); - is_above = (above >= cy0 && above <= cy1); - is_below = (below >= cy0 && below <= cy1); - - *rx0 = 0; - *rx1 = 0; - - found_left = false; - found_right = false; - - if (is_above && is_below) { - *rx0 = x0; - *rx1 = x1; - found_left = true; - found_right = true; - } else if (!is_above && is_below) { - if (from_below) { - if (from_right) { - *rx0 = cx0; - *rx1 = x1; - found_left = true; - found_right = true; - } else { - *rx0 = cx1; - *rx1 = x1; - found_left = true; - found_right = true; - } - } else { - if (from_right) { - *rx0 = cx1; - *rx1 = x1; - found_left = true; - found_right = true; - } else { - *rx1 = x1; - found_right = true; - } - } - } else if (is_above && !is_below) { - if (from_below) { - if (from_right) { - *rx0 = x0; - *rx1 = cx1; - found_left = true; - found_right = true; - } else { - *rx0 = x0; - *rx1 = cx0; - found_left = true; - found_right = true; - } - } else { - if (from_right) { - if (x0 > cx0) - return false; - *rx0 = x0; - *rx1 = cx0; - found_left = true; - found_right = true; - } else { - *rx0 = x0; - found_left = true; - } - } - } - - if (found_left && found_right) - return true; - - for (uint i = x0; i <= x1; i++) { - if (i >= cx0 && i <= cx1) { - if (!found_left) { - *rx0 = i; - found_left = true; - if (found_right) - return true; - } else { - if (!found_right) - *rx1 = i; - } - } - } - - if (rx0 && !rx1) - *rx1 = x1; - - return (rx0 && rx1); -} - -} // End of namespace Gargoyle diff --git a/engines/gargoyle/window_mask.h b/engines/gargoyle/window_mask.h deleted file mode 100644 index 502ed49c07..0000000000 --- a/engines/gargoyle/window_mask.h +++ /dev/null @@ -1,82 +0,0 @@ -/* 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. - * - */ - -#ifndef GARGOYLE_WINDOW_MASK_H -#define GARGOYLE_WINDOW_MASK_H - -#include "common/rect.h" -#include "gargoyle/glk_types.h" -#include "gargoyle/utils.h" - -namespace Gargoyle { - -class Window; - -class WindowMask { -public: - size_t _hor, _ver; - glui32 **_links; - Rect _select; - Point _last; -public: - /** - * Constructor - */ - WindowMask(); - - /** - * Resize the links array - */ - void resize(size_t x, size_t y); - - void putHyperlink(glui32 linkval, uint x0, uint y0, uint x1, uint y1); - - glui32 getHyperlink(const Point &pos) const; - - /** - * Start selecting an area of the screen - * @param pos Position to start selection area at - */ - void startSelection(const Point &pos); - - /** - * Move the end point of the selection area - * @param pos Position to end selection area at - */ - void moveSelection(const Point &pos); - - /** - * Remove any previously selected area - */ - void clearSelection(); - - /** - * Checks whether the passed area intersects the selection area - */ - bool checkSelection(const Rect &r) const; - - bool getSelection(const Rect &r, int *rx0, int *rx1) const; -}; - -} // End of namespace Gargoyle - -#endif diff --git a/engines/gargoyle/window_text_buffer.cpp b/engines/gargoyle/window_text_buffer.cpp index c6dde5bdb4..a7e5365b38 100644 --- a/engines/gargoyle/window_text_buffer.cpp +++ b/engines/gargoyle/window_text_buffer.cpp @@ -21,10 +21,10 @@ */ #include "gargoyle/window_text_buffer.h" -#include "gargoyle/clipboard.h" #include "gargoyle/conf.h" #include "gargoyle/gargoyle.h" #include "gargoyle/screen.h" +#include "gargoyle/selection.h" #include "gargoyle/unicode.h" namespace Gargoyle { @@ -232,7 +232,7 @@ void TextBufferWindow::reflow() { } void TextBufferWindow::touchScroll() { - g_vm->_windowMask->clearSelection(); + g_vm->_selection->clearSelection(); _windows->repaint(_bbox); for (int i = 0; i < _scrollMax; i++) @@ -364,7 +364,7 @@ void TextBufferWindow::putTextUni(const glui32 *buf, int len, int pos, int oldle void TextBufferWindow::touch(int line) { _lines[line]._dirty = true; - g_vm->_windowMask->clearSelection(); + g_vm->_selection->clearSelection(); int y = _bbox.top + g_conf->_tMarginY + (_height - line - 1) * g_conf->_leading; _windows->repaint(Rect(_bbox.left, y - 2, _bbox.right, y + g_conf->_leading + 2)); @@ -572,7 +572,7 @@ void TextBufferWindow::click(const Point &newPos) { _windows->setFocus(this); if (_hyperRequest) { - glui32 linkval = g_vm->_windowMask->getHyperlink(newPos); + glui32 linkval = g_vm->_selection->getHyperlink(newPos); if (linkval) { g_vm->_events->store(evtype_Hyperlink, this, linkval, 0); _hyperRequest = false; @@ -596,7 +596,7 @@ void TextBufferWindow::click(const Point &newPos) { if (!gh && !gs) { g_vm->_copySelect = true; - g_vm->_windowMask->startSelection(newPos); + g_vm->_selection->startSelection(newPos); } } @@ -815,7 +815,7 @@ void TextBufferWindow::redraw() { pw = x1 - x0 - 2 * GLI_SUBPIX; // check if any part of buffer is selected - selBuf = g_vm->_windowMask->checkSelection(Rect(x0 / GLI_SUBPIX, y0, x1 / GLI_SUBPIX, y1)); + selBuf = g_vm->_selection->checkSelection(Rect(x0 / GLI_SUBPIX, y0, x1 / GLI_SUBPIX, y1)); for (i = _scrollPos + _height - 1; i >= _scrollPos; i--) { // top of line @@ -823,7 +823,7 @@ void TextBufferWindow::redraw() { // check if part of line is selected if (selBuf) { - selrow = g_vm->_windowMask->getSelection(Rect(x0 / GLI_SUBPIX, y, + selrow = g_vm->_selection->getSelection(Rect(x0 / GLI_SUBPIX, y, x1 / GLI_SUBPIX, y + g_conf->_leading), &sx0, &sx1); selleft = (sx0 == x0/GLI_SUBPIX); selright = (sx1 == x1/GLI_SUBPIX); @@ -947,7 +947,7 @@ void TextBufferWindow::redraw() { } // clear any stored hyperlink coordinates - g_vm->_windowMask->putHyperlink(0, x0/GLI_SUBPIX, y, + g_vm->_selection->putHyperlink(0, x0/GLI_SUBPIX, y, x1/GLI_SUBPIX, y + g_conf->_leading); /* @@ -970,7 +970,7 @@ void TextBufferWindow::redraw() { if (link) { screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX + 1, y + g_conf->_baseLine + 1, w / GLI_SUBPIX + 1, g_conf->_linkStyle), g_conf->_linkColor); - g_vm->_windowMask->putHyperlink(link, x/GLI_SUBPIX, y, + g_vm->_selection->putHyperlink(link, x/GLI_SUBPIX, y, x/GLI_SUBPIX + w/GLI_SUBPIX, y + g_conf->_leading); } @@ -986,7 +986,7 @@ void TextBufferWindow::redraw() { if (link) { screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX + 1, y + g_conf->_baseLine + 1, w/GLI_SUBPIX + 1, g_conf->_linkStyle), g_conf->_linkColor); - g_vm->_windowMask->putHyperlink(link, x / GLI_SUBPIX, y, + g_vm->_selection->putHyperlink(link, x / GLI_SUBPIX, y, x / GLI_SUBPIX + w / GLI_SUBPIX, y + g_conf->_leading); } @@ -1034,7 +1034,7 @@ void TextBufferWindow::redraw() { x = x0 + SLOP; y = y0 + (_height - 1) * g_conf->_leading; - g_vm->_windowMask->putHyperlink(0, x0/GLI_SUBPIX, y, + g_vm->_selection->putHyperlink(0, x0/GLI_SUBPIX, y, x1/GLI_SUBPIX, y + g_conf->_leading); color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor; @@ -1080,7 +1080,7 @@ void TextBufferWindow::redraw() { hx1 = x0/GLI_SUBPIX + ln->_lPic->w < x1/GLI_SUBPIX ? x0/GLI_SUBPIX + ln->_lPic->w : x1/GLI_SUBPIX; - g_vm->_windowMask->putHyperlink(link, hx0, hy0, hx1, hy1); + g_vm->_selection->putHyperlink(link, hx0, hy0, hx1, hy1); } } @@ -1095,7 +1095,7 @@ void TextBufferWindow::redraw() { ? x1/GLI_SUBPIX - ln->_rPic->w : x0/GLI_SUBPIX; hx1 = x1/GLI_SUBPIX; - g_vm->_windowMask->putHyperlink(link, hx0, hy0, hx1, hy1); + g_vm->_selection->putHyperlink(link, hx0, hy0, hx1, hy1); } } } @@ -1114,7 +1114,7 @@ void TextBufferWindow::redraw() { y0 = _bbox.top + g_conf->_tMarginY; y1 = _bbox.bottom - g_conf->_tMarginY; - g_vm->_windowMask->putHyperlink(0, x0, y0, x1, y1); + g_vm->_selection->putHyperlink(0, x0, y0, x1, y1); y0 += g_conf->_scrollWidth / 2; y1 -= g_conf->_scrollWidth / 2; @@ -1144,7 +1144,7 @@ void TextBufferWindow::redraw() { if (selBuf && _copyPos) { Windows::_claimSelect = true; - g_vm->_clipboard->store(_copyBuf, _copyPos); + g_vm->_clipboard->clipboardStore(_copyBuf, _copyPos); for (i = 0; i < _copyPos; i++) _copyBuf[i] = 0; _copyPos = 0; diff --git a/engines/gargoyle/window_text_grid.cpp b/engines/gargoyle/window_text_grid.cpp index 351d9fbe23..1e5e41dd53 100644 --- a/engines/gargoyle/window_text_grid.cpp +++ b/engines/gargoyle/window_text_grid.cpp @@ -23,8 +23,8 @@ #include "gargoyle/window_text_grid.h" #include "gargoyle/conf.h" #include "gargoyle/gargoyle.h" +#include "gargoyle/selection.h" #include "gargoyle/screen.h" -#include "gargoyle/window_mask.h" namespace Gargoyle { @@ -204,7 +204,7 @@ void TextGridWindow::click(const Point &newPos) { } if (_hyperRequest) { - glui32 linkval = g_vm->_windowMask->getHyperlink(newPos); + glui32 linkval = g_vm->_selection->getHyperlink(newPos); if (linkval) { g_vm->_events->store(evtype_Hyperlink, this, linkval, 0); @@ -592,7 +592,7 @@ void TextGridWindow::redraw() { y = y0 + i * g_conf->_leading; // clear any stored hyperlink coordinates - g_vm->_windowMask->putHyperlink(0, x0, y, x0 + g_conf->_cellW * _width, y + g_conf->_leading); + g_vm->_selection->putHyperlink(0, x0, y, x0 + g_conf->_cellW * _width, y + g_conf->_leading); a = 0; for (b = 0; b < _width; b++) { @@ -612,7 +612,7 @@ void TextGridWindow::redraw() { if (link) { screen.fillRect(Rect::fromXYWH(x, y + g_conf->_baseLine + 1, w, g_conf->_linkStyle), g_conf->_linkColor); - g_vm->_windowMask->putHyperlink(link, x, y, x + w, y + g_conf->_leading); + g_vm->_selection->putHyperlink(link, x, y, x + w, y + g_conf->_leading); } x += w; @@ -634,7 +634,7 @@ void TextGridWindow::redraw() { if (link) { screen.fillRect(Rect::fromXYWH(x, y + g_conf->_baseLine + 1, w, g_conf->_linkStyle), g_conf->_linkColor); - g_vm->_windowMask->putHyperlink(link, x, y, x + w, y + g_conf->_leading); + g_vm->_selection->putHyperlink(link, x, y, x + w, y + g_conf->_leading); } } } diff --git a/engines/gargoyle/windows.h b/engines/gargoyle/windows.h index 5830c7c85e..0e4020bb76 100644 --- a/engines/gargoyle/windows.h +++ b/engines/gargoyle/windows.h @@ -30,8 +30,8 @@ #include "gargoyle/events.h" #include "gargoyle/glk_types.h" #include "gargoyle/fonts.h" +#include "gargoyle/selection.h" #include "gargoyle/streams.h" -#include "gargoyle/window_mask.h" namespace Gargoyle { -- cgit v1.2.3