diff options
author | Stephen Kennedy | 2008-07-30 13:47:54 +0000 |
---|---|---|
committer | Stephen Kennedy | 2008-07-30 13:47:54 +0000 |
commit | e2a2a672f591f36fb596bb6cb849978c70611c3e (patch) | |
tree | 73cc81ea173bdb4a35cfe437bb115e38f405f1d7 | |
parent | a051061e38bfcbd7cfac81deb3acf69f154dc681 (diff) | |
download | scummvm-rg350-e2a2a672f591f36fb596bb6cb849978c70611c3e.tar.gz scummvm-rg350-e2a2a672f591f36fb596bb6cb849978c70611c3e.tar.bz2 scummvm-rg350-e2a2a672f591f36fb596bb6cb849978c70611c3e.zip |
- major re-factoring of VK - all GUI-related code has been abstracted to VirtualKeyboardGUI class
- fixed bug with parsing modifiers in VirtualKeyboardParser
- fixed numerous GCC warnings
svn-id: r33448
-rw-r--r-- | backends/common/hardware-key.h | 27 | ||||
-rw-r--r-- | backends/common/keymap-manager.cpp | 27 | ||||
-rw-r--r-- | backends/common/keymap-manager.h | 27 | ||||
-rw-r--r-- | backends/common/keymap.cpp | 27 | ||||
-rw-r--r-- | backends/common/keymap.h | 27 | ||||
-rw-r--r-- | backends/common/keymapper.cpp | 25 | ||||
-rw-r--r-- | backends/common/keymapper.h | 27 | ||||
-rw-r--r-- | backends/common/user-action.cpp | 27 | ||||
-rw-r--r-- | backends/common/user-action.h | 27 | ||||
-rw-r--r-- | backends/common/virtual-keyboard-gui.cpp | 261 | ||||
-rw-r--r-- | backends/common/virtual-keyboard-gui.h | 89 | ||||
-rw-r--r-- | backends/common/virtual-keyboard-parser.cpp | 51 | ||||
-rw-r--r-- | backends/common/virtual-keyboard.cpp | 314 | ||||
-rw-r--r-- | backends/common/virtual-keyboard.h | 78 | ||||
-rw-r--r-- | backends/module.mk | 1 | ||||
-rw-r--r-- | dists/msvc8/scummvm.vcproj | 8 | ||||
-rw-r--r-- | graphics/surface-keycolored.cpp | 2 | ||||
-rw-r--r-- | graphics/surface-keycolored.h | 2 |
18 files changed, 738 insertions, 309 deletions
diff --git a/backends/common/hardware-key.h b/backends/common/hardware-key.h index f6253c0b96..2059ff6a34 100644 --- a/backends/common/hardware-key.h +++ b/backends/common/hardware-key.h @@ -1,3 +1,28 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + #ifndef COMMON_HARDWAREKEY #define COMMON_HARDWAREKEY @@ -92,4 +117,4 @@ private: } // end of namespace Common -#endif
\ No newline at end of file +#endif diff --git a/backends/common/keymap-manager.cpp b/backends/common/keymap-manager.cpp index 9386dc5b5e..77712f331a 100644 --- a/backends/common/keymap-manager.cpp +++ b/backends/common/keymap-manager.cpp @@ -1,3 +1,28 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + #include "backends/common/keymap-manager.h" namespace Common { @@ -157,4 +182,4 @@ Keymap *KeymapManager::getKeymap(const String& name) { return keymap; } -} // end of namespace Common
\ No newline at end of file +} // end of namespace Common diff --git a/backends/common/keymap-manager.h b/backends/common/keymap-manager.h index bc93400f3b..cc126c3284 100644 --- a/backends/common/keymap-manager.h +++ b/backends/common/keymap-manager.h @@ -1,3 +1,28 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + #ifndef COMMON_KEYMAP_MANAGER #define COMMON_KEYMAP_MANAGER @@ -61,4 +86,4 @@ private: } // end of namespace Common -#endif
\ No newline at end of file +#endif diff --git a/backends/common/keymap.cpp b/backends/common/keymap.cpp index 639b03f78f..509f50e4eb 100644 --- a/backends/common/keymap.cpp +++ b/backends/common/keymap.cpp @@ -1,3 +1,28 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + #include "backends/common/keymap.h" #include "backends/common/hardware-key.h" @@ -71,4 +96,4 @@ UserAction *Keymap::getMappedAction(const KeyState& ks) const { return it->_value; } -} // end of namespace Common
\ No newline at end of file +} // end of namespace Common diff --git a/backends/common/keymap.h b/backends/common/keymap.h index d9bc8f08df..eb7b227e52 100644 --- a/backends/common/keymap.h +++ b/backends/common/keymap.h @@ -1,3 +1,28 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + #ifndef COMMON_KEYMAP #define COMMON_KEYMAP @@ -86,4 +111,4 @@ private: } // end of namespace Common -#endif
\ No newline at end of file +#endif diff --git a/backends/common/keymapper.cpp b/backends/common/keymapper.cpp index d7d6b047aa..1d06a6dbd7 100644 --- a/backends/common/keymapper.cpp +++ b/backends/common/keymapper.cpp @@ -1,3 +1,28 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + #include "backends/common/keymapper.h" #include "backends/common/keymap-manager.h" #include "common/config-manager.h" diff --git a/backends/common/keymapper.h b/backends/common/keymapper.h index bbdd0eaca6..8d3e421625 100644 --- a/backends/common/keymapper.h +++ b/backends/common/keymapper.h @@ -1,3 +1,28 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + #ifndef COMMON_KEYMAPPER #define COMMON_KEYMAPPER @@ -91,4 +116,4 @@ private: } // end of namespace Common -#endif
\ No newline at end of file +#endif diff --git a/backends/common/user-action.cpp b/backends/common/user-action.cpp index f6b24339e9..588d5dd45b 100644 --- a/backends/common/user-action.cpp +++ b/backends/common/user-action.cpp @@ -1,3 +1,28 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + #include "backends/common/user-action.h" #include "backends/common/keymap.h" @@ -30,4 +55,4 @@ const HardwareKey *UserAction::getMappedKey() const { return _hwKey; } -} // end of namespace Common
\ No newline at end of file +} // end of namespace Common diff --git a/backends/common/user-action.h b/backends/common/user-action.h index 2e7c73334b..3fd7f7ae0a 100644 --- a/backends/common/user-action.h +++ b/backends/common/user-action.h @@ -1,3 +1,28 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + #ifndef COMMON_USERACTION #define COMMON_USERACTION @@ -70,4 +95,4 @@ public: } // end of namespace Common -#endif
\ No newline at end of file +#endif diff --git a/backends/common/virtual-keyboard-gui.cpp b/backends/common/virtual-keyboard-gui.cpp new file mode 100644 index 0000000000..f07ea1a4c9 --- /dev/null +++ b/backends/common/virtual-keyboard-gui.cpp @@ -0,0 +1,261 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + +#include "backends/common/virtual-keyboard-gui.h" +#include "backends/common/virtual-keyboard.h" +#include "graphics/cursorman.h" +#include "graphics/surface-keycolored.h" +#include "gui/newgui.h" + +namespace Common { + +VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd) { + _kbd = kbd; + + assert(g_system); + _system = g_system; + + _lastScreenChanged = _system->getScreenChangeID(); + + memset(_cursor, 0xFF, sizeof(_cursor)); + + _displaying = _needRedraw = _drag = false; + _firstRun = true; +} + +void VirtualKeyboardGUI::setKeyboardSurface(Graphics::Surface *sur, OverlayColor trans_color) { + _kbdSurface = sur; + _kbdTransparentColor = trans_color; + _kbdBound.setWidth(_kbdSurface->w); + _kbdBound.setHeight(_kbdSurface->h); + _needRedraw = true; +} + +void VirtualKeyboardGUI::run() { + + if (_lastScreenChanged != _system->getScreenChangeID()) + screenChanged(); + + // TODO: set default position if position is somehow invalid + if (_firstRun) { + _firstRun = false; + setDefaultPosition(); + } + + if (!g_gui.isActive()) { + _system->showOverlay(); + _system->clearOverlay(); + } + _overlayBackup.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor)); + _system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w); + setupCursor(); + + _displaying = true; + mainLoop(); + + removeCursor(); + _system->copyRectToOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w, 0, 0, _overlayBackup.w, _overlayBackup.h); + if (!g_gui.isActive()) _system->hideOverlay(); + _overlayBackup.free(); +} + +void VirtualKeyboardGUI::hide() { + _displaying = false; +} + +void VirtualKeyboardGUI::reset() { + _kbdBound.left = _kbdBound.top + = _kbdBound.right = _kbdBound.bottom = 0; + _displaying = _drag = false; + _firstRun = true; + _lastScreenChanged = _system->getScreenChangeID(); + _kbdSurface = 0; +} + +void VirtualKeyboardGUI::setDefaultPosition() +{ + int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight(); + int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height(); + int16 posX = 0, posY = 0; + if (scrW != kbdW) { + switch (_kbd->_hAlignment) { + case VirtualKeyboard::kAlignLeft: + posX = 0; + break; + case VirtualKeyboard::kAlignCentre: + posX = (scrW - kbdW) / 2; + break; + case VirtualKeyboard::kAlignRight: + posX = scrW - kbdW; + break; + } + } + if (scrH != kbdH) { + switch (_kbd->_vAlignment) { + case VirtualKeyboard::kAlignTop: + posY = 0; + break; + case VirtualKeyboard::kAlignMiddle: + posY = (scrH - kbdH) / 2; + break; + case VirtualKeyboard::kAlignBottom: + posY = scrH - kbdH; + break; + } + } + _kbdBound.moveTo(posX, posY); +} + +void VirtualKeyboardGUI::move(int16 x, int16 y) { + // snap to edge of screen + if (ABS(x) < SNAP_WIDTH) + x = 0; + int16 x2 = _system->getOverlayWidth() - _kbdBound.width(); + if (ABS(x - x2) < SNAP_WIDTH) + x = x2; + if (ABS(y) < SNAP_WIDTH) + y = 0; + int16 y2 = _system->getOverlayHeight() - _kbdBound.height(); + if (ABS(y - y2) < SNAP_WIDTH) + y = y2; + + _kbdBound.moveTo(x, y); +} + +void VirtualKeyboardGUI::screenChanged() { + _lastScreenChanged = _system->getScreenChangeID(); + if (!_kbd->checkModeResolutions()) + _displaying = false; +} + + +void VirtualKeyboardGUI::mainLoop() { + Common::EventManager *eventMan = _system->getEventManager(); + + while (_displaying) { + if (_needRedraw) redraw(); + + animateCursor(); + _system->updateScreen(); + Common::Event event; + while (eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_LBUTTONDOWN: + if (_kbdBound.contains(event.mouse)) { + _kbd->handleMouseDown(event.mouse.x - _kbdBound.left, + event.mouse.y - _kbdBound.top); + } + break; + case Common::EVENT_LBUTTONUP: + if (_kbdBound.contains(event.mouse)) { + _kbd->handleMouseUp(event.mouse.x - _kbdBound.left, + event.mouse.y - _kbdBound.top); + } + break; + case Common::EVENT_MOUSEMOVE: + if (_drag) { + move(event.mouse.x - _dragPoint.x, + event.mouse.y - _dragPoint.y); + _needRedraw = true; + } + break; + case Common::EVENT_SCREEN_CHANGED: + screenChanged(); + break; + case Common::EVENT_QUIT: + _system->quit(); + return; + default: + break; + } + } + // Delay for a moment + _system->delayMillis(10); + } +} + +void VirtualKeyboardGUI::startDrag(int16 x, int16 y) { + _drag = true; + _dragPoint.x = x; + _dragPoint.y = y; +} + +void VirtualKeyboardGUI::endDrag() { + _drag = false; +} + + +void VirtualKeyboardGUI::redraw() { + Graphics::SurfaceKeyColored surf; + assert(_kbdSurface); + + surf.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor)); + + memcpy(surf.pixels, _overlayBackup.pixels, surf.w * surf.h * sizeof(OverlayColor)); + surf.blit(_kbdSurface, _kbdBound.left, _kbdBound.top, _kbdTransparentColor); + + _system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 0, 0, surf.w, surf.h); + + surf.free(); + + _needRedraw = false; +} + +void VirtualKeyboardGUI::setupCursor() { + const byte palette[] = { + 255, 255, 255, 0, + 255, 255, 255, 0, + 171, 171, 171, 0, + 87, 87, 87, 0 + }; + + CursorMan.pushCursorPalette(palette, 0, 4); + CursorMan.pushCursor(NULL, 0, 0, 0, 0); + CursorMan.showMouse(true); +} + +void VirtualKeyboardGUI::animateCursor() { + int time = _system->getMillis(); + if (time > _cursorAnimateTimer + kCursorAnimateDelay) { + for (int i = 0; i < 15; i++) { + if ((i < 6) || (i > 8)) { + _cursor[16 * 7 + i] = _cursorAnimateCounter; + _cursor[16 * i + 7] = _cursorAnimateCounter; + } + } + + CursorMan.replaceCursor(_cursor, 16, 16, 7, 7); + + _cursorAnimateTimer = time; + _cursorAnimateCounter = (_cursorAnimateCounter + 1) % 4; + } +} + +void VirtualKeyboardGUI::removeCursor() { + CursorMan.popCursor(); + CursorMan.popCursorPalette(); +} + +} // end of namespace Common diff --git a/backends/common/virtual-keyboard-gui.h b/backends/common/virtual-keyboard-gui.h new file mode 100644 index 0000000000..ce9937d567 --- /dev/null +++ b/backends/common/virtual-keyboard-gui.h @@ -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. +* +* $URL$ +* $Id$ +* +*/ + +#ifndef COMMON_VIRTUAL_KEYBOARD_GUI +#define COMMON_VIRTUAL_KEYBOARD_GUI + +#include "common/rect.h" +#include "common/system.h" +#include "graphics/surface.h" + +namespace Common { + +class VirtualKeyboard; + +class VirtualKeyboardGUI { + +public: + + VirtualKeyboardGUI(VirtualKeyboard *kbd); + void setKeyboardSurface(Graphics::Surface *sur, OverlayColor trans_color); + void run(); + void hide(); + bool isDisplaying() { return _displaying; } + void reset(); + void startDrag(int16 x, int16 y); + void endDrag(); + +private: + + OSystem *_system; + VirtualKeyboard *_kbd; + Graphics::Surface *_kbdSurface; + OverlayColor _kbdTransparentColor; + + static const int SNAP_WIDTH = 10; + + Graphics::Surface _overlayBackup; + + Rect _kbdBound; + + Point _dragPoint; + bool _drag; + + bool _displaying; + bool _firstRun; + bool _needRedraw; + int _lastScreenChanged; + + void setDefaultPosition(); + void move(int16 x, int16 y); + void screenChanged(); + void mainLoop(); + void redraw(); + + static const int kCursorAnimateDelay = 250; + int _cursorAnimateCounter; + int _cursorAnimateTimer; + byte _cursor[2048]; + void setupCursor(); + void removeCursor(); + void animateCursor(); + +}; + +} // end of namespace Common + +#endif diff --git a/backends/common/virtual-keyboard-parser.cpp b/backends/common/virtual-keyboard-parser.cpp index ed77bc215c..416c539acd 100644 --- a/backends/common/virtual-keyboard-parser.cpp +++ b/backends/common/virtual-keyboard-parser.cpp @@ -226,45 +226,53 @@ bool VirtualKeyboardParser::parserCallback_Event() { if (_mode->events.contains(name)) return parserError("Event '%s' has already been defined", name.c_str()); - VirtualKeyboard::Event evt; - evt.name = name; + VirtualKeyboard::Event *evt = new VirtualKeyboard::Event(); + evt->name = name; Common::String type = evtNode->values["type"]; if (type == "key") { - if (!evtNode->values.contains("code") || !evtNode->values.contains("ascii")) + if (!evtNode->values.contains("code") || !evtNode->values.contains("ascii")) { + delete evt; return parserError("Key event element must contain code and ascii attributes"); + } - evt.type = VirtualKeyboard::kEventKey; + evt->type = VirtualKeyboard::kEventKey; Common::KeyCode code = (Common::KeyCode)atoi(evtNode->values["code"].c_str()); uint16 ascii = atoi(evtNode->values["ascii"].c_str()); byte flags = 0; - if (evtNode->values.contains("flags")) - flags = parseFlags(evtNode->values["flags"]); + if (evtNode->values.contains("modifiers")) + flags = parseFlags(evtNode->values["modifiers"]); - evt.data = new Common::KeyState(code, ascii, flags); + evt->data = new Common::KeyState(code, ascii, flags); } else if (type == "modifier") { - if (!evtNode->values.contains("flags")) + if (!evtNode->values.contains("modifiers")) { + delete evt; return parserError("Key modifier element must contain modifier attributes"); + } - evt.type = VirtualKeyboard::kEventModifier; + evt->type = VirtualKeyboard::kEventModifier; byte *flags = new byte; - *(flags) = parseFlags(evtNode->values["flags"]); - evt.data = flags; + *(flags) = parseFlags(evtNode->values["modifiers"]); + evt->data = flags; } else if (type == "switch_mode") { - if (!evtNode->values.contains("mode")) + if (!evtNode->values.contains("mode")) { + delete evt; return parserError("Switch mode event element must contain mode attribute"); + } - evt.type = VirtualKeyboard::kEventSwitchMode; - evt.data = new Common::String(evtNode->values["mode"]); + evt->type = VirtualKeyboard::kEventSwitchMode; + evt->data = new Common::String(evtNode->values["mode"]); } else if (type == "close") { - evt.type = VirtualKeyboard::kEventClose; - evt.data = 0; - } else + evt->type = VirtualKeyboard::kEventClose; + evt->data = 0; + } else { + delete evt; return parserError("Event type '%s' not known", type.c_str()); + } _mode->events[name] = evt; @@ -355,15 +363,18 @@ bool VirtualKeyboardParser::parserCallback_Area() { } byte VirtualKeyboardParser::parseFlags(const String& flags) { + if (flags.empty()) + return 0; + Common::StringTokenizer tok(flags, ", "); byte val = 0; for (Common::String fl = tok.nextToken(); !fl.empty(); fl = tok.nextToken()) { if (fl == "ctrl" || fl == "control") - val &= Common::KBD_CTRL; + val |= Common::KBD_CTRL; else if (fl == "alt") - val &= Common::KBD_ALT; + val |= Common::KBD_ALT; else if (fl == "shift") - val &= Common::KBD_SHIFT; + val |= Common::KBD_SHIFT; } return val; } diff --git a/backends/common/virtual-keyboard.cpp b/backends/common/virtual-keyboard.cpp index e6ef87b946..45a0a47568 100644 --- a/backends/common/virtual-keyboard.cpp +++ b/backends/common/virtual-keyboard.cpp @@ -24,14 +24,9 @@ */ #include "backends/common/virtual-keyboard.h" +#include "backends/common/virtual-keyboard-gui.h" #include "backends/common/virtual-keyboard-parser.h" -#include "common/config-manager.h" -#include "common/events.h" -#include "common/unzip.h" -#include "graphics/cursorman.h" #include "graphics/imageman.h" -#include "graphics/surface-keycolored.h" -#include "gui/newgui.h" namespace Common { @@ -40,43 +35,37 @@ VirtualKeyboard::VirtualKeyboard() : _currentMode(0), _keyDown(0) { _system = g_system; _parser = new VirtualKeyboardParser(this); - _loaded = _displaying = _drag = false; - _lastScreenChanged = _system->getScreenChangeID(); - - memset(_cursor, 0xFF, sizeof(_cursor)); + _kbdGUI = new VirtualKeyboardGUI(this); + _loaded = false; } VirtualKeyboard::~VirtualKeyboard() { - // TODO: clean up event data pointers - deleteEventData(); + deleteEvents(); + delete _kbdGUI; delete _parser; } +void VirtualKeyboard::deleteEvents() { + ModeMap::iterator it_m; + EventMap::iterator it_e; + for (it_m = _modes.begin(); it_m != _modes.end(); it_m++) { + EventMap *evt = &(it_m->_value.events); + for (it_e = evt->begin(); it_e != evt->end(); it_e++) + delete it_e->_value; + } +} + void VirtualKeyboard::reset() { - // TODO: clean up event data pointers - deleteEventData(); + deleteEvents(); _modes.clear(); _initialMode = _currentMode = 0; - _kbdBound.left = _kbdBound.top - = _kbdBound.right = _kbdBound.bottom = 0; _hAlignment = kAlignCentre; _vAlignment = kAlignBottom; _keyQueue.clear(); _keyDown = 0; _keyFlags = 0; - _displaying = _drag = false; - _firstRun = true; - _lastScreenChanged = _system->getScreenChangeID(); -} - -void VirtualKeyboard::deleteEventData() { - ModeMap::iterator it_m; - EventMap::iterator it_e; - for (it_m = _modes.begin(); it_m != _modes.end(); it_m++) { - EventMap *evt = &(it_m->_value.events); - for (it_e = evt->begin(); it_e != evt->end(); it_e++) - delete it_e->_value.data; - } + _loaded = false; + _kbdGUI->reset(); } bool VirtualKeyboard::loadKeyboardPack(Common::String packName) { @@ -127,79 +116,25 @@ bool VirtualKeyboard::loadKeyboardPack(Common::String packName) { return _loaded; } -void VirtualKeyboard::setDefaultPosition() -{ - int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight(); - int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height(); - int16 posX = 0, posY = 0; - if (scrW != kbdW) { - switch (_hAlignment) { - case kAlignLeft: - posX = 0; - break; - case kAlignCentre: - posX = (scrW - kbdW) / 2; - break; - case kAlignRight: - posX = scrW - kbdW; - break; - } - } - if (scrH != kbdH) { - switch (_vAlignment) { - case kAlignTop: - posY = 0; - break; - case kAlignMiddle: - posY = (scrH - kbdH) / 2; - break; - case kAlignBottom: - posY = scrH - kbdH; - break; - } - } - _kbdBound.moveTo(posX, posY); -} - bool VirtualKeyboard::checkModeResolutions() { _parser->setParseMode(kParseCheckResolutions); _loaded = _parser->parse(); return _loaded; } - -void VirtualKeyboard::move(int16 x, int16 y) { - // snap to edge of screen - if (ABS(x) < SNAP_WIDTH) - x = 0; - int16 x2 = _system->getOverlayWidth() - _kbdBound.width(); - if (ABS(x - x2) < SNAP_WIDTH) - x = x2; - if (ABS(y) < SNAP_WIDTH) - y = 0; - int16 y2 = _system->getOverlayHeight() - _kbdBound.height(); - if (ABS(y - y2) < SNAP_WIDTH) - y = y2; - - _kbdBound.moveTo(x, y); -} Common::String VirtualKeyboard::findArea(int16 x, int16 y) { - x -= _kbdBound.left; - y -= _kbdBound.top; - if (x < 0 || x > _kbdBound.width()) return ""; - if (y < 0 || y > _kbdBound.height()) return ""; return _currentMode->imageMap.findMapArea(x, y); } -void VirtualKeyboard::processClick(const Common::String& area) { +void VirtualKeyboard::processAreaClick(const Common::String& area) { if (!_currentMode->events.contains(area)) return; - Event evt = _currentMode->events[area]; + Event *evt = _currentMode->events[area]; - switch (evt.type) { + switch (evt->type) { case kEventKey: { // add virtual keypress to queue - Common::KeyState key = *(Common::KeyState*)evt.data; + Common::KeyState key = *(Common::KeyState*)evt->data; key.flags ^= _keyFlags; if ((key.keycode >= Common::KEYCODE_a) && (key.keycode <= Common::KEYCODE_z)) key.ascii = (key.flags & Common::KBD_SHIFT) ? key.keycode - 32 : key.keycode; @@ -208,25 +143,23 @@ void VirtualKeyboard::processClick(const Common::String& area) { break; } case kEventModifier: - _keyFlags ^= *(byte*)(evt.data); + _keyFlags ^= *(byte*)(evt->data); break; case kEventSwitchMode: // switch to new mode - switchMode(*(Common::String *)evt.data); + switchMode(*(Common::String *)evt->data); _keyFlags = 0; break; case kEventClose: // close virtual keyboard - _displaying = false; + _kbdGUI->hide(); break; } } void VirtualKeyboard::switchMode(Mode *newMode) { - _kbdBound.setWidth(newMode->image->w); - _kbdBound.setHeight(newMode->image->h); + _kbdGUI->setKeyboardSurface(newMode->image, newMode->transparentColor); _currentMode = newMode; - _needRedraw = true; } void VirtualKeyboard::switchMode(const Common::String& newMode) { @@ -237,6 +170,20 @@ void VirtualKeyboard::switchMode(const Common::String& newMode) { switchMode(&_modes[newMode]); } +void VirtualKeyboard::handleMouseDown(int16 x, int16 y) { + _areaDown = findArea(x, y); + if (_areaDown.empty()) + _kbdGUI->startDrag(x, y); +} + +void VirtualKeyboard::handleMouseUp(int16 x, int16 y) { + if (!_areaDown.empty() && _areaDown == findArea(x, y)) { + processAreaClick(_areaDown); + _areaDown.clear(); + } + _kbdGUI->endDrag(); +} + void VirtualKeyboard::show() { if (!_loaded) { // if not loaded then load default "vkeybd" pack @@ -245,90 +192,12 @@ void VirtualKeyboard::show() { return; } } - if (_lastScreenChanged != _system->getScreenChangeID()) - screenChanged(); switchMode(_initialMode); - _displaying = true; - if (_firstRun) { - _firstRun = false; - setDefaultPosition(); - } - - if (!g_gui.isActive()) { - _system->showOverlay(); - _system->clearOverlay(); - } - _overlayBackup.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor)); - _system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w); - setupCursor(); - - runLoop(); - - removeCursor(); - _system->copyRectToOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w, 0, 0, _overlayBackup.w, _overlayBackup.h); - if (!g_gui.isActive()) _system->hideOverlay(); - _overlayBackup.free(); -} -void VirtualKeyboard::hide() { - _displaying = false; -} - -void VirtualKeyboard::screenChanged() { - _lastScreenChanged = _system->getScreenChangeID(); - if (!checkModeResolutions()) - _displaying = false; -} + _kbdGUI->run(); -void VirtualKeyboard::runLoop() { - Common::EventManager *eventMan = _system->getEventManager(); - - while (_displaying) { - if (_needRedraw) redraw(); - - animateCursor(); - _system->updateScreen(); - Common::Event event; - while (eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_LBUTTONDOWN: - if (_kbdBound.contains(event.mouse)) { - _areaDown = findArea(event.mouse.x, event.mouse.y); - if (_areaDown.empty()) { - _drag = true; - _dragPoint.x = event.mouse.x - _kbdBound.left; - _dragPoint.y = event.mouse.y - _kbdBound.top; - } - } else - _areaDown.clear(); - break; - case Common::EVENT_LBUTTONUP: - if (_drag) _drag = false; - if (!_areaDown.empty() && _areaDown == findArea(event.mouse.x, event.mouse.y)) { - processClick(_areaDown); - _areaDown.clear(); - } - break; - case Common::EVENT_MOUSEMOVE: - if (_drag) { - move(event.mouse.x - _dragPoint.x, - event.mouse.y - _dragPoint.y); - _needRedraw = true; - } - break; - case Common::EVENT_SCREEN_CHANGED: - screenChanged(); - break; - case Common::EVENT_QUIT: - _system->quit(); - return; - default: - break; - } - } - // Delay for a moment - _system->delayMillis(10); - } + EventManager *eventMan = _system->getEventManager(); + assert(eventMan); // push keydown & keyup events into the event manager Common::Event evt; @@ -342,62 +211,20 @@ void VirtualKeyboard::runLoop() { } } -void VirtualKeyboard::redraw() { - Graphics::SurfaceKeyColored surf; - - surf.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor)); - - memcpy(surf.pixels, _overlayBackup.pixels, surf.w * surf.h * sizeof(OverlayColor)); - surf.blit(_currentMode->image, _kbdBound.left, _kbdBound.top, _currentMode->transparentColor); - - _system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 0, 0, surf.w, surf.h); - - surf.free(); - - _needRedraw = false; -} - -void VirtualKeyboard::setupCursor() { - const byte palette[] = { - 255, 255, 255, 0, - 255, 255, 255, 0, - 171, 171, 171, 0, - 87, 87, 87, 0 - }; - - CursorMan.pushCursorPalette(palette, 0, 4); - CursorMan.pushCursor(NULL, 0, 0, 0, 0); - CursorMan.showMouse(true); -} - -void VirtualKeyboard::animateCursor() { - int time = _system->getMillis(); - if (time > _cursorAnimateTimer + kCursorAnimateDelay) { - for (int i = 0; i < 15; i++) { - if ((i < 6) || (i > 8)) { - _cursor[16 * 7 + i] = _cursorAnimateCounter; - _cursor[16 * i + 7] = _cursorAnimateCounter; - } - } - - CursorMan.replaceCursor(_cursor, 16, 16, 7, 7); - - _cursorAnimateTimer = time; - _cursorAnimateCounter = (_cursorAnimateCounter + 1) % 4; - } +void VirtualKeyboard::hide() { + _kbdGUI->hide(); } -void VirtualKeyboard::removeCursor() { - CursorMan.popCursor(); - CursorMan.popCursorPalette(); +bool VirtualKeyboard::isDisplaying() { + return _kbdGUI->isDisplaying(); } -VirtualKeyboard::Queue::Queue() { - _keyPos = _keys.begin(); +VirtualKeyboard::KeyPressQueue::KeyPressQueue() { + _keyPos = _keys.end(); _strPos = 0; } -void VirtualKeyboard::Queue::insertKey(KeyState key) { +void VirtualKeyboard::KeyPressQueue::insertKey(KeyState key) { switch (key.keycode) { case KEYCODE_LEFT: moveLeft(); @@ -408,6 +235,8 @@ void VirtualKeyboard::Queue::insertKey(KeyState key) { case KEYCODE_BACKSPACE: deleteKey(); return; + default: + ; } String keyStr; @@ -429,10 +258,11 @@ void VirtualKeyboard::Queue::insertKey(KeyState key) { kp.key = key; kp.strLen = keyStr.size(); _keys.insert(_keyPos, kp); - _keyPos++; + + printf("%s %d\n", _str.c_str(), kp.strLen); } -void VirtualKeyboard::Queue::deleteKey() { +void VirtualKeyboard::KeyPressQueue::deleteKey() { if (_keyPos == _keys.begin()) return; List<VirtualKeyPress>::iterator it = _keyPos; @@ -443,41 +273,49 @@ void VirtualKeyboard::Queue::deleteKey() { _keys.erase(it); } -void VirtualKeyboard::Queue::moveLeft() { +void VirtualKeyboard::KeyPressQueue::moveLeft() { if (_keyPos == _keys.begin()) return; _keyPos--; _strPos -= _keyPos->strLen; } -void VirtualKeyboard::Queue::moveRight() { - List<VirtualKeyPress>::iterator it = _keyPos; - it++; - if (it == _keys.end()) +void VirtualKeyboard::KeyPressQueue::moveRight() { + if (_keyPos == _keys.end()) return; _strPos += _keyPos->strLen; - _keyPos = it; + _keyPos++; } -KeyState VirtualKeyboard::Queue::pop() { - KeyState ret = _keys.begin()->key; +KeyState VirtualKeyboard::KeyPressQueue::pop() { + bool front = (_keyPos == _keys.begin()); + VirtualKeyPress kp = *(_keys.begin()); _keys.pop_front(); - return ret; + + if (front) + _keyPos = _keys.begin(); + else + _strPos -= kp.strLen; + + while (kp.strLen-- > 0) + _str.deleteChar(0); + + return kp.key; } -void VirtualKeyboard::Queue::clear() { +void VirtualKeyboard::KeyPressQueue::clear() { _keys.clear(); - _keyPos = _keys.begin(); + _keyPos = _keys.end(); _str.clear(); _strPos = 0; } -bool VirtualKeyboard::Queue::empty() +bool VirtualKeyboard::KeyPressQueue::empty() { return _keys.empty(); } -String VirtualKeyboard::Queue::getString() +const String& VirtualKeyboard::KeyPressQueue::getString() { return _str; } diff --git a/backends/common/virtual-keyboard.h b/backends/common/virtual-keyboard.h index 3494de1e47..9aef84f421 100644 --- a/backends/common/virtual-keyboard.h +++ b/backends/common/virtual-keyboard.h @@ -35,10 +35,10 @@ class OSystem; #include "common/keyboard.h" #include "common/list.h" #include "common/str.h" -#include "graphics/surface.h" namespace Common { +class VirtualKeyboardGUI; class VirtualKeyboardParser; class VirtualKeyboard { @@ -53,11 +53,29 @@ protected: struct Event { Common::String name; EventType type; - Graphics::Surface *rollOverImage; void *data; + + Event() : data(0) {} + ~Event() { + if (data) { + switch (type) { + case kEventKey: + delete (KeyState*)data; + break; + case kEventModifier: + delete (byte*)data; + break; + case kEventSwitchMode: + delete (String*)data; + break; + case kEventClose: + break; + } + } + } }; - typedef Common::HashMap<Common::String, Event, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> EventMap; + typedef Common::HashMap<Common::String, Event*> EventMap; struct Mode { Common::String name; @@ -91,9 +109,9 @@ protected: uint strLen; }; - class Queue { + class KeyPressQueue { public: - Queue(); + KeyPressQueue(); void insertKey(KeyState key); void deleteKey(); void moveLeft(); @@ -101,13 +119,13 @@ protected: KeyState pop(); void clear(); bool empty(); - String getString(); + const String& getString(); private: List<VirtualKeyPress> _keys; - List<VirtualKeyPress>::iterator _keyPos; - String _str; + + List<VirtualKeyPress>::iterator _keyPos; uint _strPos; }; @@ -139,9 +157,7 @@ public: /** * Returns true if the keyboard is currently being shown */ - bool isDisplaying() { - return _displaying; - } + bool isDisplaying(); /** * Returns true if the keyboard is loaded and ready to be shown @@ -151,59 +167,39 @@ public: } protected: // TODO : clean up all this stuff - OSystem *_system; - byte _keyFlags; - Queue _keyQueue; - KeyState *_keyDown; + OSystem *_system; + friend class VirtualKeyboardGUI; + VirtualKeyboardGUI *_kbdGUI; - static const int SNAP_WIDTH = 10; + byte _keyFlags; + KeyPressQueue _keyQueue; + KeyState *_keyDown; friend class VirtualKeyboardParser; VirtualKeyboardParser *_parser; void reset(); - void deleteEventData(); - void screenChanged(); + void deleteEvents(); bool checkModeResolutions(); - void setDefaultPosition(); - void move(int16 x, int16 y); void switchMode(Mode *newMode); void switchMode(const Common::String& newMode); + void handleMouseDown(int16 x, int16 y); + void handleMouseUp(int16 x, int16 y); String findArea(int16 x, int16 y); - void processClick(const Common::String &area); - void runLoop(); - void redraw(); - - Graphics::Surface _overlayBackup; + void processAreaClick(const Common::String &area); bool _loaded; - bool _displaying; - bool _needRedraw; - bool _firstRun; ModeMap _modes; Mode *_initialMode; Mode *_currentMode; - int _lastScreenChanged; - Rect _kbdBound; - HorizontalAlignment _hAlignment; VerticalAlignment _vAlignment; String _areaDown; - Point _dragPoint; - bool _drag; - - static const int kCursorAnimateDelay = 250; - int _cursorAnimateCounter; - int _cursorAnimateTimer; - byte _cursor[2048]; - void setupCursor(); - void removeCursor(); - void animateCursor(); }; diff --git a/backends/module.mk b/backends/module.mk index 86b2bc8472..b690012042 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -29,6 +29,7 @@ MODULE_OBJS := \ saves/compressed/compressed-saves.o \ timer/default/default-timer.o \ common/virtual-keyboard.o \ + common/virtual-keyboard-gui.o \ common/virtual-keyboard-parser.o \ common/keymap.o \ common/keymap-manager.o \ diff --git a/dists/msvc8/scummvm.vcproj b/dists/msvc8/scummvm.vcproj index 7f1aacdb20..39056f231c 100644 --- a/dists/msvc8/scummvm.vcproj +++ b/dists/msvc8/scummvm.vcproj @@ -1093,6 +1093,14 @@ > </File> <File + RelativePath="..\..\backends\common\virtual-keyboard-gui.cpp" + > + </File> + <File + RelativePath="..\..\backends\common\virtual-keyboard-gui.h" + > + </File> + <File RelativePath="..\..\backends\common\virtual-keyboard-parser.cpp" > </File> diff --git a/graphics/surface-keycolored.cpp b/graphics/surface-keycolored.cpp index f533213fb6..86873a3944 100644 --- a/graphics/surface-keycolored.cpp +++ b/graphics/surface-keycolored.cpp @@ -41,4 +41,4 @@ void SurfaceKeyColored::blit(Surface *surf_src, int16 x, int16 y, OverlayColor t } } -} // end of namespace Graphics
\ No newline at end of file +} // end of namespace Graphics diff --git a/graphics/surface-keycolored.h b/graphics/surface-keycolored.h index 608bf7a482..43d5413275 100644 --- a/graphics/surface-keycolored.h +++ b/graphics/surface-keycolored.h @@ -14,4 +14,4 @@ struct SurfaceKeyColored : Surface { } // end of namespace Graphics -#endif
\ No newline at end of file +#endif |