aboutsummaryrefslogtreecommitdiff
path: root/engines/gargoyle
diff options
context:
space:
mode:
authorPaul Gilbert2018-10-21 22:53:35 -0700
committerPaul Gilbert2018-12-08 19:05:59 -0800
commit0d3ad2dc8ad49c684e8a74285ec832335d7675e7 (patch)
tree94d4172819151b5e95952aee2cfd55418fe0000c /engines/gargoyle
parent71389c2dd2b0af525c8f458cee723b61dcfeb614 (diff)
downloadscummvm-rg350-0d3ad2dc8ad49c684e8a74285ec832335d7675e7.tar.gz
scummvm-rg350-0d3ad2dc8ad49c684e8a74285ec832335d7675e7.tar.bz2
scummvm-rg350-0d3ad2dc8ad49c684e8a74285ec832335d7675e7.zip
GLK: Added TextGridWindow methods and support
Diffstat (limited to 'engines/gargoyle')
-rw-r--r--engines/gargoyle/draw.cpp32
-rw-r--r--engines/gargoyle/draw.h38
-rw-r--r--engines/gargoyle/events.cpp4
-rw-r--r--engines/gargoyle/events.h2
-rw-r--r--engines/gargoyle/glk_types.h14
-rw-r--r--engines/gargoyle/module.mk2
-rw-r--r--engines/gargoyle/window_mask.cpp336
-rw-r--r--engines/gargoyle/window_mask.h67
-rw-r--r--engines/gargoyle/windows.cpp944
-rw-r--r--engines/gargoyle/windows.h330
10 files changed, 1622 insertions, 147 deletions
diff --git a/engines/gargoyle/draw.cpp b/engines/gargoyle/draw.cpp
new file mode 100644
index 0000000000..86d5fb0f92
--- /dev/null
+++ b/engines/gargoyle/draw.cpp
@@ -0,0 +1,32 @@
+/* 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/draw.h"
+
+namespace Gargoyle {
+
+int Draw::drawStringUni(int x, int y, int fidx, byte *rgb, glui32 *s, int n, int spw) {
+ // TODO
+ return 0;
+}
+
+} // End of namespace Gargoyle
diff --git a/engines/gargoyle/draw.h b/engines/gargoyle/draw.h
new file mode 100644
index 0000000000..61dfe1891a
--- /dev/null
+++ b/engines/gargoyle/draw.h
@@ -0,0 +1,38 @@
+/* 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_DRAW_H
+#define GARGOYLE_DRAW_H
+
+#include "common/events.h"
+#include "gargoyle/glk_types.h"
+
+namespace Gargoyle {
+
+class Draw {
+protected:
+ int drawStringUni(int x, int y, int fidx, byte *rgb, glui32 *s, int n, int spw);
+};
+
+} // End of namespace Gargoyle
+
+#endif
diff --git a/engines/gargoyle/events.cpp b/engines/gargoyle/events.cpp
index 1f7cc6a236..3373628a1e 100644
--- a/engines/gargoyle/events.cpp
+++ b/engines/gargoyle/events.cpp
@@ -32,4 +32,8 @@ void Events::clearEvent(Event *ev) {
// TODO
}
+void Events::eventStore(EvType type, Window *win, uint32 val1, uint32 val2) {
+ // TODO
+}
+
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/events.h b/engines/gargoyle/events.h
index 476be40181..4ee94707ea 100644
--- a/engines/gargoyle/events.h
+++ b/engines/gargoyle/events.h
@@ -118,6 +118,8 @@ public:
void pollEvents();
void clearEvent(Event *ev);
+
+ void eventStore(EvType type, Window *win, uint32 val1 = 0, uint32 val2 = 0);
};
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/glk_types.h b/engines/gargoyle/glk_types.h
index 8f84cbe6a6..eaebb6f929 100644
--- a/engines/gargoyle/glk_types.h
+++ b/engines/gargoyle/glk_types.h
@@ -165,6 +165,20 @@ enum StyleHint {
stylehint_just_RightFlush = 3,
};
+/**
+ * These constants define the classes of opaque objects. It's a bit ugly to put
+ * them in this header file, since more classes may be added in the future.
+ * But if you find yourself stuck with an obsolete version of this file,
+ * adding new class definitions will be easy enough -- they will be numbered
+ * sequentially, and the numeric constants can be found in the Glk specification.
+ */
+enum giDisp {
+ gidisp_Class_Window = 0,
+ gidisp_Class_Stream = 1,
+ gidisp_Class_Fileref = 2,
+ gidisp_Class_Schannel = 3,
+};
+
#ifdef GLK_MODULE_IMAGE
enum ImageAlign {
diff --git a/engines/gargoyle/module.mk b/engines/gargoyle/module.mk
index 925c66d359..46f2d31722 100644
--- a/engines/gargoyle/module.mk
+++ b/engines/gargoyle/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/gargoyle
MODULE_OBJS := \
conf.o \
detection.o \
+ draw.o \
events.o \
fonts.o \
gargoyle.o \
@@ -10,6 +11,7 @@ MODULE_OBJS := \
picture.o \
streams.o \
string.o \
+ window_mask.o \
windows.o \
scott/detection.o \
scott/scott.o
diff --git a/engines/gargoyle/window_mask.cpp b/engines/gargoyle/window_mask.cpp
new file mode 100644
index 0000000000..f0f6aa36bf
--- /dev/null
+++ b/engines/gargoyle/window_mask.cpp
@@ -0,0 +1,336 @@
+/* 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"
+
+namespace Gargoyle {
+
+int WindowMask::_lastX;
+int WindowMask::_lastY;
+
+WindowMask::WindowMask() : _hor(0), _ver(0), _links(nullptr) {
+ _lastX = _lastY = 0;
+}
+
+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 Common::Point &pos) {
+ 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 Common::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 = _lastX = tx;
+ _select.top = _lastY = ty;
+ _select.right = 0;
+ _select.bottom = 0;
+
+ g_vm->_windows->selectionChanged();
+}
+
+void WindowMask::moveSelection(const Common::Point &pos) {
+ int tx, ty;
+
+ if (ABS(pos.x - _lastX) < 5 && abs(pos.y - _lastY) < 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 = _lastX = tx;
+ _select.bottom = _lastY = ty;
+
+ g_vm->_windows->selectionChanged();
+}
+
+void WindowMask::clearSelection() {
+ if (_select.left || _select.right
+ || _select.top || _select.bottom)
+ Windows::_forceRedraw = true;
+
+ _select.left = 0;
+ _select.top = 0;
+ _select.right = 0;
+ _select.bottom = 0;
+ g_vm->_windows->clearClaimSelect();
+}
+
+int WindowMask::checkSelection(uint x0, uint y0, uint x1, uint y1) {
+ uint cx0, cx1, cy0, cy1;
+
+ cx0 = _select.left < _select.right
+ ? _select.left
+ : _select.right;
+
+ cx1 = _select.left < _select.right
+ ? _select.right
+ : _select.left;
+
+ cy0 = _select.top < _select.bottom
+ ? _select.top
+ : _select.bottom;
+
+ cy1 = _select.top < _select.bottom
+ ? _select.bottom
+ : _select.top;
+
+ if (!cx0 || !cx1 || !cy0 || !cy1)
+ return false;
+
+ if (cx0 >= x0 && cx0 <= x1
+ && cy0 >= y0 && cy0 <= y1)
+ return true;
+
+ if (cx0 >= x0 && cx0 <= x1
+ && cy1 >= y0 && cy1 <= y1)
+ return true;
+
+ if (cx1 >= x0 && cx1 <= x1
+ && cy0 >= y0 && cy0 <= y1)
+ return true;
+
+ if (cx1 >= x0 && cx1 <= x1
+ && cy1 >= y0 && cy1 <= y1)
+ return true;
+
+ return false;
+}
+
+int WindowMask::getSelection(uint x0, uint y0, uint x1, uint y1, uint *rx0, uint *rx1) {
+ uint row, upper, lower, above, below;
+ int row_selected, found_left, found_right;
+ int from_right, from_below, is_above, is_below;
+ uint cx0, cx1, cy0, cy1;
+
+ 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 = _select.left < _select.right
+ ? _select.left
+ : _select.right;
+
+ cx1 = _select.left < _select.right
+ ? _select.right
+ : _select.left;
+
+ cy0 = _select.top < _select.bottom
+ ? _select.top
+ : _select.bottom;
+
+ cy1 = _select.top < _select.bottom
+ ? _select.bottom
+ : _select.top;
+
+ 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
new file mode 100644
index 0000000000..db0d7e655d
--- /dev/null
+++ b/engines/gargoyle/window_mask.h
@@ -0,0 +1,67 @@
+/* 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"
+
+namespace Gargoyle {
+
+class Window;
+
+struct WindowMask {
+ size_t _hor, _ver;
+ glui32 **_links;
+ Common::Rect _select;
+
+ static int _lastX, _lastY;
+
+ /**
+ * 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 Common::Point &pos);
+
+ void startSelection(const Common::Point &pos);
+
+ void moveSelection(const Common::Point &pos);
+
+ void clearSelection();
+
+ int checkSelection(uint x0, uint y0, uint x1, uint y1);
+
+ int getSelection(uint x0, uint y0, uint x1, uint y1, uint *rx0, uint *rx1);
+};
+
+} // End of namespace Gargoyle
+
+#endif
diff --git a/engines/gargoyle/windows.cpp b/engines/gargoyle/windows.cpp
index ac16471b37..a625040f8d 100644
--- a/engines/gargoyle/windows.cpp
+++ b/engines/gargoyle/windows.cpp
@@ -35,8 +35,15 @@ namespace Gargoyle {
bool Windows::_overrideReverse;
bool Windows::_overrideFgSet;
bool Windows::_overrideBgSet;
+bool Windows::_forceRedraw;
int Windows::_overrideFgVal;
int Windows::_overrideBgVal;
+int Windows::_zcolor_fg;
+int Windows::_zcolor_bg;
+byte Windows::_zcolor_LightGrey[3];
+byte Windows::_zcolor_Foreground[3];
+byte Windows::_zcolor_Background[3];
+byte Windows::_zcolor_Bright[3];
/*--------------------------------------------------------------------------*/
@@ -76,13 +83,25 @@ Windows::iterator &Windows::iterator::operator++() {
/*--------------------------------------------------------------------------*/
Windows::Windows(Graphics::Screen *screen) :
- _screen(screen), _forceRedraw(true), _moreFocus(false), _windowList(nullptr),
+ _screen(screen), _moreFocus(false), _windowList(nullptr),
_rootWin(nullptr), _focusWin(nullptr), _mask(nullptr), _claimSelect(0) {
+ _mask = new WindowMask();
_overrideReverse = false;
_overrideFgSet = false;
_overrideBgSet = false;
+ _forceRedraw = true;
_overrideFgVal = 0;
_overrideBgVal = 0;
+ _zcolor_fg = _zcolor_bg = 0;
+
+ _zcolor_LightGrey[0] = _zcolor_LightGrey[1] = _zcolor_LightGrey[2] = 181;
+ _zcolor_Foreground[0] = _zcolor_Foreground[1] = _zcolor_Foreground[2] = 0;
+ _zcolor_Background[0] = _zcolor_Background[1] = _zcolor_Background[2] = 0;
+ _zcolor_Bright[0] = _zcolor_Bright[1] = _zcolor_Bright[2] = 0;
+}
+
+Windows::~Windows() {
+ delete _mask;
}
Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size,
@@ -235,31 +254,43 @@ void Windows::rearrange() {
}
}
-void Windows::clearSelection() {
- if (!_mask) {
- warning("clear_selection: mask not initialized");
- return;
- }
+void Windows::selectionChanged() {
+ _claimSelect = false;
+ _forceRedraw = true;
+ redraw();
+}
- if (_mask->select.left || _mask->select.right
- || _mask->select.top || _mask->select.bottom)
- _forceRedraw = true;
+void Windows::clearSelection() {
+ _mask->clearSelection();
+}
- _mask->select = Common::Rect();
- _claimSelect = false;
+void Windows::redraw() {
+ // TODO: gli_windows_redraw
}
void Windows::repaint(const Common::Rect &box) {
// TODO
}
+void Windows::drawRect(int x0, int y0, int w, int h, const byte *rgb) {
+ // TODO
+}
+
+byte *Windows::rgbShift(byte *rgb) {
+ _zcolor_Bright[0] = (rgb[0] + 0x30) < 0xff ? (rgb[0] + 0x30) : 0xff;
+ _zcolor_Bright[1] = (rgb[1] + 0x30) < 0xff ? (rgb[1] + 0x30) : 0xff;
+ _zcolor_Bright[2] = (rgb[2] + 0x30) < 0xff ? (rgb[2] + 0x30) : 0xff;
+
+ return _zcolor_Bright;
+}
+
/*--------------------------------------------------------------------------*/
Window::Window(Windows *windows, glui32 rock) : _magicnum(MAGIC_WINDOW_NUM),
_windows(windows), _rock(rock), _type(0), _parent(nullptr), _next(nullptr), _prev(nullptr),
- yadj(0), _lineRequest(0), _lineRequestUni(0), _charRequest(0), _charRequestUni(0),
+ _yAdj(0), _lineRequest(0), _lineRequestUni(0), _charRequest(0), _charRequestUni(0),
_mouseRequest(0), _hyperRequest(0), _moreRequest(0), _scrollRequest(0), _imageLoaded(0),
- _echoLineInput(true), _lineTerminators(nullptr), _termCt(0), _echoStream(nullptr) {
+ _echoLineInput(true), _lineTerminatorsBase(nullptr), _termCt(0), _echoStream(nullptr) {
_attr.fgset = 0;
_attr.bgset = 0;
_attr.reverse = 0;
@@ -276,6 +307,27 @@ Window::Window(Windows *windows, glui32 rock) : _magicnum(MAGIC_WINDOW_NUM),
_stream = streams.addWindowStream(this);
}
+Window::~Window() {
+ if (g_vm->gli_unregister_obj)
+ (*g_vm->gli_unregister_obj)(this, gidisp_Class_Window, _dispRock);
+
+
+ _echoStream = nullptr;
+ delete _stream;
+
+ delete[] _lineTerminatorsBase;
+
+ Window *prev = _prev;
+ Window *next = _next;
+
+ if (prev)
+ prev->_next = next;
+ else
+ _windows->_windowList = next;
+ if (next)
+ next->_prev = prev;
+}
+
void Window::cancelLineEvent(Event *ev) {
Event dummyEv;
if (!ev)
@@ -284,6 +336,31 @@ void Window::cancelLineEvent(Event *ev) {
g_vm->_events->clearEvent(ev);
}
+void Window::requestLineEvent(char *buf, glui32 maxlen, glui32 initlen) {
+ warning("requestLineEvent: window does not support keyboard input");
+}
+
+void Window::requestLineEventUni(glui32 *buf, glui32 maxlen, glui32 initlen) {
+ warning("requestLineEventUni: window does not support keyboard input");
+}
+
+void Window::redraw() {
+ if (Windows::_forceRedraw) {
+ unsigned char *color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor;
+ int y0 = _yAdj ? _bbox.top - _yAdj : _bbox.top;
+ _windows->drawRect(_bbox.left, y0, _bbox.width(), _bbox.bottom - y0, color);
+ }
+}
+
+bool Window::checkTerminator(glui32 ch) {
+ if (ch == keycode_Escape)
+ return true;
+ else if (ch >= keycode_Func12 && ch <= keycode_Func1)
+ return true;
+ else
+ return false;
+}
+
/*--------------------------------------------------------------------------*/
BlankWindow::BlankWindow(Windows *windows, uint32 rock) : Window(windows, rock) {
@@ -338,9 +415,9 @@ void TextGridWindow::rearrange(const Common::Rect &box) {
}
void TextGridWindow::touch(int line) {
- int y = bbox.top + line * g_conf->_leading;
+ int y = _bbox.top + line * g_conf->_leading;
_lines[line].dirty = true;
- _windows->repaint(Common::Rect(bbox.left, y, bbox.right, y + g_conf->_leading));
+ _windows->repaint(Common::Rect(_bbox.left, y, _bbox.right, y + g_conf->_leading));
}
glui32 TextGridWindow::getSplit(glui32 size, bool vertical) const {
@@ -348,6 +425,251 @@ glui32 TextGridWindow::getSplit(glui32 size, bool vertical) const {
size * g_conf->_cellH + g_conf->_tMarginY * 2;
}
+void TextGridWindow::putChar(unsigned char ch) {
+
+}
+
+void TextGridWindow::putCharUni(uint32 ch) {
+ TextGridRow *ln;
+
+ // Canonicalize the cursor position. That is, the cursor may have been
+ // left outside the window area; wrap it if necessary.
+ if (_curX < 0) {
+ _curX = 0;
+ } else if (_curX >= _width) {
+ _curX = 0;
+ _curY++;
+ }
+ if (_curY < 0)
+ _curY = 0;
+ else if (_curY >= _height)
+ return; /* outside the window */
+
+ if (ch == '\n') {
+ /* a newline just moves the cursor. */
+ _curY++;
+ _curX = 0;
+ return;
+ }
+
+ touch(_curY);
+
+ ln = &(_lines[_curY]);
+ ln->_chars[_curX] = ch;
+ ln->_attrs[_curX] = _attr;
+
+ _curX++;
+ // We can leave the cursor outside the window, since it will be
+ // canonicalized next time a character is printed.
+}
+
+bool TextGridWindow::unputCharUni(uint32 ch) {
+ TextGridRow *ln;
+ int oldx = _curX, oldy = _curY;
+
+ /* Move the cursor back. */
+ if (_curX >= _width)
+ _curX = _width - 1;
+ else
+ _curX--;
+
+ /* Canonicalize the cursor position. That is, the cursor may have been
+ left outside the window area; wrap it if necessary. */
+ if (_curX < 0) {
+ _curX = _width - 1;
+ _curY--;
+ }
+ if (_curY < 0)
+ _curY = 0;
+ else if (_curY >= _height)
+ return false; // outside the window
+
+ if (ch == '\n') {
+ // a newline just moves the cursor.
+ if (_curX == _width - 1)
+ return 1; // deleted a newline
+ _curX = oldx;
+ _curY = oldy;
+ return 0; // it wasn't there */
+ }
+
+ ln = &(_lines[_curY]);
+ if (ln->_chars[_curX] == ch) {
+ ln->_chars[_curX] = ' ';
+ ln->_attrs[_curX].clear();
+ touch(_curY);
+ return true; // deleted the char
+ } else {
+ _curX = oldx;
+ _curY = oldy;
+ return false; // it wasn't there
+ }
+}
+
+void TextGridWindow::putBuffer(const unsigned char *buf, size_t len) {
+ // TODO
+}
+
+void TextGridWindow::putBufferUni(const uint32 *buf, size_t len) {
+ // TODO
+}
+
+void TextGridWindow::moveCursor(const Common::Point &pos) {
+ // If the values are negative, they're really huge positive numbers --
+ // remember that they were cast from glui32. So set them huge and
+ // let canonicalization take its course.
+ _curX = (pos.x < 0) ? 32767 : pos.x;
+ _curY = (pos.y < 0) ? 32767 : pos.y;
+}
+
+void TextGridWindow::clear() {
+ _attr.fgset = Windows::_overrideFgSet;
+ _attr.bgset = Windows::_overrideBgSet;
+ _attr.fgcolor = Windows::_overrideFgSet ? Windows::_overrideFgVal : 0;
+ _attr.bgcolor = Windows::_overrideBgSet ? Windows::_overrideBgVal : 0;
+ _attr.reverse = false;
+
+ for (int k = 0; k < _height; k++) {
+ TextGridRow &ln = _lines[k];
+ touch(k);
+ for (uint j = 0; j < ln._attrs.size(); ++j) {
+ ln._chars[j] = ' ';
+ ln._attrs[j].clear();
+ }
+ }
+
+ _curX = 0;
+ _curY = 0;
+}
+
+void TextGridWindow::click(const Common::Point &newPos) {
+ int x = newPos.x - _bbox.left;
+ int y = newPos.y - _bbox.top;
+
+ if (_lineRequest || _charRequest || _lineRequestUni || _charRequestUni
+ || _moreRequest || _scrollRequest)
+ _windows->setFocus(this);
+
+ if (_mouseRequest) {
+ g_vm->_events->eventStore(evtype_MouseInput, this, x / g_conf->_cellW, y / g_conf->_leading);
+ _mouseRequest = false;
+ if (g_conf->_safeClicks)
+ g_vm->_events->_forceClick = true;
+ }
+
+ if (_hyperRequest) {
+ glui32 linkval = _windows->getHyperlink(newPos);
+ if (linkval)
+ {
+ g_vm->_events->eventStore(evtype_Hyperlink, this, linkval, 0);
+ _hyperRequest = false;
+ if (g_conf->_safeClicks)
+ g_vm->_events->_forceClick = true;
+ }
+ }
+}
+
+void TextGridWindow::requestLineEvent(char *buf, glui32 maxlen, glui32 initlen) {
+ if (_charRequest || _lineRequest || _charRequestUni || _lineRequestUni)
+ {
+ warning("request_line_event: window already has keyboard request");
+ return;
+ }
+
+ if ((int)maxlen > (_width - _curX))
+ maxlen = (_width - _curX);
+
+ _inBuf = buf;
+ _inMax = maxlen;
+ _inLen = 0;
+ _inCurs = 0;
+ _inOrgX = _curX;
+ _inOrgY = _curY;
+ _origAttr = _attr;
+ _attr.set(style_Input);
+
+ if (initlen > maxlen)
+ initlen = maxlen;
+
+ if (initlen) {
+ TextGridRow *ln = &_lines[_inOrgY];
+
+ for (glui32 ix = 0; ix < initlen; ix++) {
+ ln->_attrs[_inOrgX + ix].set(style_Input);
+ ln->_chars[_inOrgX + ix] = buf[ix];
+ }
+
+ _inCurs += initlen;
+ _inLen += initlen;
+ _curX = _inOrgX + _inCurs;
+ _curY = _inOrgY;
+
+ touch(_inOrgY);
+ }
+
+ if (_lineTerminatorsBase && _termCt) {
+ _lineTerminators = new glui32[_termCt + 1];
+
+ if (_lineTerminators) {
+ memcpy(_lineTerminators, _lineTerminatorsBase, _termCt * sizeof(glui32));
+ _lineTerminators[_termCt] = 0;
+ }
+ }
+
+ if (g_vm->gli_register_arr)
+ _inArrayRock = (*g_vm->gli_register_arr)(buf, maxlen, "&+#!Cn");
+}
+
+void TextGridWindow::requestLineEventUni(glui32 *buf, glui32 maxlen, glui32 initlen) {
+ if (_charRequest || _lineRequest || _charRequestUni || _lineRequestUni) {
+ warning("requestLineEventUni: window already has keyboard request");
+ return;
+ }
+
+ if ((int)maxlen > (_width - _curX))
+ maxlen = (_width - _curX);
+
+ _inBuf = buf;
+ _inMax = maxlen;
+ _inLen = 0;
+ _inCurs = 0;
+ _inOrgX = _curX;
+ _inOrgY = _curY;
+ _origAttr = _attr;
+ _attr.set(style_Input);
+
+ if (initlen > maxlen)
+ initlen = maxlen;
+
+ if (initlen) {
+ TextGridRow *ln = &(_lines[_inOrgY]);
+
+ for (glui32 ix = 0; ix<initlen; ix++) {
+ ln->_attrs[_inOrgX + ix].set(style_Input);
+ ln->_chars[_inOrgX + ix] = buf[ix];
+ }
+
+ _inCurs += initlen;
+ _inLen += initlen;
+ _curX = _inOrgX + _inCurs;
+ _curY = _inOrgY;
+
+ touch(_inOrgY);
+ }
+
+ if (_lineTerminatorsBase && _termCt) {
+ _lineTerminators = new glui32[_termCt + 1];
+
+ if (_lineTerminators) {
+ memcpy(_lineTerminators, _lineTerminatorsBase, _termCt * sizeof(glui32));
+ _lineTerminators[_termCt] = 0;
+ }
+ }
+
+ if (g_vm->gli_register_arr)
+ _inArrayRock = (*g_vm->gli_register_arr)(buf, maxlen, "&+#!Iu");
+}
+
void TextGridWindow::cancelLineEvent(Event *ev) {
int ix;
void *inbuf;
@@ -373,7 +695,7 @@ void TextGridWindow::cancelLineEvent(Event *ev) {
if (!unicode) {
for (ix = 0; ix<_inLen; ix++)
{
- glui32 ch = ln->chars[_inOrgX + ix];
+ glui32 ch = ln->_chars[_inOrgX + ix];
if (ch > 0xff)
ch = '?';
((char *)inbuf)[ix] = (char)ch;
@@ -382,7 +704,7 @@ void TextGridWindow::cancelLineEvent(Event *ev) {
_echoStream->echoLine((char *)_inBuf, _inLen);
} else {
for (ix = 0; ix<_inLen; ix++)
- ((glui32 *)inbuf)[ix] = ln->chars[_inOrgX + ix];
+ ((glui32 *)inbuf)[ix] = ln->_chars[_inOrgX + ix];
if (_echoStream)
_echoStream->echoLineUni((glui32 *)inbuf, _inLen);
}
@@ -413,14 +735,274 @@ void TextGridWindow::cancelLineEvent(Event *ev) {
(*g_vm->gli_unregister_arr)(inbuf, inmax, unicode ? "&+#!Iu" : "&+#!Cn", inarrayrock);
}
+void TextGridWindow::acceptReadChar(glui32 arg) {
+ glui32 key;
+
+ switch (arg)
+ {
+ case keycode_Erase:
+ key = keycode_Delete;
+ break;
+ case keycode_MouseWheelUp:
+ case keycode_MouseWheelDown:
+ return;
+ default:
+ key = arg;
+ }
+
+ if (key > 0xff && key < (0xffffffff - keycode_MAXVAL + 1))
+ {
+ if (!(_charRequestUni) || key > 0x10ffff)
+ key = keycode_Unknown;
+ }
+
+ _charRequest = false;
+ _charRequestUni = false;
+ g_vm->_events->eventStore(evtype_CharInput, this, key, 0);
+}
+
+void TextGridWindow::acceptLine(glui32 keycode) {
+ int ix;
+ void *inbuf;
+ int inmax;
+ gidispatch_rock_t inarrayrock;
+ TextGridRow *ln = &(_lines[_inOrgY]);
+ int unicode = _lineRequestUni;
+
+ if (!_inBuf)
+ return;
+
+ inbuf = _inBuf;
+ inmax = _inMax;
+ inarrayrock = _inArrayRock;
+
+ if (!unicode) {
+ for (ix = 0; ix<_inLen; ix++)
+ ((char *)inbuf)[ix] = (char)ln->_chars[_inOrgX + ix];
+ if (_echoStream)
+ _echoStream->echoLine((char *)inbuf, _inLen);
+ } else {
+ for (ix = 0; ix<_inLen; ix++)
+ ((glui32 *)inbuf)[ix] = ln->_chars[_inOrgX + ix];
+ if (_echoStream)
+ _echoStream->echoLineUni((glui32 *)inbuf, _inLen);
+ }
+
+ _curY = _inOrgY + 1;
+ _curX = 0;
+ _attr = _origAttr;
+
+ if (_lineTerminators)
+ {
+ glui32 val2 = keycode;
+ if (val2 == keycode_Return)
+ val2 = 0;
+ g_vm->_events->eventStore(evtype_LineInput, this, _inLen, val2);
+ free(_lineTerminators);
+ _lineTerminators = NULL;
+ } else {
+ g_vm->_events->eventStore(evtype_LineInput, this, _inLen, 0);
+ }
+ _lineRequest = false;
+ _lineRequestUni = false;
+ _inBuf = NULL;
+ _inMax = 0;
+ _inOrgX = 0;
+ _inOrgY = 0;
+
+ if (g_vm->gli_unregister_arr)
+ (*g_vm->gli_unregister_arr)(inbuf, inmax, unicode ? "&+#!Iu" : "&+#!Cn", inarrayrock);
+}
+
+void TextGridWindow::acceptReadLine(glui32 arg) {
+ int ix;
+ TextGridRow *ln = &(_lines[_inOrgY]);
+
+ if (!_inBuf)
+ return;
+
+ if (_lineTerminators && checkTerminator(arg)) {
+ glui32 *cx;
+ for (cx = _lineTerminators; *cx; cx++) {
+ if (*cx == arg) {
+ acceptLine(arg);
+ return;
+ }
+ }
+ }
+
+ switch (arg) {
+
+ /* Delete keys, during line input. */
+
+ case keycode_Delete:
+ if (_inLen <= 0)
+ return;
+ if (_inCurs <= 0)
+ return;
+ for (ix = _inCurs; ix<_inLen; ix++)
+ ln->_chars[_inOrgX + ix - 1] = ln->_chars[_inOrgX + ix];
+ ln->_chars[_inOrgX + _inLen - 1] = ' ';
+ _inCurs--;
+ _inLen--;
+ break;
+
+ case keycode_Erase:
+ if (_inLen <= 0)
+ return;
+ if (_inCurs >= _inLen)
+ return;
+ for (ix = _inCurs; ix<_inLen - 1; ix++)
+ ln->_chars[_inOrgX + ix] = ln->_chars[_inOrgX + ix + 1];
+ ln->_chars[_inOrgX + _inLen - 1] = ' ';
+ _inLen--;
+ break;
+
+ case keycode_Escape:
+ if (_inLen <= 0)
+ return;
+ for (ix = 0; ix<_inLen; ix++)
+ ln->_chars[_inOrgX + ix] = ' ';
+ _inLen = 0;
+ _inCurs = 0;
+ break;
+
+ /* Cursor movement keys, during line input. */
+
+ case keycode_Left:
+ if (_inCurs <= 0)
+ return;
+ _inCurs--;
+ break;
+
+ case keycode_Right:
+ if (_inCurs >= _inLen)
+ return;
+ _inCurs++;
+ break;
+
+ case keycode_Home:
+ if (_inCurs <= 0)
+ return;
+ _inCurs = 0;
+ break;
+
+ case keycode_End:
+ if (_inCurs >= _inLen)
+ return;
+ _inCurs = _inLen;
+ break;
+
+ case keycode_Return:
+ acceptLine(arg);
+ break;
+
+ default:
+ if (_inLen >= _inMax)
+ return;
+
+ if (arg < 32 || arg > 0xff)
+ return;
+
+ if (g_conf->_caps && (arg > 0x60 && arg < 0x7b))
+ arg -= 0x20;
+
+ for (ix = _inLen; ix>_inCurs; ix--)
+ ln->_chars[_inOrgX + ix] = ln->_chars[_inOrgX + ix - 1];
+ ln->_attrs[_inOrgX + _inLen].set(style_Input);
+ ln->_chars[_inOrgX + _inCurs] = arg;
+
+ _inCurs++;
+ _inLen++;
+ }
+
+ _curX = _inOrgX + _inCurs;
+ _curY = _inOrgY;
+
+ touch(_inOrgY);
+}
+
+void TextGridWindow::redraw() {
+ TextGridRow *ln;
+ int x0, y0;
+ int x, y, w;
+ int i, a, b, k, o;
+ glui32 link;
+ int font;
+ byte *fgcolor, *bgcolor;
+
+ x0 = _bbox.left;
+ y0 = _bbox.top;
+
+ for (i = 0; i < _height; i++) {
+ ln = &_lines[i];
+ if (ln->dirty || Windows::_forceRedraw) {
+ ln->dirty = 0;
+
+ x = x0;
+ y = y0 + i * g_conf->_leading;
+
+ /* clear any stored hyperlink coordinates */
+ _windows->setHyperlink(0, x0, y, x0 + g_conf->_cellW * _width, y + g_conf->_leading);
+
+ a = 0;
+ for (b = 0; b < _width; b++) {
+ if (ln->_attrs[a] == ln->_attrs[b]) {
+ link = ln->_attrs[a].hyper;
+ font = ln->_attrs[a].attrFont(styles);
+ fgcolor = link ? g_conf->_linkColor : ln->_attrs[a].attrFg(styles);
+ bgcolor = ln->_attrs[a].attrBg(styles);
+ w = (b - a) * g_conf->_cellW;
+ _windows->drawRect(x, y, w, g_conf->_leading, bgcolor);
+ o = x;
+
+ for (k = a; k < b; k++) {
+ drawStringUni(o * GLI_SUBPIX,
+ y + g_conf->_baseLine, font, fgcolor,
+ &ln->_chars[k], 1, -1);
+ o += g_conf->_cellW;
+ }
+ if (link) {
+ _windows->drawRect(x, y + g_conf->_baseLine + 1, w,
+ g_conf->_linkStyle, g_conf->_linkColor);
+ _windows->setHyperlink(link, x, y, x + w, y + g_conf->_leading);
+ }
+ x += w;
+ a = b;
+ }
+ }
+ link = ln->_attrs[a].hyper;
+ font = ln->_attrs[a].attrFont(styles);
+ fgcolor = link ? g_conf->_linkColor : ln->_attrs[a].attrFg(styles);
+ bgcolor = ln->_attrs[a].attrBg(styles);
+ w = (b - a) * g_conf->_cellW;
+ w += _bbox.right - (x + w);
+ _windows->drawRect(x, y, w, g_conf->_leading, bgcolor);
+
+ o = x;
+ for (k = a; k < b; k++) {
+ drawStringUni(o * GLI_SUBPIX,
+ y + g_conf->_baseLine, font, fgcolor,
+ &ln->_chars[k], 1, -1);
+ o += g_conf->_cellW;
+ }
+ if (link) {
+ _windows->drawRect(x, y + g_conf->_baseLine + 1, w,
+ g_conf->_linkStyle, g_conf->_linkColor);
+ _windows->setHyperlink(link, x, y, x + w, y + g_conf->_leading);
+ }
+ }
+ }
+}
+
/*--------------------------------------------------------------------------*/
void TextGridWindow::TextGridRow::resize(size_t newSize) {
- chars.clear();
- attr.clear();
- chars.resize(newSize);
- attr.resize(newSize);
- Common::fill(&chars[0], &chars[0] + newSize, ' ');
+ _chars.clear();
+ _attrs.clear();
+ _chars.resize(newSize);
+ _attrs.resize(newSize);
+ Common::fill(&_chars[0], &_chars[0] + newSize, ' ');
}
/*--------------------------------------------------------------------------*/
@@ -465,8 +1047,8 @@ void TextBufferWindow::rearrange(const Common::Rect &box) {
/* align text with bottom */
rnd = newhgt * g_conf->_cellH + g_conf->_tMarginY * 2;
- yadj = (box.height() - rnd);
- bbox.top += (box.height() - rnd);
+ _yAdj = (box.height() - rnd);
+ _bbox.top += (box.height() - rnd);
if (newwid != _width) {
_width = newwid;
@@ -601,7 +1183,7 @@ void TextBufferWindow::reflow() {
if (inputbyte != -1) {
_inFence = _numChars;
- putTextUnit(charbuf + inputbyte, p - inputbyte, _numChars, 0);
+ putTextUni(charbuf + inputbyte, p - inputbyte, _numChars, 0);
_inCurs = _numChars;
}
@@ -620,54 +1202,12 @@ void TextBufferWindow::reflow() {
void TextBufferWindow::touchScroll() {
_windows->clearSelection();
- _windows->repaint(bbox);
+ _windows->repaint(_bbox);
for (int i = 0; i < _scrollMax; i++)
_lines[i].dirty = true;
}
-void TextBufferWindow::clear() {
- int i;
-
- _attr.fgset = Windows::_overrideFgSet;
- _attr.bgset = Windows::_overrideBgSet;
- _attr.fgcolor = Windows::_overrideFgSet ? Windows::_overrideFgVal : 0;
- _attr.bgcolor = Windows::_overrideBgSet ? Windows::_overrideBgVal : 0;
- _attr.reverse = false;
-
- _ladjw = _radjw = 0;
- _ladjn = _radjn = 0;
-
- _spaced = 0;
- _dashed = 0;
-
- _numChars = 0;
-
- for (i = 0; i < _scrollBack; i++) {
- _lines[i].len = 0;
-
- if (_lines[i].lpic) _lines[i].lpic->decrement();
- _lines[i].lpic = nullptr;
- if (_lines[i].rpic) _lines[i].rpic->decrement();
- _lines[i].rpic = nullptr;
-
- _lines[i].lhyper = 0;
- _lines[i].rhyper = 0;
- _lines[i].lm = 0;
- _lines[i].rm = 0;
- _lines[i].newline = 0;
- _lines[i].dirty = true;
- _lines[i].repaint = false;
- }
-
- _lastSeen = 0;
- _scrollPos = 0;
- _scrollMax = 0;
-
- for (i = 0; i < _height; i++)
- touch(i);
-}
-
bool TextBufferWindow::putPicture(Picture *pic, glui32 align, glui32 linkval) {
if (align == imagealign_MarginRight)
{
@@ -696,7 +1236,29 @@ bool TextBufferWindow::putPicture(Picture *pic, glui32 align, glui32 linkval) {
flowBreak();
}
- return true ;
+ return true;
+}
+
+void TextBufferWindow::flowBreak() {
+ // TODO
+}
+
+void TextBufferWindow::putTextUni(const glui32 *buf, int len, int pos, int oldlen) {
+ // TODO
+}
+
+void TextBufferWindow::touch(int line) {
+ int y = _bbox.top + g_conf->_tMarginY + (_height - line - 1) * g_conf->_leading;
+ _lines[line].dirty = 1;
+ _windows->clearSelection();
+ _windows->repaint(Common::Rect(_bbox.left, y - 2, _bbox.right, y + g_conf->_leading + 2));
+}
+
+glui32 TextBufferWindow::getSplit(glui32 size, bool vertical) const {
+ return (vertical) ? size * g_conf->_cellW : size * g_conf->_cellH;
+}
+
+void TextBufferWindow::putChar(unsigned char ch) {
}
void TextBufferWindow::putCharUni(glui32 ch) {
@@ -712,10 +1274,10 @@ void TextBufferWindow::putCharUni(glui32 ch) {
gli_tts_speak(&ch, 1);
- pw = (bbox.right - bbox.left - g_conf->_tMarginX * 2 - gli_scroll_width) * GLI_SUBPIX;
+ pw = (_bbox.right - _bbox.left - g_conf->_tMarginX * 2 - gli_scroll_width) * GLI_SUBPIX;
pw = pw - 2 * SLOP - radjw - ladjw;
- color = gli_override_bg_set ? gli_window_color : bgcolor;
+ color = Windows::_overrideBgSet ? gli_window_color : bgcolor;
// oops ... overflow
if (numchars + 1 >= TBLINELEN)
@@ -730,7 +1292,7 @@ void TextBufferWindow::putCharUni(glui32 ch) {
// fails for 'tis a wonderful day in the '80s
if (gli_conf_quotes > 1 && ch == '\'')
{
- if (numchars == 0 || leftquote(chars[numchars - 1]))
+ if (numchars == 0 || leftquote(_chars[numchars - 1]))
ch = UNI_LSQUO;
}
@@ -742,7 +1304,7 @@ void TextBufferWindow::putCharUni(glui32 ch) {
if (ch == '"')
{
- if (numchars == 0 || leftquote(chars[numchars - 1]))
+ if (numchars == 0 || leftquote(_chars[numchars - 1]))
ch = UNI_LDQUO;
else
ch = UNI_RDQUO;
@@ -810,23 +1372,23 @@ void TextBufferWindow::putCharUni(glui32 ch) {
}
}
- chars[numchars] = ch;
+ _chars[numchars] = ch;
attrs[numchars] = attr;
numchars++;
// kill spaces at the end for line width calculation
linelen = numchars;
- while (linelen > 1 && chars[linelen - 1] == ' '
+ while (linelen > 1 && _chars[linelen - 1] == ' '
&& styles[attrs[linelen - 1].style].bg == color
&& !styles[attrs[linelen - 1].style].reverse)
linelen--;
- if (calcwidth(dwin, chars, attrs, 0, linelen, -1) >= pw)
+ if (calcwidth(dwin, _chars, attrs, 0, linelen, -1) >= pw)
{
bpoint = numchars;
for (i = numchars - 1; i > 0; i--)
- if (chars[i] == ' ')
+ if (_chars[i] == ' ')
{
bpoint = i + 1; // skip space
break;
@@ -834,13 +1396,13 @@ void TextBufferWindow::putCharUni(glui32 ch) {
saved = numchars - bpoint;
- memcpy(bchars, chars + bpoint, saved * 4);
+ memcpy(bchars, _chars + bpoint, saved * 4);
memcpy(battrs, attrs + bpoint, saved * sizeof(attr_t));
numchars = bpoint;
scrolloneline(dwin, 0);
- memcpy(chars, bchars, saved * 4);
+ memcpy(_chars, bchars, saved * 4);
memcpy(attrs, battrs, saved * sizeof(attr_t));
numchars = saved;
}
@@ -849,23 +1411,83 @@ void TextBufferWindow::putCharUni(glui32 ch) {
*/
}
-void TextBufferWindow::putTextUnit(const glui32 *buf, int len, int pos, int oldlen) {
+bool TextBufferWindow::unputCharUni(uint32 ch) {
// TODO
+ return false;
}
-void TextBufferWindow::flowBreak() {
+void TextBufferWindow::putBuffer(const unsigned char *buf, size_t len) {
// TODO
}
-void TextBufferWindow::touch(int line) {
- int y = bbox.top + g_conf->_tMarginY + (_height - line - 1) * g_conf->_leading;
- _lines[line].dirty = 1;
- _windows->clearSelection();
- _windows->repaint(Common::Rect(bbox.left, y - 2, bbox.right, y + g_conf->_leading + 2));
+void TextBufferWindow::putBufferUni(const uint32 *buf, size_t len) {
+ // TODO
}
-glui32 TextBufferWindow::getSplit(glui32 size, bool vertical) const {
- return (vertical) ? size * g_conf->_cellW : size * g_conf->_cellH;
+void TextBufferWindow::moveCursor(const Common::Point &newPos) {
+ // TODO
+}
+
+void TextBufferWindow::clear() {
+ int i;
+
+ _attr.fgset = Windows::_overrideFgSet;
+ _attr.bgset = Windows::_overrideBgSet;
+ _attr.fgcolor = Windows::_overrideFgSet ? Windows::_overrideFgVal : 0;
+ _attr.bgcolor = Windows::_overrideBgSet ? Windows::_overrideBgVal : 0;
+ _attr.reverse = false;
+
+ _ladjw = _radjw = 0;
+ _ladjn = _radjn = 0;
+
+ _spaced = 0;
+ _dashed = 0;
+
+ _numChars = 0;
+
+ for (i = 0; i < _scrollBack; i++) {
+ _lines[i].len = 0;
+
+ if (_lines[i].lpic) _lines[i].lpic->decrement();
+ _lines[i].lpic = nullptr;
+ if (_lines[i].rpic) _lines[i].rpic->decrement();
+ _lines[i].rpic = nullptr;
+
+ _lines[i].lhyper = 0;
+ _lines[i].rhyper = 0;
+ _lines[i].lm = 0;
+ _lines[i].rm = 0;
+ _lines[i].newline = 0;
+ _lines[i].dirty = true;
+ _lines[i].repaint = false;
+ }
+
+ _lastSeen = 0;
+ _scrollPos = 0;
+ _scrollMax = 0;
+
+ for (i = 0; i < _height; i++)
+ touch(i);
+}
+
+void TextBufferWindow::requestLineEvent(char *buf, glui32 maxlen, glui32 initlen) {
+ if (_charRequest || _lineRequest || _charRequestUni || _lineRequestUni)
+ {
+ warning("request_line_event: window already has keyboard request");
+ return;
+ }
+
+ // TODO
+}
+
+void TextBufferWindow::requestLineEventUni(glui32 *buf, glui32 maxlen, glui32 initlen) {
+ if (_charRequest || _lineRequest || _charRequestUni || _lineRequestUni)
+ {
+ warning("request_line_event_uni: window already has keyboard request");
+ return;
+ }
+
+ // TODO
}
void TextBufferWindow::cancelLineEvent(Event *ev) {
@@ -899,18 +1521,15 @@ void TextBufferWindow::cancelLineEvent(Event *ev) {
if (len > inmax)
len = inmax;
- if (!unicode)
- {
- for (ix = 0; ix<len; ix++)
- {
+ if (!unicode) {
+ for (ix = 0; ix<len; ix++) {
glui32 ch = _chars[_inFence + ix];
if (ch > 0xff)
ch = '?';
((char *)inbuf)[ix] = (char)ch;
}
}
- else
- {
+ else {
for (ix = 0; ix<len; ix++)
((glui32 *)inbuf)[ix] = _chars[_inFence + ix];
}
@@ -933,7 +1552,8 @@ void TextBufferWindow::cancelLineEvent(Event *ev) {
if (_echoLineInput) {
putCharUni('\n');
- } else {
+ }
+ else {
_numChars = _inFence;
touch(0);
}
@@ -942,6 +1562,10 @@ void TextBufferWindow::cancelLineEvent(Event *ev) {
(*g_vm->gli_unregister_arr)(inbuf, inmax, unicode ? "&+#!Iu" : "&+#!Cn", inarrayrock);
}
+void TextBufferWindow::redraw() {
+ // TODO
+}
+
/*--------------------------------------------------------------------------*/
TextBufferWindow::TextBufferRow::TextBufferRow() : len(0), newline(0), dirty(false), repaint(false),
@@ -974,7 +1598,7 @@ void GraphicsWindow::rearrange(const Common::Rect &box) {
int oldw, oldh;
Graphics::ManagedSurface *newSurface;
- bbox = box;
+ _bbox = box;
newwid = box.width();
newhgt = box.height();
@@ -1013,7 +1637,11 @@ void GraphicsWindow::rearrange(const Common::Rect &box) {
void GraphicsWindow::touch() {
_dirty = true;
- _windows->repaint(bbox);
+ _windows->repaint(_bbox);
+}
+
+void GraphicsWindow::redraw() {
+ // TODO
}
/*--------------------------------------------------------------------------*/
@@ -1034,14 +1662,14 @@ void PairWindow::rearrange(const Common::Rect &box) {
int min, diff, split, splitwid, max;
Window *ch1, *ch2;
- bbox = box;
+ _bbox = box;
if (_vertical) {
- min = bbox.left;
- max = bbox.right;
+ min = _bbox.left;
+ max = _bbox.right;
} else {
- min = bbox.top;
- max = bbox.bottom;
+ min = _bbox.top;
+ max = _bbox.bottom;
}
diff = max - min;
@@ -1080,23 +1708,23 @@ void PairWindow::rearrange(const Common::Rect &box) {
}
if (_vertical) {
- box1.left = bbox.left;
+ box1.left = _bbox.left;
box1.right = split;
box2.left = split + splitwid;
- box2.right = bbox.right;
- box1.top = bbox.top;
- box1.bottom = bbox.bottom;
- box2.top = bbox.top;
- box2.bottom = bbox.bottom;
+ box2.right = _bbox.right;
+ box1.top = _bbox.top;
+ box1.bottom = _bbox.bottom;
+ box2.top = _bbox.top;
+ box2.bottom = _bbox.bottom;
} else {
- box1.top = bbox.top;
+ box1.top = _bbox.top;
box1.bottom = split;
box2.top = split + splitwid;
- box2.bottom = bbox.bottom;
- box1.left = bbox.left;
- box1.right = bbox.right;
- box2.left = bbox.left;
- box2.right = bbox.right;
+ box2.bottom = _bbox.bottom;
+ box1.left = _bbox.left;
+ box1.right = _bbox.right;
+ box2.left = _bbox.left;
+ box2.right = _bbox.right;
}
if (!_backward) {
@@ -1111,6 +1739,10 @@ void PairWindow::rearrange(const Common::Rect &box) {
ch2->rearrange(box2);
}
+void PairWindow::redraw() {
+ // TODO
+}
+
/*--------------------------------------------------------------------------*/
void Attributes::clear() {
@@ -1123,4 +1755,88 @@ void Attributes::clear() {
style = 0;
}
+byte *Attributes::attrBg(WindowStyle *styles) {
+ int revset = reverse || (styles[style].reverse && !Windows::_overrideReverse);
+
+ int zfset = fgset ? fgset : Windows::_overrideFgSet;
+ int zbset = bgset ? bgset : Windows::_overrideBgSet;
+
+ int zfore = fgset ? fgcolor : Windows::_overrideFgVal;
+ int zback = bgset ? bgcolor : Windows::_overrideBgVal;
+
+ if (zfset && zfore != Windows::_zcolor_fg) {
+ Windows::_zcolor_Foreground[0] = (zfore >> 16) & 0xff;
+ Windows::_zcolor_Foreground[1] = (zfore >> 8) & 0xff;
+ Windows::_zcolor_Foreground[2] = (zfore)& 0xff;
+ Windows::_zcolor_fg = zfore;
+ }
+
+ if (zbset && zback != Windows::_zcolor_bg) {
+ Windows::_zcolor_Background[0] = (zback >> 16) & 0xff;
+ Windows::_zcolor_Background[1] = (zback >> 8) & 0xff;
+ Windows::_zcolor_Background[2] = (zback)& 0xff;
+ Windows::_zcolor_bg = zback;
+ }
+
+ if (!revset) {
+ if (zbset)
+ return Windows::_zcolor_Background;
+ else
+ return styles[style].bg;
+ } else {
+ if (zfset)
+ if (zfore == zback)
+ return Windows::rgbShift(Windows::_zcolor_Foreground);
+ else
+ return Windows::_zcolor_Foreground;
+ else
+ if (zbset && !memcmp(styles[style].fg, Windows::_zcolor_Background, 3))
+ return Windows::_zcolor_LightGrey;
+ else
+ return styles[style].fg;
+ }
+}
+
+byte *Attributes::attrFg(WindowStyle *styles) {
+ int revset = reverse || (styles[style].reverse && !Windows::_overrideReverse);
+
+ int zfset = fgset ? fgset : Windows::_overrideFgSet;
+ int zbset = bgset ? bgset : Windows::_overrideBgSet;
+
+ int zfore = fgset ? fgcolor : Windows::_overrideFgVal;
+ int zback = bgset ? bgcolor : Windows::_overrideBgVal;
+
+ if (zfset && zfore != Windows::_zcolor_fg) {
+ Windows::_zcolor_Foreground[0] = (zfore >> 16) & 0xff;
+ Windows::_zcolor_Foreground[1] = (zfore >> 8) & 0xff;
+ Windows::_zcolor_Foreground[2] = (zfore)& 0xff;
+ Windows::_zcolor_fg = zfore;
+ }
+
+ if (zbset && zback != Windows::_zcolor_bg) {
+ Windows::_zcolor_Background[0] = (zback >> 16) & 0xff;
+ Windows::_zcolor_Background[1] = (zback >> 8) & 0xff;
+ Windows::_zcolor_Background[2] = (zback)& 0xff;
+ Windows::_zcolor_bg = zback;
+ }
+
+ if (!revset) {
+ if (zfset)
+ if (zfore == zback)
+ return Windows::rgbShift(Windows::_zcolor_Foreground);
+ else
+ return Windows::_zcolor_Foreground;
+ else
+ if (zbset && !memcmp(styles[style].fg, Windows::_zcolor_Background, 3))
+ return Windows::_zcolor_LightGrey;
+ else
+ return styles[style].fg;
+ } else {
+ if (zbset)
+ return Windows::_zcolor_Background;
+ else
+ return styles[style].bg;
+ }
+}
+
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/windows.h b/engines/gargoyle/windows.h
index 24043c6548..9a09641ca8 100644
--- a/engines/gargoyle/windows.h
+++ b/engines/gargoyle/windows.h
@@ -27,17 +27,18 @@
#include "common/list.h"
#include "common/rect.h"
#include "graphics/screen.h"
+#include "gargoyle/draw.h"
#include "gargoyle/events.h"
#include "gargoyle/glk_types.h"
#include "gargoyle/fonts.h"
#include "gargoyle/picture.h"
#include "gargoyle/streams.h"
+#include "gargoyle/window_mask.h"
namespace Gargoyle {
class Window;
class PairWindow;
-struct WindowMask;
#define HISTORYLEN 100
#define SCROLLBACK 512
@@ -47,6 +48,7 @@ struct WindowMask;
* Main windows manager
*/
class Windows {
+ friend class Window;
public:
class iterator {
private:
@@ -82,7 +84,6 @@ private:
Window * _windowList; ///< List of all windows
Window *_rootWin; ///< The topmost window
Window *_focusWin; ///< The window selected by the player
- bool _forceRedraw;
bool _moreFocus;
bool _claimSelect;
WindowMask *_mask;
@@ -105,8 +106,16 @@ public:
static bool _overrideReverse;
static bool _overrideFgSet;
static bool _overrideBgSet;
+ static bool _forceRedraw;
static int _overrideFgVal;
static int _overrideBgVal;
+ static int _zcolor_fg, _zcolor_bg;
+ static byte _zcolor_LightGrey[3];
+ static byte _zcolor_Foreground[3];
+ static byte _zcolor_Background[3];
+ static byte _zcolor_Bright[3];
+
+ static byte *rgbShift(byte *rgb);
public:
/**
* Constructor
@@ -114,6 +123,11 @@ public:
Windows(Graphics::Screen *screen);
/**
+ * Destructor
+ */
+ ~Windows();
+
+ /**
* Open a new window
*/
Window *windowOpen(Window *splitwin, glui32 method, glui32 size,
@@ -124,14 +138,35 @@ public:
*/
Window *getRoot() const { return _rootWin; }
+ /**
+ * Gets the focused window
+ */
+ Window *getFocusWindow() const { return _focusWin; }
+
+ /**
+ * Setst the focused window
+ */
+ void setFocus(Window *win) { _focusWin = win; }
+
void clearSelection();
+ void selectionChanged();
+
+ void clearClaimSelect() { _claimSelect = false; }
+
+ void redraw();
+
/**
* Repaint an area of the windows
*/
void repaint(const Common::Rect &box);
/**
+ * Draw an area of the windows
+ */
+ void drawRect(int x0, int y0, int w, int h, const byte *rgb);
+
+ /**
* Get an iterator that will move over the tree
*/
iterator begin() { return iterator(_windowList); }
@@ -140,6 +175,18 @@ public:
* Returns the end point of window iteration
*/
iterator end() { return iterator(nullptr); }
+
+ /**
+ * Gets a hyperlink
+ */
+ glui32 getHyperlink(const Common::Point &pos) { return _mask->getHyperlink(pos); }
+
+ /**
+ * Sets a hyperlink
+ */
+ void setHyperlink(glui32 linkval, uint x0, uint y0, uint x1, uint y1) {
+ return _mask->putHyperlink(linkval, x0, y0, x1, y1);
+ }
};
/**
@@ -176,21 +223,37 @@ struct Attributes {
* Clear
*/
void clear();
-};
-struct WindowMask {
- int hor;
- int ver;
- glui32 **links;
- Common::Rect select;
+ /**
+ * Set the style
+ */
+ void set(glui32 s) {
+ clear();
+ style = s;
+ }
+
+ /**
+ * Equality comparison
+ */
+ bool operator==(const Attributes &src) {
+ return fgset == src.fgset && bgset == src.bgset && reverse == src.reverse
+ && style == src.style && fgcolor == src.fgcolor && bgcolor == src.bgcolor
+ && hyper == src.hyper;
+ }
+
+ byte *attrBg(WindowStyle *styles);
+ byte *attrFg(WindowStyle *styles);
- WindowMask() : hor(0), ver(0), links(nullptr) {}
+ /**
+ * Get the font from the attribute's style
+ */
+ FACES attrFont(WindowStyle *styles) const { return styles[style].font; }
};
/**
* Window definition
*/
-class Window {
+class Window : public Draw {
public:
Windows *_windows;
glui32 _magicnum;
@@ -199,8 +262,8 @@ public:
Window *_parent; ///< pair window which contains this one
Window *_next, *_prev; ///< in the big linked list of windows
- Common::Rect bbox;
- int yadj;
+ Common::Rect _bbox;
+ int _yAdj;
Stream *_stream; ///< the window stream.
Stream *_echoStream; ///< the window's echo stream, if any.
@@ -216,7 +279,7 @@ public:
int _imageLoaded;
glui32 _echoLineInput;
- glui32 *_lineTerminators;
+ glui32 *_lineTerminatorsBase;
glui32 _termCt;
Attributes _attr;
@@ -224,6 +287,8 @@ public:
byte _fgColor[3];
gidispatch_rock_t _dispRock;
+protected:
+ bool checkTerminator(glui32 ch);
public:
/**
* Constructor
@@ -233,12 +298,12 @@ public:
/**
* Destructor
*/
- virtual ~Window() {}
+ virtual ~Window();
/**
* Rearranges the window
*/
- virtual void rearrange(const Common::Rect &box) { bbox = box; }
+ virtual void rearrange(const Common::Rect &box) { _bbox = box; }
/**
* Get window split size within parent pair window
@@ -246,29 +311,74 @@ public:
virtual glui32 getSplit(glui32 size, bool vertical) const { return 0; }
/**
- * Cancel a line event
+ * Write a character
*/
- virtual void cancelLineEvent(Event *ev);
+ virtual void putChar(unsigned char ch) {}
/**
- * Write a character
+ * Write a unicode character
*/
- virtual void putChar(unsigned char ch) { /* TODO */ }
+ virtual void putCharUni(uint32 ch) {}
/**
- * Write a unicode character
+ * Unput a unicode character
*/
- virtual void putCharUni(uint32 ch) { /* TODO */ }
+ virtual bool unputCharUni(uint32 ch) { return false; }
/**
* Write a buffer
*/
- virtual void putBuffer(const unsigned char *buf, size_t len) { /* TODO */ }
+ virtual void putBuffer(const unsigned char *buf, size_t len) {}
/**
* Write a unicode character
*/
- virtual void putBufferUni(const uint32 *buf, size_t len) { /* TODO */ }
+ virtual void putBufferUni(const uint32 *buf, size_t len) {}
+
+ /**
+ * Move the cursor
+ */
+ virtual void moveCursor(const Common::Point &newPos) {}
+
+ /**
+ * Clear the window
+ */
+ virtual void clear() {}
+
+ /**
+ * Click the window
+ */
+ virtual void click(const Common::Point &newPos) {}
+
+ /**
+ * Prepare for inputing a line
+ */
+ virtual void requestLineEvent(char *buf, glui32 maxlen, glui32 initlen);
+
+ /**
+ * Prepare for inputing a line
+ */
+ virtual void requestLineEventUni(glui32 *buf, glui32 maxlen, glui32 initlen);
+
+ /**
+ * Cancel an input line event
+ */
+ virtual void cancelLineEvent(Event *ev);
+
+ /**
+ * Cancel a mouse event
+ */
+ virtual void cancelMouseEvent() {}
+
+ /**
+ * Cancel a hyperlink event
+ */
+ virtual void cancelHyperlinkEvent() {}
+
+ /**
+ * Redraw the window
+ */
+ virtual void redraw();
};
typedef Window *winid_t;
@@ -291,8 +401,8 @@ class TextGridWindow : public Window {
* Structure for a row within the grid window
*/
struct TextGridRow {
- Common::Array<uint32> chars;
- Common::Array<Attributes> attr;
+ Common::Array<uint32> _chars;
+ Common::Array<Attributes> _attrs;
bool dirty;
/**
@@ -311,13 +421,25 @@ private:
* Mark a given text row as modified
*/
void touch(int line);
+
+ void acceptReadChar(glui32 arg);
+
+ /**
+ * Return or enter, during line input. Ends line input.
+ */
+ void acceptLine(glui32 keycode);
+
+ /**
+ * Any regular key, during line input.
+ */
+ void acceptReadLine(glui32 arg);
public:
int _width, _height;
TextGridRows _lines;
int _curX, _curY; ///< the window cursor position
- ///< for line input
+ ///< for line input
void *_inBuf; ///< unsigned char* for latin1, glui32* for unicode
int _inOrgX, _inOrgY;
int _inMax;
@@ -349,9 +471,74 @@ public:
virtual glui32 getSplit(glui32 size, bool vertical) const override;
/**
- * Cancel a line event
+ * Write a character
+ */
+ virtual void putChar(unsigned char ch) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putCharUni(uint32 ch) override;
+
+ /**
+ * Unput a unicode character
+ */
+ virtual bool unputCharUni(uint32 ch) override;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const unsigned char *buf, size_t len) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) override;
+
+ /**
+ * Move the cursor
+ */
+ virtual void moveCursor(const Common::Point &newPos) override;
+
+ /**
+ * Clear the window
+ */
+ virtual void clear() override;
+
+ /**
+ * Click the window
+ */
+ virtual void click(const Common::Point &newPos) override;
+
+ /**
+ * Prepare for inputing a line
+ */
+ virtual void requestLineEvent(char *buf, glui32 maxlen, glui32 initlen) override;
+
+ /**
+ * Prepare for inputing a line
+ */
+ virtual void requestLineEventUni(glui32 *buf, glui32 maxlen, glui32 initlen) override;
+
+ /**
+ * Cancel an input line event
*/
virtual void cancelLineEvent(Event *ev) override;
+
+ /**
+ * Cancel a mouse event
+ */
+ virtual void cancelMouseEvent() override { _mouseRequest = false; }
+
+ /**
+ * Cancel a hyperlink event
+ */
+ virtual void cancelHyperlinkEvent() override { _hyperRequest = false; }
+
+ /**
+ * Redraw the window
+ */
+ virtual void redraw() override;
};
/**
@@ -385,8 +572,7 @@ private:
void reflow();
void touchScroll();
bool putPicture(Picture *pic, glui32 align, glui32 linkval);
- void putCharUni(glui32 ch);
- void putTextUnit(const glui32 *buf, int len, int pos, int oldlen);
+ void putTextUni(const glui32 *buf, int len, int pos, int oldlen);
void flowBreak();
/**
@@ -460,14 +646,64 @@ public:
virtual glui32 getSplit(glui32 size, bool vertical) const override;
/**
- * Cancel a line event
+ * Write a character
*/
- virtual void cancelLineEvent(Event *ev) override;
+ virtual void putChar(unsigned char ch) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putCharUni(uint32 ch) override;
+
+ /**
+ * Unput a unicode character
+ */
+ virtual bool unputCharUni(uint32 ch) override;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const unsigned char *buf, size_t len) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) override;
+
+ /**
+ * Move the cursor
+ */
+ virtual void moveCursor(const Common::Point &newPos) override;
/**
* Clear the window
*/
- void clear();
+ virtual void clear() override;
+
+ /**
+ * Prepare for inputing a line
+ */
+ virtual void requestLineEvent(char *buf, glui32 maxlen, glui32 initlen) override;
+
+ /**
+ * Prepare for inputing a line
+ */
+ virtual void requestLineEventUni(glui32 *buf, glui32 maxlen, glui32 initlen) override;
+
+ /**
+ * Cancel an input line event
+ */
+ virtual void cancelLineEvent(Event *ev) override;
+
+ /**
+ * Cancel a hyperlink event
+ */
+ virtual void cancelHyperlinkEvent() override { _hyperRequest = false; }
+
+ /**
+ * Redraw the window
+ */
+ virtual void redraw() override;
};
/**
@@ -479,7 +715,7 @@ private:
public:
unsigned char _bgnd[3];
bool _dirty;
- int _w, _h;
+ glui32 _w, _h;
Graphics::ManagedSurface *_surface;
public:
/**
@@ -503,6 +739,29 @@ public:
virtual glui32 getSplit(glui32 size, bool vertical) const override {
return size;
}
+
+ /**
+ * Cancel a mouse event
+ */
+ virtual void cancelMouseEvent() override { _mouseRequest = false; }
+
+ /**
+ * Cancel a hyperlink event
+ */
+ virtual void cancelHyperlinkEvent() override { _hyperRequest = false; }
+
+ /**
+ * Redraw the window
+ */
+ virtual void redraw() override;
+
+ /**
+ * Get the window dimensions
+ */
+ void getSize(glui32 *w, glui32 *h) {
+ *w = _w;
+ *h = _h;
+ }
};
/**
@@ -530,6 +789,11 @@ public:
* Rearranges the window
*/
virtual void rearrange(const Common::Rect &box) override;
+
+ /**
+ * Redraw the window
+ */
+ virtual void redraw() override;
};
} // End of namespace Gargoyle