diff --git a/Src/gui/gui.cpp b/Src/gui/gui.cpp index 99af9d3..6bfd45f 100644 --- a/Src/gui/gui.cpp +++ b/Src/gui/gui.cpp @@ -75,6 +75,7 @@ Gui::Gui() this->infobox = NULL; this->textbox = NULL; this->status_bar_bg = NULL; + this->keyboard = NULL; this->default_font = NULL; this->dialogue_bg = NULL; this->small_font = NULL; @@ -131,6 +132,7 @@ Gui::~Gui() delete VirtualKeyboard::kbd; SDL_FreeSurface(this->bg_left); + SDL_FreeSurface(this->keyboard); SDL_FreeSurface(this->bg_middle); SDL_FreeSurface(this->bg_right); SDL_FreeSurface(this->bg_submenu_left); @@ -165,6 +167,7 @@ bool Gui::setTheme(const char *path) this->main_menu_bg = this->loadThemeImage(path, "main_menu_bg.png"); this->status_bar_bg = this->loadThemeImage(path, "status_bar.png"); this->infobox = this->loadThemeImage(path, "infobox.png"); + this->keyboard = this->loadThemeImage(path, "keyboard.png"); this->textbox = this->loadThemeImage(path, "textbox.png"); this->dialogue_bg = this->loadThemeImage(path, "dialogue_box.png"); this->disc_info = this->loadThemeImage(path, "disc_info.png"); @@ -199,6 +202,7 @@ bool Gui::setTheme(const char *path) SDL_FreeSurface(this->disc_info); SDL_FreeSurface(this->textbox); SDL_FreeSurface(this->selected_key); + SDL_FreeSurface(this->keyboard); SDL_FreeSurface(this->highlighted_key); SDL_FreeSurface(this->status_bar_bg); diff --git a/Src/gui/gui.hh b/Src/gui/gui.hh index 05cdc7c..a72f9ef 100644 --- a/Src/gui/gui.hh +++ b/Src/gui/gui.hh @@ -84,6 +84,7 @@ public: SDL_Surface *status_bar_bg; SDL_Surface *infobox; SDL_Surface *textbox; + SDL_Surface *keyboard; SDL_Surface *dialogue_bg; SDL_Surface *disc_info; SDL_Surface *bg_left, *bg_right, *bg_middle, diff --git a/Src/gui/main_menu.cpp b/Src/gui/main_menu.cpp index d5f33e6..eabb3b5 100644 --- a/Src/gui/main_menu.cpp +++ b/Src/gui/main_menu.cpp @@ -77,7 +77,7 @@ public: switch(this->p_submenus[2].sel) { case 0: - VirtualKeyboard::kbd->activate(); + VirtualKeyboard::kbd->activate(false); VirtualKeyboard::kbd->registerListener(new KeyboardTypingListener()); break; case 1: diff --git a/Src/gui/virtual_keyboard.cpp b/Src/gui/virtual_keyboard.cpp index d6af81c..c6d001b 100644 --- a/Src/gui/virtual_keyboard.cpp +++ b/Src/gui/virtual_keyboard.cpp @@ -20,16 +20,18 @@ typedef struct virtkey { const char *name; int kc; - bool is_shift; - bool is_done; + int flags; } virtkey_t; -#define INVALID_VIRTKEY ((struct virtkey){NULL, -1, false, false}) +#define F_IS_SHIFT 1 +#define F_IS_DONE 2 +#define F_SHIFT_ON 4 + +#define INVALID_VIRTKEY ((struct virtkey){NULL, -1, 0}) static inline bool IS_INVALID_VIRTKEY(virtkey_t *k) { - return k->name == NULL && k->kc == -1 && - k->is_done == false && k->is_shift == false; + return k->name == NULL && k->kc == -1 && k->flags == 0; } /* C64 keyboard matrix: @@ -47,15 +49,15 @@ static inline bool IS_INVALID_VIRTKEY(virtkey_t *k) #define MATRIX(a,b) (((a) << 3) | (b)) #define K(name, a,b) \ - { name, MATRIX(a,b), false, false } + { name, MATRIX(a,b), 0 } #define S(name, a,b) \ - { name, MATRIX(a,b), true, false } + { name, MATRIX(a,b), F_IS_SHIFT } #define N(name) \ - { name, -1, false, false } + { name, -1, 0 } #define D(name) \ - { name, -1, false, true } + { name, -1, F_IS_DONE} #define J(name, v) \ - { name, 0x40 | (v), false, false } + { name, 0x40 | (v), 0} #define KEY_COLS 15 #define KEY_ROWS 8 @@ -86,6 +88,7 @@ VirtualKeyboard::VirtualKeyboard(Font *font) : GuiView(), ListenerManager() this->sel_y = 0; this->shift_on = false; this->kbd_only_input = false; + this->default_shifted = false; this->is_active = false; this->buf_head = 0; @@ -103,11 +106,6 @@ void VirtualKeyboard::draw(SDL_Surface *where, int x_base, int y_base, int w, in { int key_w = w / KEY_COLS; int key_h = h / KEY_ROWS; - SDL_Rect bg_rect = {x_base, y_base, - key_w * KEY_COLS, key_h * KEY_ROWS}; - - SDL_FillRect(where, &bg_rect, - SDL_MapRGB(where->format, 0x00, 0x80, 0x80)); for (int y = 0; y < KEY_ROWS; y++ ) { @@ -279,8 +277,11 @@ const char VirtualKeyboard::keycodeToChar(int kc) return s[0]; } -void VirtualKeyboard::activate() +void VirtualKeyboard::activate(bool default_shifted) { + this->default_shifted = default_shifted; + this->shift_on = this->default_shifted; + Gui::gui->kbd = this; this->is_active = true; memset(this->buf, 0, sizeof(struct virtkey) * this->buf_len); @@ -325,15 +326,15 @@ void VirtualKeyboard::runLogic() if (!key) return; - if (key->is_shift == true) + if (key->flags & F_IS_SHIFT) this->toggleShift(); - else if (key->is_done) /* We're done! */ + else if (key->flags & F_IS_DONE) /* We're done! */ this->done(); else if (strcmp(key->name, "Del") == 0) { if (this->buf_head > 1) { - this->buf[this->buf_head - 1] = (struct virtkey){NULL, -1, false, false}; + this->buf[this->buf_head - 1] = INVALID_VIRTKEY; this->buf_head -= 2; } } @@ -345,9 +346,13 @@ void VirtualKeyboard::runLogic() void VirtualKeyboard::pushKey(struct virtkey *vk) { int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners); + struct virtkey key = *vk; + + if (this->shift_on) + key.flags |= F_SHIFT_ON; /* Add to buf */ - this->buf[this->buf_head] = *vk; + this->buf[this->buf_head] = key; this->buf_head++; if (this->buf_head >= this->buf_len - 1) @@ -367,26 +372,47 @@ void VirtualKeyboard::deactivate() Gui::gui->kbd = NULL; } +const char *VirtualKeyboard::getString() +{ + char *out = (char *)xmalloc(this->buf_head + 1); + + for (unsigned i = 0; i < this->buf_head; i++) + { + virtkey_t *k = &this->buf[i]; + int kc = k->kc | ((k->flags & F_SHIFT_ON) ? 0x80 : 0); + + out[i] = this->keycodeToChar(kc); + } + + return out; +} + void VirtualKeyboard::done() { int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners); - char *buf = (char *)xmalloc(this->buf_head + 1); - - for (unsigned i = 0; i < this->buf_head; i++) - buf[i] = this->keycodeToChar(this->buf[i].kc); + const char *str = this->getString(); for (int i = 0; i < n_listeners; i++) { if (this->listeners[i]) - ((KeyboardListener*)this->listeners[i])->stringCallback(buf); + ((KeyboardListener*)this->listeners[i])->stringCallback(str); } - free(buf); + free((void*)str); this->deactivate(); } void VirtualKeyboard::draw(SDL_Surface *where) { + SDL_Rect r = (SDL_Rect){10, 210, 0, 0}; + + SDL_BlitSurface(Gui::gui->keyboard, NULL, where, &r); this->draw(where, 20, 240, 600, 240); + + const char *str = this->getString(); + if (strlen(str) > 0) + this->font->draw(where, str, + 15, 212, 600, 240); + free((void*)str); } void VirtualKeyboard::updateTheme() @@ -401,6 +427,9 @@ void VirtualKeyboard::pushEvent(SDL_Event *ev) case SDL_KEYDOWN: switch (ev->key.keysym.sym) { + case SDLK_RSHIFT: + case SDLK_LSHIFT: + this->shift_on = !this->default_shifted; break; case SDLK_UP: case SDLK_DOWN: case SDLK_LEFT: @@ -424,10 +453,16 @@ void VirtualKeyboard::pushEvent(SDL_Event *ev) this->kbd_only_input = true; default: break; + } break; + case SDL_KEYUP: + switch (ev->key.keysym.sym) + { + case SDLK_RSHIFT: + case SDLK_LSHIFT: + this->shift_on = this->default_shifted; break; + default: break; } - default: - break; - + default: break; } } diff --git a/Src/gui/virtual_keyboard.hh b/Src/gui/virtual_keyboard.hh index df16936..32b1ae7 100644 --- a/Src/gui/virtual_keyboard.hh +++ b/Src/gui/virtual_keyboard.hh @@ -49,7 +49,7 @@ public: int stringToKeycode(const char *str); struct virtkey eventToVirtkey(event_t ev); - void activate(); + void activate(bool default_shifted = true); void setFont(Font *font) { @@ -73,6 +73,8 @@ public: void pushEvent(SDL_Event *ev); + const char *getString(); + /* Singleton object */ static VirtualKeyboard *kbd; private: @@ -90,6 +92,7 @@ private: bool shift_on; bool kbd_only_input; + bool default_shifted; bool is_active; struct virtkey *buf; diff --git a/themes/default/keyboard.png b/themes/default/keyboard.png new file mode 100644 index 0000000..7f6e22b Binary files /dev/null and b/themes/default/keyboard.png differ