aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Kennedy2008-07-26 20:35:46 +0000
committerStephen Kennedy2008-07-26 20:35:46 +0000
commit6e48d5c76d829a0439f06ed8ca92dc9887b3be23 (patch)
tree2d487a7dae55459f18bb5ad0a9cd563a12360309
parentdfcdbb0d335128c99d13ba017a4e36f2338f7736 (diff)
downloadscummvm-rg350-6e48d5c76d829a0439f06ed8ca92dc9887b3be23.tar.gz
scummvm-rg350-6e48d5c76d829a0439f06ed8ca92dc9887b3be23.tar.bz2
scummvm-rg350-6e48d5c76d829a0439f06ed8ca92dc9887b3be23.zip
VirtualKeyboard:
- implemented functionality for modifier keys - cleaned up parser - started on text display svn-id: r33317
-rw-r--r--backends/common/virtual-keyboard-parser.cpp97
-rw-r--r--backends/common/virtual-keyboard-parser.h4
-rw-r--r--backends/common/virtual-keyboard.cpp106
-rw-r--r--backends/common/virtual-keyboard.h67
4 files changed, 220 insertions, 54 deletions
diff --git a/backends/common/virtual-keyboard-parser.cpp b/backends/common/virtual-keyboard-parser.cpp
index 7b1e79e937..ed77bc215c 100644
--- a/backends/common/virtual-keyboard-parser.cpp
+++ b/backends/common/virtual-keyboard-parser.cpp
@@ -240,20 +240,20 @@ bool VirtualKeyboardParser::parserCallback_Event() {
uint16 ascii = atoi(evtNode->values["ascii"].c_str());
byte flags = 0;
- if (evtNode->values.contains("flags")) {
- Common::StringTokenizer tok(evtNode->values["flags"], ", ");
- for (Common::String fl = tok.nextToken(); !fl.empty(); fl = tok.nextToken()) {
- if (fl == "ctrl" || fl == "control")
- flags &= Common::KBD_CTRL;
- else if (fl == "alt")
- flags &= Common::KBD_ALT;
- else if (fl == "shift")
- flags &= Common::KBD_SHIFT;
- }
- }
+ if (evtNode->values.contains("flags"))
+ flags = parseFlags(evtNode->values["flags"]);
evt.data = new Common::KeyState(code, ascii, flags);
+ } else if (type == "modifier") {
+ if (!evtNode->values.contains("flags"))
+ return parserError("Key modifier element must contain modifier attributes");
+
+ evt.type = VirtualKeyboard::kEventModifier;
+ byte *flags = new byte;
+ *(flags) = parseFlags(evtNode->values["flags"]);
+ evt.data = flags;
+
} else if (type == "switch_mode") {
if (!evtNode->values.contains("mode"))
return parserError("Switch mode event element must contain mode attribute");
@@ -335,29 +335,62 @@ bool VirtualKeyboardParser::parserCallback_Area() {
if (!areaNode->values.contains("shape") || !areaNode->values.contains("coords") || !areaNode->values.contains("target"))
return parserError("Area element must contain shape, coords and target attributes");
- Common::String shape = areaNode->values["shape"];
- if (shape == "rect") {
- Common::Rect *rect = _mode->imageMap.createRectArea(areaNode->values["target"]);
- int x1, y1, x2, y2;
- if (!parseIntegerKey(areaNode->values["coords"].c_str(), 4, &x1, &y1, &x2, &y2))
- return parserError("Invalid coords for rect area");
- rect->left = x1; rect->top = y1; rect->right = x2; rect->bottom = y2;
+ Common::String& shape = areaNode->values["shape"];
+ Common::String& target = areaNode->values["target"];
+ Common::String& coords = areaNode->values["coords"];
+
+ if (target == "preview_area") {
+ if (shape != "rect")
+ return parserError("preview_area must be a rect area");
+ _mode->previewArea = new Common::Rect();
+ return parseRect(_mode->previewArea, coords);
+ } else if (shape == "rect") {
+ Common::Rect *rect = _mode->imageMap.createRectArea(target);
+ return parseRect(rect, coords);
} else if (shape == "poly") {
- Common::StringTokenizer tok (areaNode->values["coords"], ", ");
- Common::Polygon *poly = _mode->imageMap.createPolygonArea(areaNode->values["target"]);
- for (Common::String st = tok.nextToken(); !st.empty(); st = tok.nextToken()) {
- int x, y;
- if (sscanf(st.c_str(), "%d", &x) != 1)
- return parserError("Invalid coords for polygon area");
- st = tok.nextToken();
- if (sscanf(st.c_str(), "%d", &y) != 1)
- return parserError("Invalid coords for polygon area");
- poly->addPoint(x, y);
- }
- if (poly->getPointCount() < 3)
+ Common::Polygon *poly = _mode->imageMap.createPolygonArea(target);
+ return parsePolygon(poly, coords);
+ }
+ return parserError("Area shape '%s' not known", shape.c_str());
+}
+
+byte VirtualKeyboardParser::parseFlags(const String& flags) {
+ 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;
+ else if (fl == "alt")
+ val &= Common::KBD_ALT;
+ else if (fl == "shift")
+ val &= Common::KBD_SHIFT;
+ }
+ return val;
+}
+
+bool VirtualKeyboardParser::parseRect(Common::Rect *rect, const String& coords) {
+ int x1, y1, x2, y2;
+ if (!parseIntegerKey(coords.c_str(), 4, &x1, &y1, &x2, &y2))
+ return parserError("Invalid coords for rect area");
+ rect->left = x1; rect->top = y1; rect->right = x2; rect->bottom = y2;
+ if (!rect->isValidRect())
+ return parserError("Rect area is not a valid rectangle");
+ return true;
+}
+
+bool VirtualKeyboardParser::parsePolygon(Common::Polygon *poly, const String& coords) {
+ Common::StringTokenizer tok (coords, ", ");
+ for (Common::String st = tok.nextToken(); !st.empty(); st = tok.nextToken()) {
+ int x, y;
+ if (sscanf(st.c_str(), "%d", &x) != 1)
return parserError("Invalid coords for polygon area");
- } else
- return parserError("Area shape '%s' not known", shape.c_str());
+ st = tok.nextToken();
+ if (sscanf(st.c_str(), "%d", &y) != 1)
+ return parserError("Invalid coords for polygon area");
+ poly->addPoint(x, y);
+ }
+ if (poly->getPointCount() < 3)
+ return parserError("Invalid coords for polygon area");
return true;
}
diff --git a/backends/common/virtual-keyboard-parser.h b/backends/common/virtual-keyboard-parser.h
index cd2ea28faf..dfb7286191 100644
--- a/backends/common/virtual-keyboard-parser.h
+++ b/backends/common/virtual-keyboard-parser.h
@@ -203,6 +203,10 @@ protected:
bool parserCallback_KeyboardClosed();
bool parserCallback_ModeClosed();
+ byte parseFlags(const String& flags);
+ bool parseRect(Common::Rect *rect, const String& coords);
+ bool parsePolygon(Common::Polygon *poly, const String& coords);
+
Common::HashMap<Common::String, ParserCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _callbacks;
Common::HashMap<Common::String, ParserCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _closedCallbacks;
};
diff --git a/backends/common/virtual-keyboard.cpp b/backends/common/virtual-keyboard.cpp
index 0a061df545..e6ef87b946 100644
--- a/backends/common/virtual-keyboard.cpp
+++ b/backends/common/virtual-keyboard.cpp
@@ -63,6 +63,7 @@ void VirtualKeyboard::reset() {
_vAlignment = kAlignBottom;
_keyQueue.clear();
_keyDown = 0;
+ _keyFlags = 0;
_displaying = _drag = false;
_firstRun = true;
_lastScreenChanged = _system->getScreenChangeID();
@@ -196,13 +197,23 @@ void VirtualKeyboard::processClick(const Common::String& area) {
Event evt = _currentMode->events[area];
switch (evt.type) {
- case kEventKey:
+ case kEventKey: {
// add virtual keypress to queue
- _keyQueue.push(*(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;
+ _keyQueue.insertKey(key);
+ _keyFlags = 0;
+ break;
+ }
+ case kEventModifier:
+ _keyFlags ^= *(byte*)(evt.data);
break;
case kEventSwitchMode:
// switch to new mode
switchMode(*(Common::String *)evt.data);
+ _keyFlags = 0;
break;
case kEventClose:
// close virtual keyboard
@@ -247,7 +258,6 @@ void VirtualKeyboard::show() {
_system->showOverlay();
_system->clearOverlay();
}
-
_overlayBackup.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
_system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
setupCursor();
@@ -382,4 +392,94 @@ void VirtualKeyboard::removeCursor() {
CursorMan.popCursorPalette();
}
+VirtualKeyboard::Queue::Queue() {
+ _keyPos = _keys.begin();
+ _strPos = 0;
+}
+
+void VirtualKeyboard::Queue::insertKey(KeyState key) {
+ switch (key.keycode) {
+ case KEYCODE_LEFT:
+ moveLeft();
+ return;
+ case KEYCODE_RIGHT:
+ moveRight();
+ return;
+ case KEYCODE_BACKSPACE:
+ deleteKey();
+ return;
+ }
+
+ String keyStr;
+ if (key.keycode >= 32 && key.keycode <= 126) {
+ if (key.flags & KBD_CTRL)
+ keyStr += "Ctrl+";
+ if (key.flags & KBD_ALT)
+ keyStr += "Alt+";
+ if (key.flags & KBD_SHIFT && (key.ascii < 65 || key.ascii > 90))
+ keyStr += "Shift+";
+ keyStr += (char)key.ascii;
+ }
+
+ const char *k = keyStr.c_str();
+ while (char ch = *k++)
+ _str.insertChar(ch, _strPos++);
+
+ VirtualKeyPress kp;
+ kp.key = key;
+ kp.strLen = keyStr.size();
+ _keys.insert(_keyPos, kp);
+ _keyPos++;
+}
+
+void VirtualKeyboard::Queue::deleteKey() {
+ if (_keyPos == _keys.begin())
+ return;
+ List<VirtualKeyPress>::iterator it = _keyPos;
+ it--;
+ _strPos -= it->strLen;
+ while((it->strLen)-- > 0)
+ _str.deleteChar(_strPos);
+ _keys.erase(it);
+}
+
+void VirtualKeyboard::Queue::moveLeft() {
+ if (_keyPos == _keys.begin())
+ return;
+ _keyPos--;
+ _strPos -= _keyPos->strLen;
+}
+
+void VirtualKeyboard::Queue::moveRight() {
+ List<VirtualKeyPress>::iterator it = _keyPos;
+ it++;
+ if (it == _keys.end())
+ return;
+ _strPos += _keyPos->strLen;
+ _keyPos = it;
+}
+
+KeyState VirtualKeyboard::Queue::pop() {
+ KeyState ret = _keys.begin()->key;
+ _keys.pop_front();
+ return ret;
+}
+
+void VirtualKeyboard::Queue::clear() {
+ _keys.clear();
+ _keyPos = _keys.begin();
+ _str.clear();
+ _strPos = 0;
+}
+
+bool VirtualKeyboard::Queue::empty()
+{
+ return _keys.empty();
+}
+
+String VirtualKeyboard::Queue::getString()
+{
+ return _str;
+}
+
} // end of namespace Common
diff --git a/backends/common/virtual-keyboard.h b/backends/common/virtual-keyboard.h
index fc2300c24c..3494de1e47 100644
--- a/backends/common/virtual-keyboard.h
+++ b/backends/common/virtual-keyboard.h
@@ -33,7 +33,7 @@ class OSystem;
#include "common/hash-str.h"
#include "common/image-map.h"
#include "common/keyboard.h"
-#include "common/queue.h"
+#include "common/list.h"
#include "common/str.h"
#include "graphics/surface.h"
@@ -42,9 +42,10 @@ namespace Common {
class VirtualKeyboardParser;
class VirtualKeyboard {
-
+protected:
enum EventType {
kEventKey,
+ kEventModifier,
kEventSwitchMode,
kEventClose
};
@@ -59,14 +60,16 @@ class VirtualKeyboard {
typedef Common::HashMap<Common::String, Event, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> EventMap;
struct Mode {
- Common::String name;
- Common::String resolution;
- Common::String bitmapName;
- Graphics::Surface *image;
- OverlayColor transparentColor;
- Common::ImageMap imageMap;
- EventMap events;
- Mode() : image(0) {}
+ Common::String name;
+ Common::String resolution;
+ Common::String bitmapName;
+ Graphics::Surface *image;
+ OverlayColor transparentColor;
+ Common::ImageMap imageMap;
+ EventMap events;
+ Common::Rect *previewArea;
+
+ Mode() : image(0), previewArea(0) {}
};
typedef Common::HashMap<Common::String, Mode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ModeMap;
@@ -83,6 +86,31 @@ class VirtualKeyboard {
kAlignBottom
};
+ struct VirtualKeyPress {
+ Common::KeyState key;
+ uint strLen;
+ };
+
+ class Queue {
+ public:
+ Queue();
+ void insertKey(KeyState key);
+ void deleteKey();
+ void moveLeft();
+ void moveRight();
+ KeyState pop();
+ void clear();
+ bool empty();
+ String getString();
+
+ private:
+ List<VirtualKeyPress> _keys;
+ List<VirtualKeyPress>::iterator _keyPos;
+
+ String _str;
+ uint _strPos;
+ };
+
public:
VirtualKeyboard();
virtual ~VirtualKeyboard();
@@ -122,15 +150,19 @@ public:
return _loaded;
}
-protected:
+protected: // TODO : clean up all this stuff
OSystem *_system;
+ byte _keyFlags;
+ Queue _keyQueue;
+ KeyState *_keyDown;
+
+
static const int SNAP_WIDTH = 10;
friend class VirtualKeyboardParser;
VirtualKeyboardParser *_parser;
- // TODO : sort order of all this stuff
void reset();
void deleteEventData();
void screenChanged();
@@ -139,7 +171,7 @@ protected:
void move(int16 x, int16 y);
void switchMode(Mode *newMode);
void switchMode(const Common::String& newMode);
- Common::String findArea(int16 x, int16 y);
+ String findArea(int16 x, int16 y);
void processClick(const Common::String &area);
void runLoop();
void redraw();
@@ -156,18 +188,15 @@ protected:
Mode *_currentMode;
int _lastScreenChanged;
- Common::Rect _kbdBound;
+ Rect _kbdBound;
HorizontalAlignment _hAlignment;
VerticalAlignment _vAlignment;
- Common::String _areaDown;
- Common::Point _dragPoint;
+ String _areaDown;
+ Point _dragPoint;
bool _drag;
- Common::Queue<Common::KeyState> _keyQueue;
- Common::KeyState *_keyDown;
-
static const int kCursorAnimateDelay = 250;
int _cursorAnimateCounter;
int _cursorAnimateTimer;