[Add] Basic toolkit focus. We can now completely navigate the menus etc with the keyboard.
This commit is contained in:
parent
521f3baa9f
commit
b1d1142739
12
src/menu.c
12
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);
|
||||
}
|
||||
|
||||
|
@ -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_ {
|
||||
@ -57,6 +56,9 @@ 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.
|
||||
@ -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].name = strdup(name);
|
||||
|
||||
windows[nwindows].hidden = 0;
|
||||
windows[nwindows].focus = -1;
|
||||
|
||||
windows[nwindows].w = (double) w;
|
||||
windows[nwindows].h = (double) h;
|
||||
if((x == -1) && (y == -1)) {
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user