GLK: Logic for keypress event handling

This commit is contained in:
Paul Gilbert 2018-10-27 18:44:32 -07:00 committed by Paul Gilbert
parent 7bbedcd099
commit 9eb4debd15
11 changed files with 324 additions and 17 deletions

View File

@ -0,0 +1,39 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software{} you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation{} either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY{} without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program{} if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "gargoyle/clipboard.h"
namespace Gargoyle {
void Clipboard::store(const uint32 *text, size_t len) {
// TODO
}
void Clipboard::send() {
// TODO
}
void Clipboard::receive() {
// TODO
}
} // End of namespace Gargoyle

View File

@ -0,0 +1,43 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef GARGOYLE_CLIPBOARD_H
#define GARGOYLE_CLIPBOARD_H
#include "common/array.h"
namespace Gargoyle {
class Clipboard {
private:
Common::Array<uint32> _text;
public:
void store(const uint32 *text, size_t len);
void send();
void receive();
};
} // End of namespace Gargoyle
#endif

View File

@ -21,11 +21,35 @@
*/
#include "gargoyle/events.h"
#include "gargoyle/clipboard.h"
#include "gargoyle/gargoyle.h"
#include "gargoyle/windows.h"
namespace Gargoyle {
void Events::getEvent(event_t *event, bool polled) {
// TODO
_currentEvent = event;
event->clear();
Common::Event ev;
dispatchEvent(*_currentEvent, polled);
if (!polled) {
while (!g_vm->shouldQuit() && _currentEvent->type == evtype_None && !_timeouts) {
pollEvents();
g_system->delayMillis(10);
dispatchEvent(*_currentEvent, polled);
}
}
if (_currentEvent->type == evtype_None && _timeouts) {
store(evtype_Timer, NULL, 0, 0);
dispatchEvent(*_currentEvent, polled);
_timeouts = false;
}
_currentEvent = nullptr;
}
void Events::store(EvType type, Window *win, uint32 val1, uint32 val2) {
@ -60,4 +84,76 @@ void Events::dispatchEvent(Event &ev, bool polled) {
ev = dispatch;
}
void Events::pollEvents() {
Common::Event event;
do {
g_system->getEventManager()->pollEvent(event);
switch (event.type) {
case Common::EVENT_KEYDOWN:
handleKeyDown(event.kbd);
return;
default:
break;
}
} while (event.type == Common::EVENT_MOUSEMOVE);
}
void Events::handleKeyDown(const Common::KeyState &ks) {
Clipboard &clipboard = *g_vm->_clipboard;
Windows &windows = *g_vm->_windows;
if (ks.flags & Common::KBD_CTRL) {
if (ks.keycode == Common::KEYCODE_a)
windows.inputHandleKey(keycode_Home);
else if (ks.keycode == Common::KEYCODE_c)
clipboard.send();
else if (ks.keycode == Common::KEYCODE_e)
windows.inputHandleKey(keycode_End);
else if (ks.keycode == Common::KEYCODE_u)
windows.inputHandleKey(keycode_Escape);
else if (ks.keycode == Common::KEYCODE_v)
clipboard.receive();
else if (ks.keycode == Common::KEYCODE_x)
clipboard.send();
else if (ks.keycode == Common::KEYCODE_LEFT || ks.keycode == Common::KEYCODE_KP4)
windows.inputHandleKey(keycode_SkipWordLeft);
else if (ks.keycode == Common::KEYCODE_RIGHT || ks.keycode == Common::KEYCODE_KP6)
windows.inputHandleKey(keycode_SkipWordRight);
return;
}
if (ks.flags & Common::KBD_ALT)
return;
if (ks.keycode == Common::KEYCODE_RETURN) windows.inputHandleKey(keycode_Return);
else if (ks.keycode == Common::KEYCODE_BACKSPACE) windows.inputHandleKey(keycode_Delete);
else if (ks.keycode == Common::KEYCODE_DELETE) windows.inputHandleKey(keycode_Erase);
else if (ks.keycode == Common::KEYCODE_TAB) windows.inputHandleKey(keycode_Tab);
else if (ks.keycode == Common::KEYCODE_UP) windows.inputHandleKey(keycode_PageUp);
else if (ks.keycode == Common::KEYCODE_PAGEDOWN) windows.inputHandleKey(keycode_PageDown);
else if (ks.keycode == Common::KEYCODE_HOME) windows.inputHandleKey(keycode_Home);
else if (ks.keycode == Common::KEYCODE_END) windows.inputHandleKey(keycode_End);
else if (ks.keycode == Common::KEYCODE_LEFT) windows.inputHandleKey(keycode_Left);
else if (ks.keycode == Common::KEYCODE_RIGHT) windows.inputHandleKey(keycode_Right);
else if (ks.keycode == Common::KEYCODE_UP) windows.inputHandleKey(keycode_Up);
else if (ks.keycode == Common::KEYCODE_DOWN) windows.inputHandleKey(keycode_Down);
else if (ks.keycode == Common::KEYCODE_ESCAPE) windows.inputHandleKey(keycode_Escape);
else if (ks.keycode == Common::KEYCODE_F1) windows.inputHandleKey(keycode_Func1);
else if (ks.keycode == Common::KEYCODE_F2) windows.inputHandleKey(keycode_Func2);
else if (ks.keycode == Common::KEYCODE_F3) windows.inputHandleKey(keycode_Func3);
else if (ks.keycode == Common::KEYCODE_F4) windows.inputHandleKey(keycode_Func4);
else if (ks.keycode == Common::KEYCODE_F5) windows.inputHandleKey(keycode_Func5);
else if (ks.keycode == Common::KEYCODE_F6) windows.inputHandleKey(keycode_Func6);
else if (ks.keycode == Common::KEYCODE_F7) windows.inputHandleKey(keycode_Func7);
else if (ks.keycode == Common::KEYCODE_F8) windows.inputHandleKey(keycode_Func8);
else if (ks.keycode == Common::KEYCODE_F9) windows.inputHandleKey(keycode_Func9);
else if (ks.keycode == Common::KEYCODE_F10) windows.inputHandleKey(keycode_Func10);
else if (ks.keycode == Common::KEYCODE_F11) windows.inputHandleKey(keycode_Func11);
else if (ks.keycode == Common::KEYCODE_F12) windows.inputHandleKey(keycode_Func12);
else windows.inputHandleKey(ks.ascii);
}
} // End of namespace Gargoyle

View File

@ -138,19 +138,37 @@ public:
}
};
/**
* Events manager
*/
class Events {
private:
EventQueue _eventsPolled;
EventQueue _eventsLogged;
EventQueue _eventsPolled; ///< User generated events
EventQueue _eventsLogged; ///< Custom events generated by game code
Event *_currentEvent; ///< Event pointer passed during event retrieval
bool _timeouts; ///< Timer timeouts flag
private:
/**
* Dispatches an event
*/
void dispatchEvent(Event &ev, bool polled);
/**
* Poll for user events
*/
void pollEvents();
/**
* Handle a key down event
*/
void handleKeyDown(const Common::KeyState &ks);
public:
bool _forceClick;
public:
/**
* Constructor
*/
Events() : _forceClick(false) {}
Events() : _forceClick(false), _currentEvent(nullptr), _timeouts(false) {}
/**
* Get any pending event

View File

@ -29,6 +29,7 @@
#include "graphics/scaler.h"
#include "graphics/thumbnail.h"
#include "gargoyle/gargoyle.h"
#include "gargoyle/clipboard.h"
#include "gargoyle/conf.h"
#include "gargoyle/events.h"
#include "gargoyle/picture.h"
@ -42,14 +43,15 @@ namespace Gargoyle {
GargoyleEngine *g_vm;
GargoyleEngine::GargoyleEngine(OSystem *syst, const GargoyleGameDescription *gameDesc) :
_gameDescription(gameDesc), Engine(syst), _random("Gargoyle"), _conf(nullptr),
_events(nullptr), _picList(nullptr), _screen(nullptr), _windows(nullptr),
_windowMask(nullptr), _copySelect(false),
_gameDescription(gameDesc), Engine(syst), _random("Gargoyle"), _clipboard(nullptr),
_conf(nullptr), _events(nullptr), _picList(nullptr), _screen(nullptr), _windows(nullptr),
_windowMask(nullptr), _copySelect(false), _terminated(false),
gli_unregister_obj(nullptr), gli_register_arr(nullptr), gli_unregister_arr(nullptr) {
g_vm = this;
}
GargoyleEngine::~GargoyleEngine() {
delete _clipboard;
delete _conf;
delete _events;
delete _picList;
@ -68,6 +70,7 @@ void GargoyleEngine::initialize() {
initGraphics(640, 480, false);
_screen = new Screen();
_clipboard = new Clipboard();
_conf = new Conf();
_events = new Events();
_picList = new PicList();

View File

@ -33,6 +33,7 @@
namespace Gargoyle {
class Clipboard;
class Conf;
class Events;
class PicList;
@ -93,6 +94,7 @@ protected:
*/
virtual void runGame(Common::SeekableReadStream *gameFile) = 0;
public:
Clipboard *_clipboard;
Conf *_conf;
Events *_events;
PicList *_picList;
@ -101,6 +103,7 @@ public:
Windows *_windows;
WindowMask *_windowMask;
bool _copySelect;
bool _terminated;
void (*gli_unregister_obj)(void *obj, glui32 objclass, gidispatch_rock_t objrock);
gidispatch_rock_t (*gli_register_arr)(void *array, glui32 len, const char *typecode);
void (*gli_unregister_arr)(void *array, glui32 len, const char *typecode, gidispatch_rock_t objrock);

View File

@ -1,6 +1,7 @@
MODULE := engines/gargoyle
MODULE_OBJS := \
clipboard.o \
conf.o \
detection.o \
events.o \

View File

@ -21,6 +21,7 @@
*/
#include "gargoyle/window_text_buffer.h"
#include "gargoyle/clipboard.h"
#include "gargoyle/conf.h"
#include "gargoyle/gargoyle.h"
#include "gargoyle/screen.h"
@ -1155,7 +1156,7 @@ void TextBufferWindow::redraw() {
if (selbuf && _copyPos) {
Windows::_claimSelect = true;
copyTextToClipboard(_copyBuf, _copyPos);
g_vm->_clipboard->store(_copyBuf, _copyPos);
for (i = 0; i < _copyPos; i++)
_copyBuf[i] = 0;
_copyPos = 0;
@ -1623,10 +1624,6 @@ int TextBufferWindow::calcWidth(glui32 *chars, Attributes *attrs, int startchar,
return w;
}
void TextBufferWindow::copyTextToClipboard(const glui32 *text, size_t len) {
// TODO
}
void TextBufferWindow::getSize(glui32 *width, glui32 *height) const {
if (width)
*width = (_bbox.width() - g_conf->_tMarginX * 2) / g_conf->_cellW;

View File

@ -84,11 +84,6 @@ private:
void scrollOneLine(bool forced);
void scrollResize();
int calcWidth(glui32 *chars, Attributes *attrs, int startchar, int numchars, int spw);
/**
* Copy the passed text to the clipboard
*/
void copyTextToClipboard(const glui32 *text, size_t len);
public:
int _width, _height;
int _spaced;

View File

@ -294,6 +294,96 @@ void Windows::inputGuessFocus() {
}
}
void Windows::inputMoreFocus() {
Window *altWin = _focusWin;
do {
if (altWin && altWin->_moreRequest)
break;
altWin = iterateTreeOrder(altWin);
} while (altWin != _focusWin);
_focusWin = altWin;
}
void Windows::inputNextFocus() {
Window *altWin = _focusWin;
do
{
altWin = iterateTreeOrder(altWin);
if (altWin
&& (altWin->_lineRequest || altWin->_charRequest ||
altWin->_lineRequestUni || altWin->_charRequestUni))
break;
} while (altWin != _focusWin);
if (_focusWin != altWin) {
_focusWin = altWin;
_forceRedraw = true;
redraw();
}
}
void Windows::inputScrollFocus() {
Window *altWin = _focusWin;
do {
if (altWin && altWin->_scrollRequest)
break;
altWin = iterateTreeOrder(altWin);
} while (altWin != _focusWin);
_focusWin = altWin;
}
void Windows::inputHandleKey(glui32 key) {
if (_moreFocus) {
inputMoreFocus();
} else {
switch (key) {
case keycode_Tab:
inputNextFocus();
return;
case keycode_PageUp:
case keycode_PageDown:
case keycode_MouseWheelUp:
case keycode_MouseWheelDown:
inputScrollFocus();
break;
default:
inputGuessFocus();
break;
}
}
Window *win = _focusWin;
if (!win)
return;
bool deferExit = false;
TextGridWindow *gridWindow = dynamic_cast<TextGridWindow *>(win);
TextBufferWindow *bufWindow = dynamic_cast<TextBufferWindow *>(win);
if (gridWindow) {
if (gridWindow->_charRequest || gridWindow->_charRequestUni)
gridWindow->acceptReadChar(key);
else if (gridWindow->_lineRequest || gridWindow->_lineRequestUni)
gridWindow->acceptReadLine(key);
} else if (bufWindow) {
if (bufWindow->_charRequest || bufWindow->_charRequestUni)
bufWindow->acceptReadChar(key);
else if (bufWindow->_lineRequest || bufWindow->_lineRequestUni)
bufWindow->acceptReadLine(key);
else if (bufWindow->_moreRequest || bufWindow->_scrollRequest)
deferExit = bufWindow->acceptScroll(key);
}
if (!deferExit && g_vm->_terminated)
g_vm->quitGame();
}
void Windows::selectionChanged() {
_claimSelect = false;
_forceRedraw = true;

View File

@ -101,6 +101,23 @@ private:
void refocus(Window *win);
Window *iterateTreeOrder(Window *win);
/**
* Pick first window which has a more request
*/
void inputMoreFocus();
/**
*
*/
void inputNextFocus();
/**
* Pick first window which might want scrolling.
* This is called after pressing page keys.
*/
void inputScrollFocus();
public:
static bool _overrideReverse;
static bool _overrideFgSet;
@ -154,6 +171,11 @@ public:
*/
void inputGuessFocus();
/**
* Handle input keypress
*/
void inputHandleKey(glui32 key);
void selectionChanged();
void clearClaimSelect() { _claimSelect = false; }