Virtual Keyboard:

* added support for submit, cancel, backspace, and cursor movement commands
* minor API modifications

svn-id: r33887
This commit is contained in:
Stephen Kennedy 2008-08-15 01:21:29 +00:00
parent c61294e70f
commit fca5a0ad34
7 changed files with 95 additions and 80 deletions

View file

@ -421,7 +421,7 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
// HACK to show/hide keyboard (keyboard is not shown if gui is active) // HACK to show/hide keyboard (keyboard is not shown if gui is active)
if (event.kbd.keycode == Common::KEYCODE_F6 && event.kbd.flags == 0) { if (event.kbd.keycode == Common::KEYCODE_F6 && event.kbd.flags == 0) {
if (_vk->isDisplaying()) { if (_vk->isDisplaying()) {
_vk->hide(); _vk->close(true);
} else { } else {
bool isPaused = (g_engine) ? g_engine->isPaused() : true; bool isPaused = (g_engine) ? g_engine->isPaused() : true;
if (!isPaused) g_engine->pauseEngine(true); if (!isPaused) g_engine->pauseEngine(true);

View file

@ -114,7 +114,7 @@ void VirtualKeyboardGUI::run() {
_dispSurface.free(); _dispSurface.free();
} }
void VirtualKeyboardGUI::hide() { void VirtualKeyboardGUI::close() {
_displaying = false; _displaying = false;
} }

View file

@ -43,7 +43,7 @@ public:
void initMode(VirtualKeyboard::Mode *mode); void initMode(VirtualKeyboard::Mode *mode);
void run(); void run();
void hide(); void close();
bool isDisplaying() { return _displaying; } bool isDisplaying() { return _displaying; }
void reset(); void reset();
void startDrag(int16 x, int16 y); void startDrag(int16 x, int16 y);

View file

@ -235,17 +235,15 @@ bool VirtualKeyboardParser::parserCallback_Event() {
delete evt; delete evt;
return parserError("Key event element must contain code and ascii attributes"); return parserError("Key event element must contain code and ascii attributes");
} }
evt->type = VirtualKeyboard::kEventKey; evt->type = VirtualKeyboard::kEventKey;
KeyCode code = (KeyCode)atoi(evtNode->values["code"].c_str()); KeyState *ks = (KeyState*) malloc(sizeof(KeyState));
uint16 ascii = atoi(evtNode->values["ascii"].c_str()); ks->keycode = (KeyCode)atoi(evtNode->values["code"].c_str());
ks->ascii = atoi(evtNode->values["ascii"].c_str());
byte flags = 0; ks->flags = 0;
if (evtNode->values.contains("modifiers")) if (evtNode->values.contains("modifiers"))
flags = parseFlags(evtNode->values["modifiers"]); ks->flags = parseFlags(evtNode->values["modifiers"]);
evt->data = ks;
evt->data = new KeyState(code, ascii, flags);
} else if (type == "modifier") { } else if (type == "modifier") {
if (!evtNode->values.contains("modifiers")) { if (!evtNode->values.contains("modifiers")) {
@ -254,7 +252,7 @@ bool VirtualKeyboardParser::parserCallback_Event() {
} }
evt->type = VirtualKeyboard::kEventModifier; evt->type = VirtualKeyboard::kEventModifier;
byte *flags = new byte; byte *flags = (byte*) malloc(sizeof(byte));
*(flags) = parseFlags(evtNode->values["modifiers"]); *(flags) = parseFlags(evtNode->values["modifiers"]);
evt->data = flags; evt->data = flags;
@ -265,9 +263,25 @@ bool VirtualKeyboardParser::parserCallback_Event() {
} }
evt->type = VirtualKeyboard::kEventSwitchMode; evt->type = VirtualKeyboard::kEventSwitchMode;
evt->data = new String(evtNode->values["mode"]); String& mode = evtNode->values["mode"];
} else if (type == "close") { char *str = (char*) malloc(sizeof(char) * mode.size() + 1);
evt->type = VirtualKeyboard::kEventClose; memcpy(str, mode.c_str(), sizeof(char) * mode.size());
str[mode.size()] = 0;
evt->data = str;
} else if (type == "submit") {
evt->type = VirtualKeyboard::kEventSubmit;
evt->data = 0;
} else if (type == "cancel") {
evt->type = VirtualKeyboard::kEventCancel;
evt->data = 0;
} else if (type == "delete") {
evt->type = VirtualKeyboard::kEventDelete;
evt->data = 0;
} else if (type == "move_left") {
evt->type = VirtualKeyboard::kEventMoveLeft;
evt->data = 0;
} else if (type == "move_right") {
evt->type = VirtualKeyboard::kEventMoveRight;
evt->data = 0; evt->data = 0;
} else { } else {
delete evt; delete evt;

View file

@ -36,7 +36,7 @@ VirtualKeyboard::VirtualKeyboard() : _currentMode(0) {
_parser = new VirtualKeyboardParser(this); _parser = new VirtualKeyboardParser(this);
_kbdGUI = new VirtualKeyboardGUI(this); _kbdGUI = new VirtualKeyboardGUI(this);
_loaded = false; _submitKeys = _loaded = false;
} }
VirtualKeyboard::~VirtualKeyboard() { VirtualKeyboard::~VirtualKeyboard() {
@ -139,12 +139,23 @@ void VirtualKeyboard::processAreaClick(const Common::String& area) {
break; break;
case kEventSwitchMode: case kEventSwitchMode:
// switch to new mode // switch to new mode
switchMode(*(Common::String *)evt->data); switchMode((char *)evt->data);
_keyQueue.clearFlags(); _keyQueue.clearFlags();
break; break;
case kEventClose: case kEventSubmit:
// close virtual keyboard close(true);
_kbdGUI->hide(); break;
case kEventCancel:
close(false);
break;
case kEventDelete:
_keyQueue.deleteKey();
break;
case kEventMoveLeft:
_keyQueue.moveLeft();
break;
case kEventMoveRight:
_keyQueue.moveRight();
break; break;
} }
} }
@ -188,23 +199,28 @@ void VirtualKeyboard::show() {
_kbdGUI->run(); _kbdGUI->run();
EventManager *eventMan = _system->getEventManager(); if (_submitKeys) {
assert(eventMan); EventManager *eventMan = _system->getEventManager();
assert(eventMan);
// push keydown & keyup events into the event manager // push keydown & keyup events into the event manager
Common::Event evt; Common::Event evt;
evt.synthetic = false; evt.synthetic = false;
while (!_keyQueue.empty()) { while (!_keyQueue.empty()) {
evt.kbd = _keyQueue.pop(); evt.kbd = _keyQueue.pop();
evt.type = Common::EVENT_KEYDOWN; evt.type = Common::EVENT_KEYDOWN;
eventMan->pushEvent(evt); eventMan->pushEvent(evt);
evt.type = Common::EVENT_KEYUP; evt.type = Common::EVENT_KEYUP;
eventMan->pushEvent(evt); eventMan->pushEvent(evt);
}
} else {
_keyQueue.clear();
} }
} }
void VirtualKeyboard::hide() { void VirtualKeyboard::close(bool submit) {
_kbdGUI->hide(); _submitKeys = submit;
_kbdGUI->close();
} }
bool VirtualKeyboard::isDisplaying() { bool VirtualKeyboard::isDisplaying() {
@ -230,20 +246,6 @@ void VirtualKeyboard::KeyPressQueue::clearFlags() {
void VirtualKeyboard::KeyPressQueue::insertKey(KeyState key) { void VirtualKeyboard::KeyPressQueue::insertKey(KeyState key) {
_strChanged = true; _strChanged = true;
switch (key.keycode) {
case KEYCODE_LEFT:
moveLeft();
return;
case KEYCODE_RIGHT:
moveRight();
return;
case KEYCODE_BACKSPACE:
deleteKey();
return;
default:
;
}
key.flags ^= _keyFlags; key.flags ^= _keyFlags;
if ((key.keycode >= Common::KEYCODE_a) && (key.keycode <= Common::KEYCODE_z)) if ((key.keycode >= Common::KEYCODE_a) && (key.keycode <= Common::KEYCODE_z))
key.ascii = (key.flags & Common::KBD_SHIFT) ? key.keycode - 32 : key.keycode; key.ascii = (key.flags & Common::KBD_SHIFT) ? key.keycode - 32 : key.keycode;

View file

@ -47,7 +47,11 @@ protected:
kEventKey, kEventKey,
kEventModifier, kEventModifier,
kEventSwitchMode, kEventSwitchMode,
kEventClose kEventSubmit,
kEventCancel,
kEventDelete,
kEventMoveLeft,
kEventMoveRight
}; };
struct Event { struct Event {
@ -57,21 +61,7 @@ protected:
Event() : data(0) {} Event() : data(0) {}
~Event() { ~Event() {
if (data) { if (data) free(data);
switch (type) {
case kEventKey:
delete (KeyState*)data;
break;
case kEventModifier:
delete (byte*)data;
break;
case kEventSwitchMode:
delete (String*)data;
break;
case kEventClose:
break;
}
}
} }
}; };
@ -144,34 +134,41 @@ public:
virtual ~VirtualKeyboard(); virtual ~VirtualKeyboard();
/** /**
* Loads the keyboard pack with the given name. * Loads the keyboard pack with the given name.
* The system first looks for an uncompressed keyboard pack by searching * The system first looks for an uncompressed keyboard pack by searching
* for packName.xml in the filesystem, if this does not exist then it * for packName.xml in the filesystem, if this does not exist then it
* searches for a compressed keyboard pack by looking for packName.zip. * searches for a compressed keyboard pack by looking for packName.zip.
* @param packName name of the keyboard pack * @param packName name of the keyboard pack
*/ */
bool loadKeyboardPack(Common::String packName); bool loadKeyboardPack(Common::String packName);
/** /**
* Shows the keyboard, starting an event loop that will intercept all * Shows the keyboard, starting an event loop that will intercept all
* user input (like a modal GUI dialog). * user input (like a modal GUI dialog).
* It is assumed that the game has been paused, before this is called * It is assumed that the game has been paused, before this is called
*/ */
void show(); void show();
/** /**
* Hides the keyboard, ending the event loop. * Hides the keyboard, ending the event loop.
*/ * @param submit if true all accumulated key presses are submitted to
void hide(); * the event manager
*/
void close(bool submit);
/** /**
* Returns true if the keyboard is currently being shown * Hides the keyboard, submiting any key presses to the event manager
*/ */
void submit();
/**
* Returns true if the keyboard is currently being shown
*/
bool isDisplaying(); bool isDisplaying();
/** /**
* Returns true if the keyboard is loaded and ready to be shown * Returns true if the keyboard is loaded and ready to be shown
*/ */
bool isLoaded() { bool isLoaded() {
return _loaded; return _loaded;
} }
@ -209,6 +206,8 @@ protected: // TODO : clean up all this stuff
String _areaDown; String _areaDown;
bool _submitKeys;
}; };

Binary file not shown.