mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-11 12:18:05 +00:00
GLK: Split the windows.cpp file into separate files for each window class
This commit is contained in:
parent
0d3ad2dc8a
commit
8708ed4f9a
@ -11,8 +11,12 @@ MODULE_OBJS := \
|
||||
picture.o \
|
||||
streams.o \
|
||||
string.o \
|
||||
window_mask.o \
|
||||
windows.o \
|
||||
window_mask.o \
|
||||
window_graphics.o \
|
||||
window_pair.o \
|
||||
window_text_buffer.o \
|
||||
window_text_grid.o \
|
||||
scott/detection.o \
|
||||
scott/scott.o
|
||||
|
||||
|
89
engines/gargoyle/window_graphics.cpp
Normal file
89
engines/gargoyle/window_graphics.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/* 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_graphics.h"
|
||||
|
||||
namespace Gargoyle {
|
||||
|
||||
GraphicsWindow::GraphicsWindow(Windows *windows, uint32 rock) : Window(windows, rock),
|
||||
_w(0), _h(0), _dirty(false), _surface(nullptr) {
|
||||
_type = wintype_Graphics;
|
||||
Common::copy(&_bgColor[0], &_bgColor[3], _bgnd);
|
||||
}
|
||||
|
||||
GraphicsWindow::~GraphicsWindow() {
|
||||
delete _surface;
|
||||
}
|
||||
|
||||
void GraphicsWindow::rearrange(const Common::Rect &box) {
|
||||
int newwid, newhgt;
|
||||
int bothwid, bothhgt;
|
||||
int oldw, oldh;
|
||||
Graphics::ManagedSurface *newSurface;
|
||||
|
||||
_bbox = box;
|
||||
|
||||
newwid = box.width();
|
||||
newhgt = box.height();
|
||||
oldw = _w;
|
||||
oldh = _h;
|
||||
|
||||
if (newwid <= 0 || newhgt <= 0) {
|
||||
_w = 0;
|
||||
_h = 0;
|
||||
delete _surface;
|
||||
_surface = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
bothwid = _w;
|
||||
if (newwid < bothwid)
|
||||
bothwid = newwid;
|
||||
bothhgt = _h;
|
||||
if (newhgt < bothhgt)
|
||||
bothhgt = newhgt;
|
||||
|
||||
newSurface = new Graphics::ManagedSurface(newwid, newhgt,
|
||||
Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0));
|
||||
|
||||
// If the new surface is equal or bigger than the old one, copy it over
|
||||
if (_surface && bothwid && bothhgt)
|
||||
newSurface->blitFrom(*_surface);
|
||||
|
||||
delete _surface;
|
||||
_surface = newSurface;
|
||||
_w = newwid;
|
||||
_h = newhgt;
|
||||
|
||||
touch();
|
||||
}
|
||||
|
||||
void GraphicsWindow::touch() {
|
||||
_dirty = true;
|
||||
_windows->repaint(_bbox);
|
||||
}
|
||||
|
||||
void GraphicsWindow::redraw() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
} // End of namespace Gargoyle
|
91
engines/gargoyle/window_graphics.h
Normal file
91
engines/gargoyle/window_graphics.h
Normal file
@ -0,0 +1,91 @@
|
||||
/* 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_GRAPHICS_H
|
||||
#define GARGOYLE_WINDOW_GRAPHICS_H
|
||||
|
||||
#include "gargoyle/windows.h"
|
||||
#include "gargoyle/picture.h"
|
||||
|
||||
namespace Gargoyle {
|
||||
|
||||
/**
|
||||
* Graphics window
|
||||
*/
|
||||
class GraphicsWindow : public Window {
|
||||
private:
|
||||
void touch();
|
||||
public:
|
||||
unsigned char _bgnd[3];
|
||||
bool _dirty;
|
||||
glui32 _w, _h;
|
||||
Graphics::ManagedSurface *_surface;
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
GraphicsWindow(Windows *windows, uint32 rock);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~GraphicsWindow();
|
||||
|
||||
/**
|
||||
* Rearranges the window
|
||||
*/
|
||||
virtual void rearrange(const Common::Rect &box) override;
|
||||
|
||||
/**
|
||||
* Get window split size within parent pair window
|
||||
*/
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Gargoyle
|
||||
|
||||
#endif
|
125
engines/gargoyle/window_pair.cpp
Normal file
125
engines/gargoyle/window_pair.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/* 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_pair.h"
|
||||
#include "gargoyle/conf.h"
|
||||
|
||||
namespace Gargoyle {
|
||||
|
||||
PairWindow::PairWindow(Windows *windows, glui32 method, Window *key, glui32 size) :
|
||||
Window(windows, 0),
|
||||
_dir(method & winmethod_DirMask),
|
||||
_division(method & winmethod_DivisionMask),
|
||||
_wBorder((method & winmethod_BorderMask) == winmethod_Border),
|
||||
_vertical(_dir == winmethod_Left || _dir == winmethod_Right),
|
||||
_backward(_dir == winmethod_Left || _dir == winmethod_Above),
|
||||
_key(key), _size(size), _keyDamage(0), _child1(nullptr), _child2(nullptr) {
|
||||
_type = wintype_Pair;
|
||||
}
|
||||
|
||||
void PairWindow::rearrange(const Common::Rect &box) {
|
||||
Common::Rect box1, box2;
|
||||
int min, diff, split, splitwid, max;
|
||||
Window *ch1, *ch2;
|
||||
|
||||
_bbox = box;
|
||||
|
||||
if (_vertical) {
|
||||
min = _bbox.left;
|
||||
max = _bbox.right;
|
||||
} else {
|
||||
min = _bbox.top;
|
||||
max = _bbox.bottom;
|
||||
}
|
||||
diff = max - min;
|
||||
|
||||
// We now figure split.
|
||||
if (_vertical)
|
||||
splitwid = g_conf->_wPaddingX; // want border?
|
||||
else
|
||||
splitwid = g_conf->_wPaddingY; // want border?
|
||||
|
||||
switch (_division) {
|
||||
case winmethod_Proportional:
|
||||
split = (diff * _size) / 100;
|
||||
break;
|
||||
|
||||
case winmethod_Fixed:
|
||||
split = !_key ? 0 : _key->getSplit(_size, _vertical);
|
||||
break;
|
||||
|
||||
default:
|
||||
split = diff / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_backward)
|
||||
split = max - split - splitwid;
|
||||
else
|
||||
split = min + split;
|
||||
|
||||
if (min >= max) {
|
||||
split = min;
|
||||
} else {
|
||||
if (split < min)
|
||||
split = min;
|
||||
else if (split > max - splitwid)
|
||||
split = max - splitwid;
|
||||
}
|
||||
|
||||
if (_vertical) {
|
||||
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;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
if (!_backward) {
|
||||
ch1 = _child1;
|
||||
ch2 = _child2;
|
||||
} else {
|
||||
ch1 = _child2;
|
||||
ch2 = _child1;
|
||||
}
|
||||
|
||||
ch1->rearrange(box1);
|
||||
ch2->rearrange(box2);
|
||||
}
|
||||
|
||||
void PairWindow::redraw() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
} // End of namespace Gargoyle
|
64
engines/gargoyle/window_pair.h
Normal file
64
engines/gargoyle/window_pair.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* 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_PAIR_H
|
||||
#define GARGOYLE_WINDOW_PAIR_H
|
||||
|
||||
#include "gargoyle/windows.h"
|
||||
|
||||
namespace Gargoyle {
|
||||
|
||||
/**
|
||||
* Pair window
|
||||
*/
|
||||
class PairWindow : public Window {
|
||||
public:
|
||||
Window *_child1, *_child2;
|
||||
|
||||
/* split info... */
|
||||
glui32 _dir; ///< winmethod_Left, Right, Above, or Below
|
||||
bool _vertical, _backward; ///< flags
|
||||
glui32 _division; ///< winmethod_Fixed or winmethod_Proportional
|
||||
Window *_key; ///< NULL or a leaf-descendant (not a Pair)
|
||||
int _keyDamage; ///< used as scratch space in window closing
|
||||
glui32 _size; ///< size value
|
||||
glui32 _wBorder; ///< winMethod_Border, NoBorder
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
PairWindow(Windows *windows, glui32 method, Window *key, glui32 size);
|
||||
|
||||
/**
|
||||
* Rearranges the window
|
||||
*/
|
||||
virtual void rearrange(const Common::Rect &box) override;
|
||||
|
||||
/**
|
||||
* Redraw the window
|
||||
*/
|
||||
virtual void redraw() override;
|
||||
};
|
||||
|
||||
} // End of namespace Gargoyle
|
||||
|
||||
#endif
|
602
engines/gargoyle/window_text_buffer.cpp
Normal file
602
engines/gargoyle/window_text_buffer.cpp
Normal file
@ -0,0 +1,602 @@
|
||||
/* 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_text_buffer.h"
|
||||
#include "gargoyle/conf.h"
|
||||
#include "gargoyle/gargoyle.h"
|
||||
|
||||
namespace Gargoyle {
|
||||
|
||||
TextBufferWindow::TextBufferWindow(Windows *windows, uint32 rock) : Window(windows, rock),
|
||||
_historyPos(0), _historyFirst(0), _historyPresent(0), _lastSeen(0), _scrollPos(0),
|
||||
_scrollMax(0), _scrollBack(SCROLLBACK), _width(-1), _height(-1), _inBuf(nullptr),
|
||||
_lineTerminators(nullptr), _echoLineInput(true), _ladjw(0), _radjw(0), _ladjn(0),
|
||||
_radjn(0), _numChars(0), _chars(nullptr), _attrs(nullptr),
|
||||
_spaced(0), _dashed(0), _copyBuf(0), _copyPos(0) {
|
||||
_type = wintype_TextBuffer;
|
||||
Common::fill(&_history[0], &_history[HISTORYLEN], nullptr);
|
||||
|
||||
Common::copy(&g_conf->_tStyles[0], &g_conf->_tStyles[style_NUMSTYLES], styles);
|
||||
}
|
||||
|
||||
TextBufferWindow::~TextBufferWindow() {
|
||||
if (_inBuf) {
|
||||
if (g_vm->gli_unregister_arr)
|
||||
(*g_vm->gli_unregister_arr)(_inBuf, _inMax, "&+#!Cn", _inArrayRock);
|
||||
_inBuf = nullptr;
|
||||
}
|
||||
|
||||
delete[] _copyBuf;
|
||||
delete[] _lineTerminators;
|
||||
|
||||
for (int i = 0; i < _scrollBack; i++) {
|
||||
if (_lines[i].lpic)
|
||||
_lines[i].lpic->decrement();
|
||||
if (_lines[i].rpic)
|
||||
_lines[i].rpic->decrement();
|
||||
}
|
||||
}
|
||||
|
||||
void TextBufferWindow::rearrange(const Common::Rect &box) {
|
||||
Window::rearrange(box);
|
||||
int newwid, newhgt;
|
||||
int rnd;
|
||||
|
||||
newwid = (box.width() - g_conf->_tMarginX * 2 - g_conf->_scrollWidth) / g_conf->_cellW;
|
||||
newhgt = (box.height() - g_conf->_tMarginY * 2) / g_conf->_cellH;
|
||||
|
||||
/* align text with bottom */
|
||||
rnd = newhgt * g_conf->_cellH + g_conf->_tMarginY * 2;
|
||||
_yAdj = (box.height() - rnd);
|
||||
_bbox.top += (box.height() - rnd);
|
||||
|
||||
if (newwid != _width) {
|
||||
_width = newwid;
|
||||
reflow();
|
||||
}
|
||||
|
||||
if (newhgt != _height) {
|
||||
/* scroll up if we obscure new lines */
|
||||
if (_lastSeen >= newhgt - 1)
|
||||
_scrollPos += (_height - newhgt);
|
||||
|
||||
_height = newhgt;
|
||||
|
||||
/* keep window within 'valid' lines */
|
||||
if (_scrollPos > _scrollMax - _height + 1)
|
||||
_scrollPos = _scrollMax - _height + 1;
|
||||
if (_scrollPos < 0)
|
||||
_scrollPos = 0;
|
||||
touchScroll();
|
||||
|
||||
/* allocate copy buffer */
|
||||
if (_copyBuf)
|
||||
delete[] _copyBuf;
|
||||
_copyBuf = new glui32[_height * TBLINELEN];
|
||||
|
||||
for (int i = 0; i < (_height * TBLINELEN); i++)
|
||||
_copyBuf[i] = 0;
|
||||
|
||||
_copyPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TextBufferWindow::reflow() {
|
||||
int inputbyte = -1;
|
||||
Attributes curattr, oldattr;
|
||||
int i, k, p, s;
|
||||
int x;
|
||||
|
||||
if (_height < 4 || _width < 20)
|
||||
return;
|
||||
|
||||
_lines[0].len = _numChars;
|
||||
|
||||
/* allocate temp buffers */
|
||||
Attributes *attrbuf = new Attributes[SCROLLBACK * TBLINELEN];
|
||||
glui32 *charbuf = new glui32[SCROLLBACK * TBLINELEN];
|
||||
int *alignbuf = new int[SCROLLBACK];
|
||||
Picture **pictbuf = new Picture *[SCROLLBACK];
|
||||
glui32 *hyperbuf = new glui32[SCROLLBACK];
|
||||
int *offsetbuf = new int[SCROLLBACK];
|
||||
|
||||
if (!attrbuf || !charbuf || !alignbuf || !pictbuf || !hyperbuf || !offsetbuf) {
|
||||
delete[] attrbuf;
|
||||
delete[] charbuf;
|
||||
delete[] alignbuf;
|
||||
delete[] pictbuf;
|
||||
delete[] hyperbuf;
|
||||
delete[] offsetbuf;
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy text to temp buffers */
|
||||
|
||||
oldattr = _attr;
|
||||
curattr.clear();
|
||||
|
||||
x = 0;
|
||||
p = 0;
|
||||
s = _scrollMax < SCROLLBACK ? _scrollMax : SCROLLBACK - 1;
|
||||
|
||||
for (k = s; k >= 0; k--) {
|
||||
if (k == 0 && _lineRequest)
|
||||
inputbyte = p + _inFence;
|
||||
|
||||
if (_lines[k].lpic) {
|
||||
offsetbuf[x] = p;
|
||||
alignbuf[x] = imagealign_MarginLeft;
|
||||
pictbuf[x] = _lines[k].lpic;
|
||||
|
||||
if (pictbuf[x]) pictbuf[x]->increment();
|
||||
hyperbuf[x] = _lines[k].lhyper;
|
||||
x++;
|
||||
}
|
||||
|
||||
if (_lines[k].rpic) {
|
||||
offsetbuf[x] = p;
|
||||
alignbuf[x] = imagealign_MarginRight;
|
||||
pictbuf[x] = _lines[k].rpic;
|
||||
if (pictbuf[x]) pictbuf[x]->increment();
|
||||
hyperbuf[x] = _lines[k].rhyper;
|
||||
x++;
|
||||
}
|
||||
|
||||
for (i = 0; i < _lines[k].len; i++) {
|
||||
attrbuf[p] = curattr = _lines[k].attr[i];
|
||||
charbuf[p] = _lines[k].chars[i];
|
||||
p++;
|
||||
}
|
||||
|
||||
if (_lines[k].newline) {
|
||||
attrbuf[p] = curattr;
|
||||
charbuf[p] = '\n';
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
offsetbuf[x] = -1;
|
||||
|
||||
/* clear window */
|
||||
|
||||
clear();
|
||||
|
||||
/* and dump text back */
|
||||
|
||||
x = 0;
|
||||
for (i = 0; i < p; i++) {
|
||||
if (i == inputbyte)
|
||||
break;
|
||||
_attr = attrbuf[i];
|
||||
|
||||
if (offsetbuf[x] == i) {
|
||||
putPicture(pictbuf[x], alignbuf[x], hyperbuf[x]);
|
||||
x++;
|
||||
}
|
||||
|
||||
putCharUni(charbuf[i]);
|
||||
}
|
||||
|
||||
/* terribly sorry about this... */
|
||||
_lastSeen = 0;
|
||||
_scrollPos = 0;
|
||||
|
||||
if (inputbyte != -1) {
|
||||
_inFence = _numChars;
|
||||
putTextUni(charbuf + inputbyte, p - inputbyte, _numChars, 0);
|
||||
_inCurs = _numChars;
|
||||
}
|
||||
|
||||
// free temp buffers
|
||||
delete[] attrbuf;
|
||||
delete[] charbuf;
|
||||
delete[] alignbuf;
|
||||
delete[] pictbuf;
|
||||
delete[] hyperbuf;
|
||||
delete[] offsetbuf;
|
||||
|
||||
_attr = oldattr;
|
||||
|
||||
touchScroll();
|
||||
}
|
||||
|
||||
void TextBufferWindow::touchScroll() {
|
||||
_windows->clearSelection();
|
||||
_windows->repaint(_bbox);
|
||||
|
||||
for (int i = 0; i < _scrollMax; i++)
|
||||
_lines[i].dirty = true;
|
||||
}
|
||||
|
||||
bool TextBufferWindow::putPicture(Picture *pic, glui32 align, glui32 linkval) {
|
||||
if (align == imagealign_MarginRight)
|
||||
{
|
||||
if (_lines[0].rpic || _numChars)
|
||||
return false;
|
||||
|
||||
_radjw = (pic->w + g_conf->_tMarginX) * GLI_SUBPIX;
|
||||
_radjn = (pic->h + g_conf->_cellH - 1) / g_conf->_cellH;
|
||||
_lines[0].rpic = pic;
|
||||
_lines[0].rm = _radjw;
|
||||
_lines[0].rhyper = linkval;
|
||||
} else {
|
||||
if (align != imagealign_MarginLeft && _numChars)
|
||||
putCharUni('\n');
|
||||
|
||||
if (_lines[0].lpic || _numChars)
|
||||
return false;
|
||||
|
||||
_ladjw = (pic->w + g_conf->_tMarginX) * GLI_SUBPIX;
|
||||
_ladjn = (pic->h + g_conf->_cellH - 1) / g_conf->_cellH;
|
||||
_lines[0].lpic = pic;
|
||||
_lines[0].lm = _ladjw;
|
||||
_lines[0].lhyper = linkval;
|
||||
|
||||
if (align != imagealign_MarginLeft)
|
||||
flowBreak();
|
||||
}
|
||||
|
||||
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) {
|
||||
/*
|
||||
glui32 bchars[TBLINELEN];
|
||||
Attributes battrs[TBLINELEN];
|
||||
int pw;
|
||||
int bpoint;
|
||||
int saved;
|
||||
int i;
|
||||
int linelen;
|
||||
unsigned char *color;
|
||||
|
||||
gli_tts_speak(&ch, 1);
|
||||
|
||||
pw = (_bbox.right - _bbox.left - g_conf->_tMarginX * 2 - gli_scroll_width) * GLI_SUBPIX;
|
||||
pw = pw - 2 * SLOP - radjw - ladjw;
|
||||
|
||||
color = Windows::_overrideBgSet ? gli_window_color : bgcolor;
|
||||
|
||||
// oops ... overflow
|
||||
if (numchars + 1 >= TBLINELEN)
|
||||
scrolloneline(dwin, 0);
|
||||
|
||||
if (ch == '\n') {
|
||||
scrolloneline(dwin, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gli_conf_quotes) {
|
||||
// fails for 'tis a wonderful day in the '80s
|
||||
if (gli_conf_quotes > 1 && ch == '\'')
|
||||
{
|
||||
if (numchars == 0 || leftquote(_chars[numchars - 1]))
|
||||
ch = UNI_LSQUO;
|
||||
}
|
||||
|
||||
if (ch == '`')
|
||||
ch = UNI_LSQUO;
|
||||
|
||||
if (ch == '\'')
|
||||
ch = UNI_RSQUO;
|
||||
|
||||
if (ch == '"')
|
||||
{
|
||||
if (numchars == 0 || leftquote(_chars[numchars - 1]))
|
||||
ch = UNI_LDQUO;
|
||||
else
|
||||
ch = UNI_RDQUO;
|
||||
}
|
||||
}
|
||||
|
||||
if (gli_conf_dashes && attr.style != style_Preformatted)
|
||||
{
|
||||
if (ch == '-')
|
||||
{
|
||||
dashed++;
|
||||
if (dashed == 2)
|
||||
{
|
||||
numchars--;
|
||||
if (gli_conf_dashes == 2)
|
||||
ch = UNI_NDASH;
|
||||
else
|
||||
ch = UNI_MDASH;
|
||||
}
|
||||
if (dashed == 3)
|
||||
{
|
||||
numchars--;
|
||||
ch = UNI_MDASH;
|
||||
dashed = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
dashed = 0;
|
||||
}
|
||||
|
||||
if (gli_conf_spaces && attr.style != style_Preformatted
|
||||
&& styles[attr.style].bg == color
|
||||
&& !styles[attr.style].reverse)
|
||||
{
|
||||
// turn (period space space) into (period space)
|
||||
if (gli_conf_spaces == 1)
|
||||
{
|
||||
if (ch == '.')
|
||||
spaced = 1;
|
||||
else if (ch == ' ' && spaced == 1)
|
||||
spaced = 2;
|
||||
else if (ch == ' ' && spaced == 2)
|
||||
{
|
||||
spaced = 0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
spaced = 0;
|
||||
}
|
||||
|
||||
// Turn (per sp x) into (per sp sp x)
|
||||
if (gli_conf_spaces == 2)
|
||||
{
|
||||
if (ch == '.')
|
||||
spaced = 1;
|
||||
else if (ch == ' ' && spaced == 1)
|
||||
spaced = 2;
|
||||
else if (ch != ' ' && spaced == 2)
|
||||
{
|
||||
spaced = 0;
|
||||
win_textbuffer_putchar_uni(win, ' ');
|
||||
}
|
||||
else
|
||||
spaced = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_chars[numchars] = ch;
|
||||
attrs[numchars] = attr;
|
||||
numchars++;
|
||||
|
||||
// kill spaces at the end for line width calculation
|
||||
linelen = numchars;
|
||||
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)
|
||||
{
|
||||
bpoint = numchars;
|
||||
|
||||
for (i = numchars - 1; i > 0; i--)
|
||||
if (_chars[i] == ' ')
|
||||
{
|
||||
bpoint = i + 1; // skip space
|
||||
break;
|
||||
}
|
||||
|
||||
saved = numchars - bpoint;
|
||||
|
||||
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(attrs, battrs, saved * sizeof(attr_t));
|
||||
numchars = saved;
|
||||
}
|
||||
|
||||
touch(0);
|
||||
*/
|
||||
}
|
||||
|
||||
bool TextBufferWindow::unputCharUni(uint32 ch) {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
void TextBufferWindow::putBuffer(const unsigned char *buf, size_t len) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void TextBufferWindow::putBufferUni(const uint32 *buf, size_t len) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
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) {
|
||||
gidispatch_rock_t inarrayrock;
|
||||
int ix;
|
||||
int len;
|
||||
void *inbuf;
|
||||
int inmax;
|
||||
int unicode = _lineRequestUni;
|
||||
Event dummyEv;
|
||||
|
||||
if (!ev)
|
||||
ev = &dummyEv;
|
||||
|
||||
g_vm->_events->clearEvent(ev);
|
||||
|
||||
if (!_lineRequest && !_lineRequestUni)
|
||||
return;
|
||||
|
||||
if (!_inBuf)
|
||||
return;
|
||||
|
||||
inbuf = _inBuf;
|
||||
inmax = _inMax;
|
||||
inarrayrock = _inArrayRock;
|
||||
|
||||
len = _numChars - _inFence;
|
||||
if (_echoStream)
|
||||
_echoStream->echoLineUni(_chars + _inFence, len);
|
||||
|
||||
if (len > inmax)
|
||||
len = inmax;
|
||||
|
||||
if (!unicode) {
|
||||
for (ix = 0; ix<len; ix++) {
|
||||
glui32 ch = _chars[_inFence + ix];
|
||||
if (ch > 0xff)
|
||||
ch = '?';
|
||||
((char *)inbuf)[ix] = (char)ch;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (ix = 0; ix<len; ix++)
|
||||
((glui32 *)inbuf)[ix] = _chars[_inFence + ix];
|
||||
}
|
||||
|
||||
_attr = _origAttr;
|
||||
|
||||
ev->_type = evtype_LineInput;
|
||||
ev->_window = this;
|
||||
ev->_val1 = len;
|
||||
ev->_val2 = 0;
|
||||
|
||||
_lineRequest = false;
|
||||
_lineRequestUni = false;
|
||||
if (_lineTerminators) {
|
||||
free(_lineTerminators);
|
||||
_lineTerminators = nullptr;
|
||||
}
|
||||
_inBuf = nullptr;
|
||||
_inMax = 0;
|
||||
|
||||
if (_echoLineInput) {
|
||||
putCharUni('\n');
|
||||
}
|
||||
else {
|
||||
_numChars = _inFence;
|
||||
touch(0);
|
||||
}
|
||||
|
||||
if (g_vm->gli_unregister_arr)
|
||||
(*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),
|
||||
lpic(nullptr), rpic(nullptr), lhyper(0), rhyper(0), lm(0), rm(0) {
|
||||
}
|
||||
|
||||
void TextBufferWindow::TextBufferRow::resize(size_t newSize) {
|
||||
chars.clear();
|
||||
attr.clear();
|
||||
chars.resize(newSize);
|
||||
attr.resize(newSize);
|
||||
Common::fill(&chars[0], &chars[0] + newSize, ' ');
|
||||
}
|
||||
|
||||
} // End of namespace Gargoyle
|
198
engines/gargoyle/window_text_buffer.h
Normal file
198
engines/gargoyle/window_text_buffer.h
Normal file
@ -0,0 +1,198 @@
|
||||
/* 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_TEXT_BUFFER_H
|
||||
#define GARGOYLE_WINDOW_TEXT_BUFFER_H
|
||||
|
||||
#include "gargoyle/windows.h"
|
||||
#include "gargoyle/picture.h"
|
||||
|
||||
namespace Gargoyle {
|
||||
|
||||
/**
|
||||
* Text Buffer window
|
||||
*/
|
||||
class TextBufferWindow : public Window {
|
||||
/**
|
||||
* Structure for a row within the window
|
||||
*/
|
||||
struct TextBufferRow {
|
||||
Common::Array<uint32> chars;
|
||||
Common::Array<Attributes> attr;
|
||||
int len, newline;
|
||||
bool dirty, repaint;
|
||||
Picture *lpic, *rpic;
|
||||
glui32 lhyper, rhyper;
|
||||
int lm, rm;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TextBufferRow();
|
||||
|
||||
/**
|
||||
* Resize the row
|
||||
*/
|
||||
void resize(size_t newSize);
|
||||
};
|
||||
typedef Common::Array<TextBufferRow> TextBufferRows;
|
||||
private:
|
||||
void reflow();
|
||||
void touchScroll();
|
||||
bool putPicture(Picture *pic, glui32 align, glui32 linkval);
|
||||
void putTextUni(const glui32 *buf, int len, int pos, int oldlen);
|
||||
void flowBreak();
|
||||
|
||||
/**
|
||||
* Mark a given text row as modified
|
||||
*/
|
||||
void touch(int line);
|
||||
public:
|
||||
int _width, _height;
|
||||
int _spaced;
|
||||
int _dashed;
|
||||
|
||||
TextBufferRows _lines;
|
||||
int _scrollBack;
|
||||
|
||||
int _numChars; ///< number of chars in last line: lines[0]
|
||||
glui32 *_chars; ///< alias to lines[0].chars
|
||||
Attributes *_attrs; ///< alias to lines[0].attrs
|
||||
|
||||
///< adjust margins temporarily for images
|
||||
int _ladjw;
|
||||
int _ladjn;
|
||||
int _radjw;
|
||||
int _radjn;
|
||||
|
||||
/* Command history. */
|
||||
glui32 *_history[HISTORYLEN];
|
||||
int _historyPos;
|
||||
int _historyFirst, _historyPresent;
|
||||
|
||||
/* for paging */
|
||||
int _lastSeen;
|
||||
int _scrollPos;
|
||||
int _scrollMax;
|
||||
|
||||
/* for line input */
|
||||
void *_inBuf; ///< unsigned char* for latin1, glui32* for unicode
|
||||
int _inMax;
|
||||
long _inFence;
|
||||
long _inCurs;
|
||||
Attributes _origAttr;
|
||||
gidispatch_rock_t _inArrayRock;
|
||||
|
||||
glui32 _echoLineInput;
|
||||
glui32 *_lineTerminators;
|
||||
|
||||
/* style hints and settings */
|
||||
WindowStyle styles[style_NUMSTYLES];
|
||||
|
||||
/* for copy selection */
|
||||
glui32 *_copyBuf;
|
||||
int _copyPos;
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TextBufferWindow(Windows *windows, uint32 rock);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~TextBufferWindow();
|
||||
|
||||
/**
|
||||
* Rearranges the window
|
||||
*/
|
||||
virtual void rearrange(const Common::Rect &box) override;
|
||||
|
||||
/**
|
||||
* Get window split size within parent pair window
|
||||
*/
|
||||
virtual glui32 getSplit(glui32 size, bool vertical) const override;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
} // End of namespace Gargoyle
|
||||
|
||||
#endif
|
665
engines/gargoyle/window_text_grid.cpp
Normal file
665
engines/gargoyle/window_text_grid.cpp
Normal file
@ -0,0 +1,665 @@
|
||||
/* 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_text_grid.h"
|
||||
#include "gargoyle/conf.h"
|
||||
#include "gargoyle/gargoyle.h"
|
||||
|
||||
namespace Gargoyle {
|
||||
|
||||
TextGridWindow::TextGridWindow(Windows *windows, uint32 rock) : Window(windows, rock) {
|
||||
_type = wintype_TextGrid;
|
||||
_width = _height = 0;
|
||||
_curX = _curY = 0;
|
||||
_inBuf = nullptr;
|
||||
_inOrgX = _inOrgY = 0;
|
||||
_inMax = 0;
|
||||
_inCurs = _inLen = 0;
|
||||
_inArrayRock.num = 0;
|
||||
_lineTerminators = nullptr;
|
||||
|
||||
Common::copy(&g_conf->_gStyles[0], &g_conf->_gStyles[style_NUMSTYLES], styles);
|
||||
}
|
||||
|
||||
TextGridWindow::~TextGridWindow() {
|
||||
if (_inBuf) {
|
||||
if (g_vm->gli_unregister_arr)
|
||||
(*g_vm->gli_unregister_arr)(_inBuf, _inMax, "&+#!Cn", _inArrayRock);
|
||||
_inBuf = nullptr;
|
||||
}
|
||||
|
||||
delete[] _lineTerminators;
|
||||
}
|
||||
|
||||
void TextGridWindow::rearrange(const Common::Rect &box) {
|
||||
Window::rearrange(box);
|
||||
int newwid, newhgt;
|
||||
|
||||
newwid = box.width() / g_conf->_cellW;
|
||||
newhgt = box.height() / g_conf->_cellH;
|
||||
|
||||
if (newwid == _width && newhgt == _height)
|
||||
return;
|
||||
|
||||
_lines.resize(newhgt);
|
||||
for (int y = 0; y < newhgt; ++y) {
|
||||
_lines[y].resize(newwid);
|
||||
touch(y);
|
||||
}
|
||||
|
||||
_attr.clear();
|
||||
_width = newwid;
|
||||
_height = newhgt;
|
||||
}
|
||||
|
||||
void TextGridWindow::touch(int line) {
|
||||
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));
|
||||
}
|
||||
|
||||
glui32 TextGridWindow::getSplit(glui32 size, bool vertical) const {
|
||||
return vertical ? size * g_conf->_cellW + g_conf->_tMarginX * 2 :
|
||||
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;
|
||||
int inmax;
|
||||
int unicode = _lineRequestUni;
|
||||
gidispatch_rock_t inarrayrock;
|
||||
TextGridRow *ln = &_lines[_inOrgY];
|
||||
Event dummyEv;
|
||||
|
||||
if (!ev)
|
||||
ev = &dummyEv;
|
||||
|
||||
g_vm->_events->clearEvent(ev);
|
||||
|
||||
if (!_lineRequest && !_lineRequestUni)
|
||||
return;
|
||||
|
||||
|
||||
inbuf = _inBuf;
|
||||
inmax = _inMax;
|
||||
inarrayrock = _inArrayRock;
|
||||
|
||||
if (!unicode) {
|
||||
for (ix = 0; ix<_inLen; ix++)
|
||||
{
|
||||
glui32 ch = ln->_chars[_inOrgX + ix];
|
||||
if (ch > 0xff)
|
||||
ch = '?';
|
||||
((char *)inbuf)[ix] = (char)ch;
|
||||
}
|
||||
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;
|
||||
|
||||
ev->_type = evtype_LineInput;
|
||||
ev->_window = this;
|
||||
ev->_val1 = _inLen;
|
||||
ev->_val2 = 0;
|
||||
|
||||
_lineRequest = false;
|
||||
_lineRequestUni = false;
|
||||
|
||||
if (_lineTerminators) {
|
||||
free(_lineTerminators);
|
||||
_lineTerminators = nullptr;
|
||||
}
|
||||
|
||||
_inBuf = nullptr;
|
||||
_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::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();
|
||||
_attrs.clear();
|
||||
_chars.resize(newSize);
|
||||
_attrs.resize(newSize);
|
||||
Common::fill(&_chars[0], &_chars[0] + newSize, ' ');
|
||||
}
|
||||
|
||||
} // End of namespace Gargoyle
|
180
engines/gargoyle/window_text_grid.h
Normal file
180
engines/gargoyle/window_text_grid.h
Normal file
@ -0,0 +1,180 @@
|
||||
/* 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_TEXT_GRID_H
|
||||
#define GARGOYLE_WINDOW_TEXT_GRID_H
|
||||
|
||||
#include "gargoyle/windows.h"
|
||||
|
||||
namespace Gargoyle {
|
||||
|
||||
/**
|
||||
* Text Grid window
|
||||
*/
|
||||
class TextGridWindow : public Window {
|
||||
/**
|
||||
* Structure for a row within the grid window
|
||||
*/
|
||||
struct TextGridRow {
|
||||
Common::Array<uint32> _chars;
|
||||
Common::Array<Attributes> _attrs;
|
||||
bool dirty;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TextGridRow() : dirty(false) {}
|
||||
|
||||
/**
|
||||
* Resize the row
|
||||
*/
|
||||
void resize(size_t newSize);
|
||||
};
|
||||
typedef Common::Array<TextGridRow> TextGridRows;
|
||||
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
|
||||
void *_inBuf; ///< unsigned char* for latin1, glui32* for unicode
|
||||
int _inOrgX, _inOrgY;
|
||||
int _inMax;
|
||||
int _inCurs, _inLen;
|
||||
Attributes _origAttr;
|
||||
gidispatch_rock_t _inArrayRock;
|
||||
glui32 *_lineTerminators;
|
||||
|
||||
WindowStyle styles[style_NUMSTYLES]; ///< style hints and settings
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TextGridWindow(Windows *windows, uint32 rock);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~TextGridWindow();
|
||||
|
||||
/**
|
||||
* Rearranges the window
|
||||
*/
|
||||
virtual void rearrange(const Common::Rect &box) override;
|
||||
|
||||
/**
|
||||
* Get window split size within parent pair window
|
||||
*/
|
||||
virtual glui32 getSplit(glui32 size, bool vertical) const override;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
} // End of namespace Gargoyle
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,6 @@
|
||||
#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"
|
||||
|
||||
@ -43,6 +42,8 @@ class PairWindow;
|
||||
#define HISTORYLEN 100
|
||||
#define SCROLLBACK 512
|
||||
#define TBLINELEN 300
|
||||
#define GLI_SUBPIX 8
|
||||
|
||||
|
||||
/**
|
||||
* Main windows manager
|
||||
@ -256,7 +257,6 @@ struct Attributes {
|
||||
class Window : public Draw {
|
||||
public:
|
||||
Windows *_windows;
|
||||
glui32 _magicnum;
|
||||
glui32 _rock;
|
||||
glui32 _type;
|
||||
|
||||
@ -393,409 +393,6 @@ public:
|
||||
BlankWindow(Windows *windows, uint32 rock);
|
||||
};
|
||||
|
||||
/**
|
||||
* Text Grid window
|
||||
*/
|
||||
class TextGridWindow : public Window {
|
||||
/**
|
||||
* Structure for a row within the grid window
|
||||
*/
|
||||
struct TextGridRow {
|
||||
Common::Array<uint32> _chars;
|
||||
Common::Array<Attributes> _attrs;
|
||||
bool dirty;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TextGridRow() : dirty(false) {}
|
||||
|
||||
/**
|
||||
* Resize the row
|
||||
*/
|
||||
void resize(size_t newSize);
|
||||
};
|
||||
typedef Common::Array<TextGridRow> TextGridRows;
|
||||
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
|
||||
void *_inBuf; ///< unsigned char* for latin1, glui32* for unicode
|
||||
int _inOrgX, _inOrgY;
|
||||
int _inMax;
|
||||
int _inCurs, _inLen;
|
||||
Attributes _origAttr;
|
||||
gidispatch_rock_t _inArrayRock;
|
||||
glui32 *_lineTerminators;
|
||||
|
||||
WindowStyle styles[style_NUMSTYLES]; ///< style hints and settings
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TextGridWindow(Windows *windows, uint32 rock);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~TextGridWindow();
|
||||
|
||||
/**
|
||||
* Rearranges the window
|
||||
*/
|
||||
virtual void rearrange(const Common::Rect &box) override;
|
||||
|
||||
/**
|
||||
* Get window split size within parent pair window
|
||||
*/
|
||||
virtual glui32 getSplit(glui32 size, bool vertical) const override;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Text Buffer window
|
||||
*/
|
||||
class TextBufferWindow : public Window {
|
||||
/**
|
||||
* Structure for a row within the window
|
||||
*/
|
||||
struct TextBufferRow {
|
||||
Common::Array<uint32> chars;
|
||||
Common::Array<Attributes> attr;
|
||||
int len, newline;
|
||||
bool dirty, repaint;
|
||||
Picture *lpic, *rpic;
|
||||
glui32 lhyper, rhyper;
|
||||
int lm, rm;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TextBufferRow();
|
||||
|
||||
/**
|
||||
* Resize the row
|
||||
*/
|
||||
void resize(size_t newSize);
|
||||
};
|
||||
typedef Common::Array<TextBufferRow> TextBufferRows;
|
||||
private:
|
||||
void reflow();
|
||||
void touchScroll();
|
||||
bool putPicture(Picture *pic, glui32 align, glui32 linkval);
|
||||
void putTextUni(const glui32 *buf, int len, int pos, int oldlen);
|
||||
void flowBreak();
|
||||
|
||||
/**
|
||||
* Mark a given text row as modified
|
||||
*/
|
||||
void touch(int line);
|
||||
public:
|
||||
int _width, _height;
|
||||
int _spaced;
|
||||
int _dashed;
|
||||
|
||||
TextBufferRows _lines;
|
||||
int _scrollBack;
|
||||
|
||||
int _numChars; ///< number of chars in last line: lines[0]
|
||||
glui32 *_chars; ///< alias to lines[0].chars
|
||||
Attributes *_attrs; ///< alias to lines[0].attrs
|
||||
|
||||
///< adjust margins temporarily for images
|
||||
int _ladjw;
|
||||
int _ladjn;
|
||||
int _radjw;
|
||||
int _radjn;
|
||||
|
||||
/* Command history. */
|
||||
glui32 *_history[HISTORYLEN];
|
||||
int _historyPos;
|
||||
int _historyFirst, _historyPresent;
|
||||
|
||||
/* for paging */
|
||||
int _lastSeen;
|
||||
int _scrollPos;
|
||||
int _scrollMax;
|
||||
|
||||
/* for line input */
|
||||
void *_inBuf; ///< unsigned char* for latin1, glui32* for unicode
|
||||
int _inMax;
|
||||
long _inFence;
|
||||
long _inCurs;
|
||||
Attributes _origAttr;
|
||||
gidispatch_rock_t _inArrayRock;
|
||||
|
||||
glui32 _echoLineInput;
|
||||
glui32 *_lineTerminators;
|
||||
|
||||
/* style hints and settings */
|
||||
WindowStyle styles[style_NUMSTYLES];
|
||||
|
||||
/* for copy selection */
|
||||
glui32 *_copyBuf;
|
||||
int _copyPos;
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TextBufferWindow(Windows *windows, uint32 rock);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~TextBufferWindow();
|
||||
|
||||
/**
|
||||
* Rearranges the window
|
||||
*/
|
||||
virtual void rearrange(const Common::Rect &box) override;
|
||||
|
||||
/**
|
||||
* Get window split size within parent pair window
|
||||
*/
|
||||
virtual glui32 getSplit(glui32 size, bool vertical) const override;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Graphics window
|
||||
*/
|
||||
class GraphicsWindow : public Window {
|
||||
private:
|
||||
void touch();
|
||||
public:
|
||||
unsigned char _bgnd[3];
|
||||
bool _dirty;
|
||||
glui32 _w, _h;
|
||||
Graphics::ManagedSurface *_surface;
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
GraphicsWindow(Windows *windows, uint32 rock);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~GraphicsWindow();
|
||||
|
||||
/**
|
||||
* Rearranges the window
|
||||
*/
|
||||
virtual void rearrange(const Common::Rect &box) override;
|
||||
|
||||
/**
|
||||
* Get window split size within parent pair window
|
||||
*/
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pair window
|
||||
*/
|
||||
class PairWindow : public Window {
|
||||
public:
|
||||
Window *_child1, *_child2;
|
||||
|
||||
/* split info... */
|
||||
glui32 _dir; ///< winmethod_Left, Right, Above, or Below
|
||||
bool _vertical, _backward; ///< flags
|
||||
glui32 _division; ///< winmethod_Fixed or winmethod_Proportional
|
||||
Window *_key; ///< NULL or a leaf-descendant (not a Pair)
|
||||
int _keyDamage; ///< used as scratch space in window closing
|
||||
glui32 _size; ///< size value
|
||||
glui32 _wBorder; ///< winMethod_Border, NoBorder
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
PairWindow(Windows *windows, glui32 method, Window *key, glui32 size);
|
||||
|
||||
/**
|
||||
* Rearranges the window
|
||||
*/
|
||||
virtual void rearrange(const Common::Rect &box) override;
|
||||
|
||||
/**
|
||||
* Redraw the window
|
||||
*/
|
||||
virtual void redraw() override;
|
||||
};
|
||||
|
||||
} // End of namespace Gargoyle
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user