[Add] Basic toolkit focus. We can now completely navigate the menus etc with the keyboard.

This commit is contained in:
Allanis 2013-02-27 23:45:41 +00:00
parent 521f3baa9f
commit b1d1142739
2 changed files with 98 additions and 8 deletions

View File

@ -42,15 +42,17 @@ void menu_small(void) {
wid = window_create("Menu", -1, -1, MENU_WIDTH, MENU_HEIGHT); 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, window_addButton(wid, 20, 20 + BUTTON_HEIGHT*2 + 20*2,
BUTTON_WIDTH, BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnResume", "Resume", menu_small_close); "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); menu_Open(MENU_SMALL);
} }

View File

@ -14,8 +14,7 @@ typedef enum WidgetType_ {
typedef enum WidgetStatus_ { typedef enum WidgetStatus_ {
WIDGET_STATUS_NORMAL, WIDGET_STATUS_NORMAL,
WIDGET_STATUS_MOUSEOVER, WIDGET_STATUS_MOUSEOVER,
WIDGET_STATUS_MOUSEDOWN, WIDGET_STATUS_MOUSEDOWN
WIDGET_STATUS_FOCUS
} WidgetStatus; } WidgetStatus;
typedef struct Widget_ { typedef struct Widget_ {
@ -57,6 +56,9 @@ typedef struct Window_ {
unsigned int id; // Unique identifier. unsigned int id; // Unique identifier.
char* name; char* name;
int hidden; // Is it hidden?
int focus; // Which window is focused.
double x,y; // Position. double x,y; // Position.
double w,h; // Dimensions. 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); static Widget* window_getwgt(const unsigned int wid, char* name);
// Input. // Input.
static void toolkit_mouseEvent(SDL_Event* event); 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. // Render.
static void window_render(Window* w); static void window_render(Window* w);
static void toolkit_renderButton(Widget* btn, double bx, double by); 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; if(y < 0) wgt->y = wdw->h - wgt->h + y;
else wgt->y = (double)y; else wgt->y = (double)y;
wgt->dat.btn.fptr = call; wgt->dat.btn.fptr = call;
if(wdw->focus == -1) // Init the focus.
toolkit_nextFocus();
} }
// Add text to the window. // Add text to the window.
@ -243,6 +251,9 @@ unsigned int window_create(char* name, const int x, const int y, const int w, co
windows[nwindows].id = wid; windows[nwindows].id = wid;
windows[nwindows].name = strdup(name); windows[nwindows].name = strdup(name);
windows[nwindows].hidden = 0;
windows[nwindows].focus = -1;
windows[nwindows].w = (double) w; windows[nwindows].w = (double) w;
windows[nwindows].h = (double) h; windows[nwindows].h = (double) h;
if((x == -1) && (y == -1)) { if((x == -1) && (y == -1)) {
@ -334,7 +345,7 @@ void window_destroyWidget(unsigned int wid, const char* wgtname) {
// Render a window. // Render a window.
static void window_render(Window* w) { static void window_render(Window* w) {
int i; int i;
double x, y; double x, y, wid, hei;
glColour *lc, *c, *dc, *oc; glColour *lc, *c, *dc, *oc;
// Position. // Position.
@ -520,6 +531,30 @@ static void window_render(Window* w) {
break; 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. // Renders a button.
@ -702,6 +737,9 @@ int toolkit_input(SDL_Event* event) {
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
toolkit_mouseEvent(event); toolkit_mouseEvent(event);
return 1; // Block input. return 1; // Block input.
case SDL_KEYDOWN:
case SDL_KEYUP:
return toolkit_keyEvent(event);
} }
return 0; // Don't block unput. 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. // Init.
int toolkit_init(void) { int toolkit_init(void) {
windows = malloc(sizeof(Window)*MIN_WINDOWS); windows = malloc(sizeof(Window)*MIN_WINDOWS);