From b1d11427391795f4851b7bad1bfe682befe8d064 Mon Sep 17 00:00:00 2001 From: Allanis Date: Wed, 27 Feb 2013 23:45:41 +0000 Subject: [PATCH] [Add] Basic toolkit focus. We can now completely navigate the menus etc with the keyboard. --- src/menu.c | 12 ++++--- src/toolkit.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 8 deletions(-) diff --git a/src/menu.c b/src/menu.c index 5f4bdfd..3c4db9b 100644 --- a/src/menu.c +++ b/src/menu.c @@ -42,15 +42,17 @@ void menu_small(void) { wid = window_create("Menu", -1, -1, MENU_WIDTH, MENU_HEIGHT); - window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, - "btnExit", "Exit", (void(*)(char*))exit_game); - window_addButton(wid, 20, 20 + BUTTON_HEIGHT + 20, - BUTTON_WIDTH, BUTTON_HEIGHT, - "btnOptions", "Options", (void(*)(char*))edit_options); window_addButton(wid, 20, 20 + BUTTON_HEIGHT*2 + 20*2, BUTTON_WIDTH, BUTTON_HEIGHT, "btnResume", "Resume", menu_small_close); + window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, + "btnExit", "Exit", (void(*)(char*))exit_game); + + window_addButton(wid, 20, 20 + BUTTON_HEIGHT + 20, + BUTTON_WIDTH, BUTTON_HEIGHT, + "btnOptions", "Options", (void(*)(char*))edit_options); + menu_Open(MENU_SMALL); } diff --git a/src/toolkit.c b/src/toolkit.c index 7fd0686..790bafa 100644 --- a/src/toolkit.c +++ b/src/toolkit.c @@ -14,8 +14,7 @@ typedef enum WidgetType_ { typedef enum WidgetStatus_ { WIDGET_STATUS_NORMAL, WIDGET_STATUS_MOUSEOVER, - WIDGET_STATUS_MOUSEDOWN, - WIDGET_STATUS_FOCUS + WIDGET_STATUS_MOUSEDOWN } WidgetStatus; typedef struct Widget_ { @@ -56,6 +55,9 @@ typedef struct Widget_ { typedef struct Window_ { unsigned int id; // Unique identifier. char* name; + + int hidden; // Is it hidden? + int focus; // Which window is focused. double x,y; // Position. double w,h; // Dimensions. @@ -79,6 +81,9 @@ static Window* window_wget(const unsigned int wid); static Widget* window_getwgt(const unsigned int wid, char* name); // Input. static void toolkit_mouseEvent(SDL_Event* event); +static int toolkit_keyEvent(SDL_Event* event); +static void toolkit_nextFocus(void); +static void toolkit_triggerFocus(void); // Render. static void window_render(Window* w); static void toolkit_renderButton(Widget* btn, double bx, double by); @@ -105,6 +110,9 @@ void window_addButton(const unsigned int wid, const int x, const int y, const in if(y < 0) wgt->y = wdw->h - wgt->h + y; else wgt->y = (double)y; wgt->dat.btn.fptr = call; + + if(wdw->focus == -1) // Init the focus. + toolkit_nextFocus(); } // Add text to the window. @@ -242,6 +250,9 @@ unsigned int window_create(char* name, const int x, const int y, const int w, co windows[nwindows].id = wid; windows[nwindows].name = strdup(name); + + windows[nwindows].hidden = 0; + windows[nwindows].focus = -1; windows[nwindows].w = (double) w; windows[nwindows].h = (double) h; @@ -334,7 +345,7 @@ void window_destroyWidget(unsigned int wid, const char* wgtname) { // Render a window. static void window_render(Window* w) { int i; - double x, y; + double x, y, wid, hei; glColour *lc, *c, *dc, *oc; // Position. @@ -520,6 +531,30 @@ static void window_render(Window* w) { break; } } + // Focus widget. + if(w->focus != -1) { + x += w->widgets[w->focus].x; + y += w->widgets[w->focus].y; + wid = w->widgets[w->focus].w; + hei = w->widgets[w->focus].h; + + glBegin(GL_LINE_LOOP); + COLOUR(cBlack); + // Left. + glVertex2d(x-3., y); + glVertex2d(x-3., y+hei); + // Top. + glVertex2d(x, y+hei+3.); + glVertex2d(x+wid, y+hei+3.); + // Right. + glVertex2d(x+wid+3., y+hei); + glVertex2d(x+wid+3., y); + // Bottom. + glVertex2d(x+wid, y-3.); + glVertex2d(x, y-3.); + glVertex2d(x-3., y); + glEnd(); + } } // Renders a button. @@ -702,6 +737,9 @@ int toolkit_input(SDL_Event* event) { case SDL_MOUSEBUTTONUP: toolkit_mouseEvent(event); return 1; // Block input. + case SDL_KEYDOWN: + case SDL_KEYUP: + return toolkit_keyEvent(event); } return 0; // Don't block unput. } @@ -767,6 +805,56 @@ static void toolkit_mouseEvent(SDL_Event* event) { } } +// Handle the key events. +static int toolkit_keyEvent(SDL_Event* event) { + SDLKey key = event->key.keysym.sym; + switch(key) { + case SDLK_TAB: + if(event->type == SDL_KEYDOWN) + toolkit_nextFocus(); + return 1; + case SDLK_RETURN: + if(event->type == SDL_KEYDOWN) + toolkit_triggerFocus(); + return 1; + default: + return 0; + } +} + +// Focus next widget. +static void toolkit_nextFocus(void) { + Window* wdw = &windows[nwindows-1]; // Get active window. + + if(wdw->nwidgets==0) + wdw->focus = -1; + else if(wdw->focus >= wdw->nwidgets) + wdw->focus = -1; + else if((++wdw->focus+1) && // Just increment. + (wdw->widgets[wdw->focus].type == WIDGET_BUTTON)) + return; + else + toolkit_nextFocus(); +} + +static void toolkit_triggerFocus(void) { + Window* wdw; + Widget* wgt; + + wdw = &windows[nwindows-1]; + + if(wdw->focus == -1) return; + + wgt = &wdw->widgets[wdw->focus]; + + switch(wgt->type) { + case WIDGET_BUTTON: + (*wgt->dat.btn.fptr)(wgt->name); + default: + break; + } +} + // Init. int toolkit_init(void) { windows = malloc(sizeof(Window)*MIN_WINDOWS);