Keyboard fixes: Allow switching shift state via the keyboard, add a

keyboard background image, use flags instead. Shift is default on for
all non-typing stuff.
This commit is contained in:
simon.kagstrom 2010-01-30 15:38:19 +00:00
parent feb9fdfc10
commit b7064f58f0
6 changed files with 74 additions and 31 deletions

View File

@ -75,6 +75,7 @@ Gui::Gui()
this->infobox = NULL; this->infobox = NULL;
this->textbox = NULL; this->textbox = NULL;
this->status_bar_bg = NULL; this->status_bar_bg = NULL;
this->keyboard = NULL;
this->default_font = NULL; this->default_font = NULL;
this->dialogue_bg = NULL; this->dialogue_bg = NULL;
this->small_font = NULL; this->small_font = NULL;
@ -131,6 +132,7 @@ Gui::~Gui()
delete VirtualKeyboard::kbd; delete VirtualKeyboard::kbd;
SDL_FreeSurface(this->bg_left); SDL_FreeSurface(this->bg_left);
SDL_FreeSurface(this->keyboard);
SDL_FreeSurface(this->bg_middle); SDL_FreeSurface(this->bg_middle);
SDL_FreeSurface(this->bg_right); SDL_FreeSurface(this->bg_right);
SDL_FreeSurface(this->bg_submenu_left); 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->main_menu_bg = this->loadThemeImage(path, "main_menu_bg.png");
this->status_bar_bg = this->loadThemeImage(path, "status_bar.png"); this->status_bar_bg = this->loadThemeImage(path, "status_bar.png");
this->infobox = this->loadThemeImage(path, "infobox.png"); this->infobox = this->loadThemeImage(path, "infobox.png");
this->keyboard = this->loadThemeImage(path, "keyboard.png");
this->textbox = this->loadThemeImage(path, "textbox.png"); this->textbox = this->loadThemeImage(path, "textbox.png");
this->dialogue_bg = this->loadThemeImage(path, "dialogue_box.png"); this->dialogue_bg = this->loadThemeImage(path, "dialogue_box.png");
this->disc_info = this->loadThemeImage(path, "disc_info.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->disc_info);
SDL_FreeSurface(this->textbox); SDL_FreeSurface(this->textbox);
SDL_FreeSurface(this->selected_key); SDL_FreeSurface(this->selected_key);
SDL_FreeSurface(this->keyboard);
SDL_FreeSurface(this->highlighted_key); SDL_FreeSurface(this->highlighted_key);
SDL_FreeSurface(this->status_bar_bg); SDL_FreeSurface(this->status_bar_bg);

View File

@ -84,6 +84,7 @@ public:
SDL_Surface *status_bar_bg; SDL_Surface *status_bar_bg;
SDL_Surface *infobox; SDL_Surface *infobox;
SDL_Surface *textbox; SDL_Surface *textbox;
SDL_Surface *keyboard;
SDL_Surface *dialogue_bg; SDL_Surface *dialogue_bg;
SDL_Surface *disc_info; SDL_Surface *disc_info;
SDL_Surface *bg_left, *bg_right, *bg_middle, SDL_Surface *bg_left, *bg_right, *bg_middle,

View File

@ -77,7 +77,7 @@ public:
switch(this->p_submenus[2].sel) switch(this->p_submenus[2].sel)
{ {
case 0: case 0:
VirtualKeyboard::kbd->activate(); VirtualKeyboard::kbd->activate(false);
VirtualKeyboard::kbd->registerListener(new KeyboardTypingListener()); VirtualKeyboard::kbd->registerListener(new KeyboardTypingListener());
break; break;
case 1: case 1:

View File

@ -20,16 +20,18 @@ typedef struct virtkey
{ {
const char *name; const char *name;
int kc; int kc;
bool is_shift; int flags;
bool is_done;
} virtkey_t; } 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) static inline bool IS_INVALID_VIRTKEY(virtkey_t *k)
{ {
return k->name == NULL && k->kc == -1 && return k->name == NULL && k->kc == -1 && k->flags == 0;
k->is_done == false && k->is_shift == false;
} }
/* /*
C64 keyboard matrix: C64 keyboard matrix:
@ -47,15 +49,15 @@ static inline bool IS_INVALID_VIRTKEY(virtkey_t *k)
#define MATRIX(a,b) (((a) << 3) | (b)) #define MATRIX(a,b) (((a) << 3) | (b))
#define K(name, a,b) \ #define K(name, a,b) \
{ name, MATRIX(a,b), false, false } { name, MATRIX(a,b), 0 }
#define S(name, a,b) \ #define S(name, a,b) \
{ name, MATRIX(a,b), true, false } { name, MATRIX(a,b), F_IS_SHIFT }
#define N(name) \ #define N(name) \
{ name, -1, false, false } { name, -1, 0 }
#define D(name) \ #define D(name) \
{ name, -1, false, true } { name, -1, F_IS_DONE}
#define J(name, v) \ #define J(name, v) \
{ name, 0x40 | (v), false, false } { name, 0x40 | (v), 0}
#define KEY_COLS 15 #define KEY_COLS 15
#define KEY_ROWS 8 #define KEY_ROWS 8
@ -86,6 +88,7 @@ VirtualKeyboard::VirtualKeyboard(Font *font) : GuiView(), ListenerManager()
this->sel_y = 0; this->sel_y = 0;
this->shift_on = false; this->shift_on = false;
this->kbd_only_input = false; this->kbd_only_input = false;
this->default_shifted = false;
this->is_active = false; this->is_active = false;
this->buf_head = 0; 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_w = w / KEY_COLS;
int key_h = h / KEY_ROWS; 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++ ) for (int y = 0; y < KEY_ROWS; y++ )
{ {
@ -279,8 +277,11 @@ const char VirtualKeyboard::keycodeToChar(int kc)
return s[0]; 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; Gui::gui->kbd = this;
this->is_active = true; this->is_active = true;
memset(this->buf, 0, sizeof(struct virtkey) * this->buf_len); memset(this->buf, 0, sizeof(struct virtkey) * this->buf_len);
@ -325,15 +326,15 @@ void VirtualKeyboard::runLogic()
if (!key) if (!key)
return; return;
if (key->is_shift == true) if (key->flags & F_IS_SHIFT)
this->toggleShift(); this->toggleShift();
else if (key->is_done) /* We're done! */ else if (key->flags & F_IS_DONE) /* We're done! */
this->done(); this->done();
else if (strcmp(key->name, "Del") == 0) else if (strcmp(key->name, "Del") == 0)
{ {
if (this->buf_head > 1) 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; this->buf_head -= 2;
} }
} }
@ -345,9 +346,13 @@ void VirtualKeyboard::runLogic()
void VirtualKeyboard::pushKey(struct virtkey *vk) void VirtualKeyboard::pushKey(struct virtkey *vk)
{ {
int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners); 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 */ /* Add to buf */
this->buf[this->buf_head] = *vk; this->buf[this->buf_head] = key;
this->buf_head++; this->buf_head++;
if (this->buf_head >= this->buf_len - 1) if (this->buf_head >= this->buf_len - 1)
@ -367,26 +372,47 @@ void VirtualKeyboard::deactivate()
Gui::gui->kbd = NULL; 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() void VirtualKeyboard::done()
{ {
int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners); int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners);
char *buf = (char *)xmalloc(this->buf_head + 1); const char *str = this->getString();
for (unsigned i = 0; i < this->buf_head; i++)
buf[i] = this->keycodeToChar(this->buf[i].kc);
for (int i = 0; i < n_listeners; i++) for (int i = 0; i < n_listeners; i++)
{ {
if (this->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(); this->deactivate();
} }
void VirtualKeyboard::draw(SDL_Surface *where) 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); 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() void VirtualKeyboard::updateTheme()
@ -401,6 +427,9 @@ void VirtualKeyboard::pushEvent(SDL_Event *ev)
case SDL_KEYDOWN: case SDL_KEYDOWN:
switch (ev->key.keysym.sym) switch (ev->key.keysym.sym)
{ {
case SDLK_RSHIFT:
case SDLK_LSHIFT:
this->shift_on = !this->default_shifted; break;
case SDLK_UP: case SDLK_UP:
case SDLK_DOWN: case SDLK_DOWN:
case SDLK_LEFT: case SDLK_LEFT:
@ -424,10 +453,16 @@ void VirtualKeyboard::pushEvent(SDL_Event *ev)
this->kbd_only_input = true; this->kbd_only_input = true;
default: default:
break; 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: default: break;
break;
} }
} }

View File

@ -49,7 +49,7 @@ public:
int stringToKeycode(const char *str); int stringToKeycode(const char *str);
struct virtkey eventToVirtkey(event_t ev); struct virtkey eventToVirtkey(event_t ev);
void activate(); void activate(bool default_shifted = true);
void setFont(Font *font) void setFont(Font *font)
{ {
@ -73,6 +73,8 @@ public:
void pushEvent(SDL_Event *ev); void pushEvent(SDL_Event *ev);
const char *getString();
/* Singleton object */ /* Singleton object */
static VirtualKeyboard *kbd; static VirtualKeyboard *kbd;
private: private:
@ -90,6 +92,7 @@ private:
bool shift_on; bool shift_on;
bool kbd_only_input; bool kbd_only_input;
bool default_shifted;
bool is_active; bool is_active;
struct virtkey *buf; struct virtkey *buf;

BIN
themes/default/keyboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB