diff --git a/Makefile b/Makefile index efc57d3..7bd5202 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ OBJS=menu.oo main.oo utils.oo gui.oo dialogue_box.oo menu_messages.oo \ - timer.oo game_info.oo widget.oo + timer.oo game_info.oo widget.oo virtual_keyboard.oo all: menu @@ -14,6 +14,8 @@ gui.oo: gui.cpp gui.hh Makefile font.hh menu.hh sdl_ttf_font.hh \ dialogue_box.hh help_box.hh main_menu.cpp disc_menu.cpp \ file_browser.hh timer.hh game_info.hh +virtual_keyboard.oo: virtual_keyboard.hh virtual_keyboard.cpp widget.hh + game_info.oo: game_info.hh game_info.cpp utils.oo: utils.cpp utils.hh Makefile diff --git a/virtual_keyboard.cpp b/virtual_keyboard.cpp index b1fdea4..4c9a1bb 100644 --- a/virtual_keyboard.cpp +++ b/virtual_keyboard.cpp @@ -12,8 +12,8 @@ #include #include -#include "menu.h" #include "virtual_keyboard.hh" +#include "utils.hh" typedef struct virtkey { @@ -71,13 +71,16 @@ static const char *shifted_names[KEY_COLS * KEY_ROWS] = { NULL, NULL, NULL, NULL, NULL, NULL, "f2", "f4", "f6", "f8", "Ins", NULL, NULL, NULL, NULL, }; -VirtualKeyboard::VirtualKeyboard(TTF_Font *font) +VirtualKeyboard::VirtualKeyboard(TTF_Font *font) : Widget() { this->font = font; this->sel_x = 0; this->sel_y = 0; this->shift_on = false; + this->is_active = false; + this->buf_head = 0; + memset(this->buf, 0, sizeof(this->buf)); memset(this->stringListeners, 0, sizeof(this->stringListeners)); memset(this->keyListeners, 0, sizeof(this->keyListeners)); @@ -117,10 +120,11 @@ void VirtualKeyboard::draw(SDL_Surface *where, int x, int y, int w, int h) if ( (x == this->sel_x && y == this->sel_y) || (this->shift_on && key.is_shift)) b = 0; - +#if 0 menu_print_font(where, r, g, b, x * key_w + border_x, y * key_h + border_y, what); +#endif } } } @@ -225,109 +229,6 @@ const char VirtualKeyboard::keycodeToChar(int kc) return s[0]; } -struct virtkey *VirtualKeyboard::getKeyInternal() -{ - while(1) - { - uint32_t k; - - this->draw(); - SDL_Flip(this->screen); - - k = menu_wait_key_press(); - - if (k & KEY_UP) - this->selectNext(0, -1); - else if (k & KEY_DOWN) - this->selectNext(0, 1); - else if (k & KEY_LEFT) - this->selectNext(-1, 0); - else if (k & KEY_RIGHT) - this->selectNext(1, 0); - else if (k & KEY_ESCAPE) - return NULL; - else if (k & KEY_SELECT) - { - virtkey_t *key = &keys[ this->sel_y * KEY_COLS + this->sel_x ]; - - if (key->is_shift == true) - this->toggleShift(); - else - return key; - } - } - - return NULL; -} - -int VirtualKeyboard::getKey() -{ - virtkey_t *key; - - SDL_FillRect(this->screen, 0, SDL_MapRGB(screen->format, 0x00, 0x80, 0x80)); - - key = this->getKeyInternal(); - if (key == NULL) - return -2; - - if (this->shift_on) - return key->kc | 0x80; - return key->kc; -} - -const char *VirtualKeyboard::getString() -{ - int cnt = 0; - - SDL_FillRect(this->screen, 0, SDL_MapRGB(screen->format, 0x00, 0x80, 0x80)); - memset(this->buf, 0, sizeof(this->buf)); - - while (true) - { - virtkey_t *key = this->getKeyInternal(); - char c; - - /* Abort */ - if (key == NULL) - return NULL; - - /* Done */ - if (key->is_done) - return this->buf; - /* Skip None */ - if (key->kc == -1) - continue; - - /* Special-case for delete */ - if (strcmp(key->name, "Del") == 0) - { - if (cnt < 1) - continue; - this->buf[cnt - 1] = ' '; - cnt -= 2; - } - else - { - c = this->keycodeToChar( this->shift_on ? key->kc | 0x80 : key->kc ); - - this->buf[cnt] = c; - } - - cnt++; - if (cnt >= sizeof(this->buf) - 1) - return this->buf; - - /* SDL_Flip is done in get_key_internal() */ - SDL_FillRect(this->screen, 0, SDL_MapRGB(screen->format, 0x00, 0x80, 0x80)); - menu_print_font(this->screen, 255, 255, 0, - 40, screen->h - 50, - this->buf); - } - - /* Not reachable */ - return NULL; -} - void VirtualKeyboard::registerListener(KeyListener *kl) { int n_listeners = sizeof(this->keyListeners) / sizeof(*this->keyListeners); @@ -376,3 +277,87 @@ void VirtualKeyboard::unregisterListener(StringListener *sl) this->stringListeners[i] = NULL; } } + +void VirtualKeyboard::activate() +{ + this->is_active = true; + memset(this->buf, 0, sizeof(this->buf)); + this->buf_head = 0; +} + + +void VirtualKeyboard::runLogic() +{ + event_t ev; + + if (!this->is_active) + return; + + ev = this->popEvent(); + if (ev == EVENT_NONE) + return; + + if (ev & KEY_UP) + this->selectNext(0, -1); + else if (ev & KEY_DOWN) + this->selectNext(0, 1); + else if (ev & KEY_LEFT) + this->selectNext(-1, 0); + else if (ev & KEY_RIGHT) + this->selectNext(1, 0); + else if (ev & KEY_ESCAPE) + this->deactivate(); + else if (ev & KEY_SELECT) + { + virtkey_t *key = &keys[ this->sel_y * KEY_COLS + this->sel_x ]; + + if (!key) + return; + + if (key->is_shift == true) + this->toggleShift(); + else if (key->is_done) + { + int n_listeners = sizeof(this->stringListeners) / sizeof(*this->stringListeners); + + for (int i = 0; i < n_listeners; i++) + { + if (this->stringListeners[i]) + this->stringListeners[i]->stringCallback(this->buf); + } + /* We're done! */ + this->deactivate(); + } + else if (strcmp(key->name, "Del") == 0) + { + if (this->buf_head > 1) + { + this->buf[this->buf_head - 1] = ' '; + this->buf_head -= 2; + } + } + else + { + int n_listeners = sizeof(this->keyListeners) / sizeof(*this->keyListeners); + char c; + + /* Add to buf */ + c = this->keycodeToChar( this->shift_on ? key->kc | 0x80 : key->kc ); + + this->buf[this->buf_head] = c; + + this->buf_head++; + if (this->buf_head >= sizeof(this->buf) - 1) + this->buf_head = 0; /* OK, not good, but well... */ + for (int i = 0; i < n_listeners; i++) + { + if (this->keyListeners[i]) + this->keyListeners[i]->keyCallback(this->shift_on, + key->name); + } + } + } +} + +/* The singleton */ +VirtualKeyboard *VirtualKeyboard::kbd; diff --git a/virtual_keyboard.hh b/virtual_keyboard.hh index 44c0381..f59ee87 100644 --- a/virtual_keyboard.hh +++ b/virtual_keyboard.hh @@ -9,19 +9,27 @@ * $Id$ * ********************************************************************/ +#ifndef __VIRTUAL_KEYBORD_HH__ +#define __VIRTUAL_KEYBORD_HH__ + #include #include +#include "widget.hh" + struct virtkey; class KeyListener { - void keyCallback(char c); +public: + /* Each key is a string */ + virtual void keyCallback(bool shift, const char *str) = 0; }; class StringListener { - void stringCallback(const char *str); +public: + virtual void stringCallback(const char *str) = 0; }; class VirtualKeyboard : public Widget @@ -35,13 +43,19 @@ public: void unregisterListener(StringListener *sl); /* Conversions */ - int getKey(); - const char *getString(); const char *keycodeToString(int kc); const char keycodeToChar(int kc); int charToKeycode(char c); + int stringToKeycode(const char *str); - void pushEvent(SDL_Event *ev); + void activate(); + + void deactivate() + { + this->is_active = false; + } + + void runLogic(); void draw(SDL_Surface *where, int x, int y, int w, int h); @@ -51,7 +65,6 @@ private: KeyListener *keyListeners[8]; StringListener *stringListeners[8]; - struct virtkey *getKeyInternal(); void selectNext(int dx, int dy); void toggleShift(); @@ -60,5 +73,9 @@ private: int sel_y; bool shift_on; + bool is_active; char buf[255]; + unsigned buf_head; }; + +#endif /* __VIRTUAL_KEYBORD_HH__ */