From 14e525078eecec883fabe2345643979015e3e08a Mon Sep 17 00:00:00 2001 From: Allanis Date: Sun, 17 Feb 2013 19:51:31 +0000 Subject: [PATCH] [Add] Basic toolkit for window/widget rendering etc. [Add] Landing. --- src/conf.c | 1 + src/input.c | 14 ++- src/land.c | 30 ++++++ src/land.h | 8 ++ src/main.c | 21 ++-- src/opengl.c | 13 ++- src/opengl.h | 15 +-- src/outfit.c | 4 +- src/pause.c | 2 - src/player.c | 37 ++++--- src/ship.c | 5 +- src/toolkit.c | 264 +++++++++++++++++++++++++++++++++++++++++++++----- src/toolkit.h | 12 ++- src/xml.h | 6 +- 14 files changed, 356 insertions(+), 76 deletions(-) create mode 100644 src/land.c create mode 100644 src/land.h diff --git a/src/conf.c b/src/conf.c index 17dd719..e12691c 100644 --- a/src/conf.c +++ b/src/conf.c @@ -153,6 +153,7 @@ int conf_loadConfig(const char* file) { } else { // Failed to load the config file.. DEBUG("Config file '%s' not found.", file); + lua_close(L); return 1; } lua_close(L); diff --git a/src/input.c b/src/input.c index 8fdcb33..cac9d85 100644 --- a/src/input.c +++ b/src/input.c @@ -2,6 +2,7 @@ #include "log.h" #include "player.h" #include "pause.h" +#include "toolkit.h" #include "input.h" #define KEY_PRESS ( 1.) @@ -53,7 +54,7 @@ void input_setDefault(void) { input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 0); input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_DOWN, 0); input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0); - input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_p, 0); + input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_F1, 0); } // Initialization/exit functions (does not assign keys). @@ -99,7 +100,7 @@ void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) { // value : Value of keypress (defined above). // abs : Whether or not it's an abs value (For those pesky joysticks. // ===================================================================== -#define KEY(s) strcmp(input_keybinds[keynum]->name, s)==0 +#define KEY(s) (strcmp(input_keybinds[keynum]->name, s)==0) static void input_key(int keynum, double value, int abs) { // Accelerating. if(KEY("accel")) { @@ -198,7 +199,8 @@ static void input_key(int keynum, double value, int abs) { // Pause the game. if(KEY("pause")) { if(value == KEY_PRESS) { - if(paused) unpause(); + if(!toolkit) + if(paused) unpause(); } else pause(); } } @@ -292,6 +294,12 @@ void input_handle(SDL_Event* event) { case SDL_KEYUP: input_keyup(event->key.keysym.sym); break; + // Toolkit. + case SDL_MOUSEMOTION: + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + if(toolkit) toolkit_mouseEvent(event); + break; } } diff --git a/src/land.c b/src/land.c new file mode 100644 index 0000000..7f56c2b --- /dev/null +++ b/src/land.c @@ -0,0 +1,30 @@ +#include "toolkit.h" +#include "pause.h" +#include "land.h" + +int landed = 0; + +static int land_wid = 0; +static Planet* planet = NULL; + +// Land the player. +void land(Planet* p) { + if(landed) return; + + planet = p; + pause(); + land_wid = window_create(-1, -1, 400, 300); + window_addButton(land_wid, 400-80-20, 20, 80, 40, "takeoff", "Takeoff", (void(*)(char*))takeoff); + landed = 1; +} + +// Takeoff from the planet. +void takeoff(void) { + if(!landed) return; + + planet = NULL; + unpause(); + window_destroy(land_wid); + landed = 0; +} + diff --git a/src/land.h b/src/land.h new file mode 100644 index 0000000..f2efde7 --- /dev/null +++ b/src/land.h @@ -0,0 +1,8 @@ +#pragma once +#include "space.h" + +extern int landed; + +void land(Planet* p); +void takeoff(void); + diff --git a/src/main.c b/src/main.c index dac9317..75a809c 100644 --- a/src/main.c +++ b/src/main.c @@ -51,6 +51,7 @@ static void display_fps(const double dt); static void window_caption(void); static void data_name(void); // Update. +static void fps_control(void); static void update_space(void); static void render_space(void); @@ -151,7 +152,8 @@ int main(int argc, char** argv) { } glClear(GL_COLOR_BUFFER_BIT); - + + fps_control(); // Who doesn't love FPS control? if(!paused) update_space(); // Update the game. render_space(); @@ -186,24 +188,21 @@ int main(int argc, char** argv) { // Updates the game. static double fps_dt = 1.; static double dt = 0.; -static void update_space(void) { +static void fps_control(void) { // dt in ms/1000. dt = (double)(SDL_GetTicks() - gtime) / 1000.; gtime = SDL_GetTicks(); - // TODO: This could use some work. - if(dt > MINIMUM_FPS) { - Vec2 pos; - vect_csetmin(&pos, 10., (double)(gl_screen.h-40)); - SDL_GL_SwapBuffers(); - return; - } - // If FPS is limited. - else if((max_fps != 0) && (dt < 1./max_fps)) { + // If the fps is limited.. + if((max_fps != 0) && (dt < 1./max_fps)) { double delay = 1./max_fps - dt; SDL_Delay(delay); fps_dt += delay; // Make sure it displays the propper FPS. } +} + +// Update the game. +static void update_space(void) { weapons_update(dt); pilots_update(dt); } diff --git a/src/opengl.c b/src/opengl.c index b6a169e..a9433b1 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -19,8 +19,11 @@ #define FONT_DEF "../gfx/fonts/font.ttf" // Default colors. -glColour cGrey = { .r = 0.75, .g = 0.75, .b = 0.75, .a = 1 }; -glColour cGreen = { .r = 0.20, .g = 0.80, .b = 0.20, .a = 1 }; +gl_colour cLightGrey = { .r = 0.80, .g = 0.80, .b = 0.80, .a = 1 }; +gl_colour cGrey = { .r = 0.65, .g = 0.65, .b = 0.65, .a = 1 }; +gl_colour cDarkGrey = { .r = 0.50, .g = 0.50, .b = 0.50, .a = 1 }; +gl_colour cGreen = { .r = 0.20, .g = 0.80, .b = 0.20, .a = 1 }; +gl_colour cRed = { .r = 0.80, .g = 0.20, .b = 0.20, .a = 1 }; // offsets to Adjust the pilot's place onscreen to be in the middle, even with the GUI. extern double gui_xoff; @@ -349,7 +352,7 @@ void gl_getSpriteFromDir(int* x, int* y, const gl_texture* t, const double dir) // ================ // Blit the sprite at given position. -void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, const int sx, const int sy, const glColour* c) { +void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, const int sx, const int sy, const gl_colour* c) { // Don't bother drawing if offscreen -- waste of cycles. if(fabs(VX(*pos) -VX(*gl_camera)+gui_xoff) > gl_screen.w / 2 + sprite->sw / 2 || fabs(VY(*pos) -VY(*gl_camera)+gui_yoff) > gl_screen.h / 2 + sprite->sh / 2) @@ -391,7 +394,7 @@ void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, const int sx, cons } // Just straight out blit the thing at position. -void gl_blitStatic(const gl_texture* texture, const Vec2* pos, const glColour* c) { +void gl_blitStatic(const gl_texture* texture, const Vec2* pos, const gl_colour* c) { glEnable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPushMatrix(); // Set up translation matrix. @@ -425,7 +428,7 @@ void gl_bindCamera(const Vec2* pos) { // Print text on screen! YES!!!! Just like printf! But different! // Defaults ft_font to gl_defFont if NULL. -void gl_print(const gl_font* ft_font, const Vec2* pos, const glColour* c, const char* fmt, ...) { +void gl_print(const gl_font* ft_font, const Vec2* pos, const gl_colour* c, const char* fmt, ...) { //float h = ft_font->h / .63; // Slightly increases font size. char text[256]; va_list ap; diff --git a/src/opengl.h b/src/opengl.h index e0244c4..c4b4e87 100644 --- a/src/opengl.h +++ b/src/opengl.h @@ -30,12 +30,15 @@ extern gl_info gl_screen; // Local structure set with gl_init etc. // Colours. typedef struct { double r, g, b, a; -} glColour; +} gl_colour; #define COLOUR(x) glColor4d((x).r, (x).g, (x).b, (x).a) // Default colors. -extern glColour cGrey; -extern glColour cGreen; +extern gl_colour cLightGrey; +extern gl_colour cGrey; +extern gl_colour cDarkGrey; +extern gl_colour cGreen; +extern gl_colour cRed; // Spritesheet info. typedef struct { @@ -69,11 +72,11 @@ void gl_freeTexture(gl_texture* texture); // Rendering. void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, - const int sx, const int sy, const glColour* c); + const int sx, const int sy, const gl_colour* c); -void gl_blitStatic(const gl_texture* texture, const Vec2* pos, const glColour* c); +void gl_blitStatic(const gl_texture* texture, const Vec2* pos, const gl_colour* c); void gl_bindCamera(const Vec2* pos); -void gl_print(const gl_font* ft_font, const Vec2* pos, const glColour* c, const char* fmt, ...); +void gl_print(const gl_font* ft_font, const Vec2* pos, const gl_colour* c, const char* fmt, ...); int gl_printWidth(const gl_font* ft_font, const char* fmt, ...); // Initialize/cleanup. diff --git a/src/outfit.c b/src/outfit.c index f5479fc..a9dce7c 100644 --- a/src/outfit.c +++ b/src/outfit.c @@ -278,8 +278,8 @@ int outfit_load(void) { void outfit_free(void) { int i; for(i = 0; i < outfits; i++) { - if(outfit_isWeapon(&outfit_stack[i]) && outfit_stack[i].gfx_space) - gl_freeTexture(outfit_stack[i].gfx_space); + // Free graphics. + if(outfit_stack[i].gfx_space) gl_freeTexture(outfit_stack[i].gfx_space); if(outfit_isLauncher(&outfit_stack[i]) && outfit_stack[i].ammo) free(outfit_stack[i].ammo); diff --git a/src/pause.c b/src/pause.c index b08471a..93325d3 100644 --- a/src/pause.c +++ b/src/pause.c @@ -20,7 +20,6 @@ static void pilots_unpause(void); void pause(void) { if(paused) return; // Well well.. We are paused already. - gtime -= SDL_GetTicks(); pilots_pause(); weapons_pause(); @@ -30,7 +29,6 @@ void pause(void) { void unpause(void) { if(!paused) return; // We are unpaused already. - gtime += SDL_GetTicks(); pilots_unpause(); weapons_unpause(); diff --git a/src/player.c b/src/player.c index 34c883c..ec283c2 100644 --- a/src/player.c +++ b/src/player.c @@ -8,6 +8,7 @@ #include "xml.h" #include "space.h" #include "rng.h" +#include "land.h" #include "player.h" #define XML_GUI_ID "GUIs" // XML section identifier. @@ -39,20 +40,20 @@ extern int pilots; // -- Colours. // Standard colors. -glColour cConsole = { .r = 0.5, .g = 0.8, .b = 0.5, .a = 1. }; +gl_colour cConsole = { .r = 0.5, .g = 0.8, .b = 0.5, .a = 1. }; -glColour cInert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. }; -glColour cNeutral = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. }; -glColour cFriend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. }; -glColour cHostile = { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1. }; +gl_colour cInert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. }; +gl_colour cNeutral = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. }; +gl_colour cFriend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. }; +gl_colour cHostile = { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1. }; -glColour cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1. }; -glColour cRadar_targ = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. }; -glColour cRadar_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. }; +gl_colour cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1. }; +gl_colour cRadar_targ = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. }; +gl_colour cRadar_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. }; // Bars. -glColour cShield = { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1. }; -glColour cArmor = { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1. }; -glColour cEnergy = { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1. }; +gl_colour cShield = { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1. }; +gl_colour cArmor = { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1. }; +gl_colour cEnergy = { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1. }; typedef struct { double w,h; // Dimensions. @@ -115,7 +116,7 @@ extern void planets_minimap(const double res, const double w, const double h, co static void rect_parse(const xmlNodePtr parent, double* x, double* y, double* w, double* h); static int gui_parse(const xmlNodePtr parent, const char* name); static void gui_renderPilot(const Pilot* p); -static void gui_renderBar(const glColour* c, const Vec2* p, const Rect* r, const double w); +static void gui_renderBar(const gl_colour* c, const Vec2* p, const Rect* r, const double w); // Create a new player. void player_new(void) { @@ -216,7 +217,7 @@ void player_render(void) { Pilot* p; Planet* planet; Vec2 v; - glColour* c; + gl_colour* c; gl_font* f; // Render the player target graphics. @@ -467,7 +468,7 @@ static void gui_renderPilot(const Pilot* p) { } // Render a bar. -static void gui_renderBar(const glColour* c, const Vec2* p, const Rect* r, const double w) { +static void gui_renderBar(const gl_colour* c, const Vec2* p, const Rect* r, const double w) { int x, y, sx, sy; glBegin(GL_QUADS); @@ -858,6 +859,11 @@ void player_targetPlanet(void) { // Attempt to land or target closest planet if no land target. void player_land(void) { + if(landed) { + // Player is already landed. + takeoff(); + return; + } Planet* planet = &cur_system->planets[planet_target]; if(planet_target >= 0) { if(vect_dist(&player->solid->vel, &planet->pos) > planet->gfx_space->sw) { @@ -868,8 +874,7 @@ void player_land(void) { player_message("You are going too fast to land on %s", planet->name); return; } - // TODO: Landing. - player_message("D'aww.. Allanis was too lazy to do it properly."); + land(planet); // Land the player. } else { // Get nearest planet target. int i; diff --git a/src/ship.c b/src/ship.c index c482317..ec9a791 100644 --- a/src/ship.c +++ b/src/ship.c @@ -191,8 +191,9 @@ void ships_free(void) { ShipOutfit* so, *sot; int i; for(i = 0; i < ships; i++) { - if((ship_stack+i)->name) // Free the name. - free((ship_stack+i)->name); + // Free stored strings. + if((ship_stack+i)->name) free(ship_stack[i].name); + if((ship_stack+i)->gui) free(ship_stack[i].gui); so = (ship_stack+i)->outfit; while(so) { // free the ship outfit. sot = so; diff --git a/src/toolkit.c b/src/toolkit.c index 44bbf9f..a10bebf 100644 --- a/src/toolkit.c +++ b/src/toolkit.c @@ -1,14 +1,41 @@ #include "log.h" #include "pause.h" +#include "opengl.h" #include "toolkit.h" +typedef enum { + WIDGET_NULL, + WIDGET_BUTTON, + WIDGET_TEXT +} WidgetType; + +typedef enum { + WIDGET_STATUS_NORMAL, + WIDGET_STATUS_MOUSEOVER, + WIDGET_STATUS_MOUSEDOWN, +} WidgetStatus; + +typedef struct { + char* name; // Widget name. + WidgetType type; // type.. + + double x,y; // Position. + double w,h; // Dimensions. + + WidgetStatus status; + + void(*fptr) (char*); // Callback. + char* string; // Stored text. +} Widget; + typedef struct { unsigned int id; // Unique identifier. double x,y; // Position. double w,h; // Dimensions. - gl_texture* t; // Possible texture. + Widget* widgets; // Widget storage. + int nwidgets; // Total number of widgets. } Window; static unsigned int genwid = 0; // Generate unique id. @@ -16,46 +43,109 @@ static unsigned int genwid = 0; // Generate unique id. int toolkit = 0; #define MIN_WINDOWS 3 -static Window** windows = NULL; +static Window* windows = NULL; static int nwindows = 0; static int mwindows = 0; +static Widget* window_newWidget(const unsigned int wid); +static void widget_cleanup(Widget* widget); +static void window_render(Window* w); + +// Add a button that when pressed will trigger call, passing it's name as the +// only parameter. +void window_addButton(const unsigned int wid, const int x, const int y, const int w, + const int h, char* name, char* display, void (*call)(char*)) { + + Widget* widget = window_newWidget(wid); + + widget->type = WIDGET_BUTTON; + widget->name = strdup(name); + widget->string = strdup(display); + + // Set the properties. + widget->x = (double) x; + widget->y = (double) y; + widget->w = (double) w; + widget->h = (double) h; + widget->fptr = call; +} + +// Return pointer to newly allocated widget. +static Widget* window_newWidget(const unsigned int wid) { + int i; + for(i = 0; i < nwindows; i++) + if(windows[i].id == wid) + break; + + if(i == nwindows) return NULL; + + Widget* w = NULL; + + windows[i].widgets = realloc(windows[i].widgets, sizeof(Widget)*(++windows[i].nwidgets)); + if(windows[i].widgets == NULL) WARN("Out of memory"); + + w = &windows[i].widgets[windows[i].nwidgets - 1]; + + w->type = WIDGET_NULL; + w->status = WIDGET_STATUS_NORMAL; + return w; +} + // Create a window. -unsigned int window_create(int x, int y, int w, int h, gl_texture* t) { - Window* wtmp = NULL; - if(nwindows == mwindows) { - // We have reached the memory limit. - windows = realloc(windows, sizeof(Window*)*(++mwindows)); +unsigned int window_create(const int x, const int y, const int w, const int h) { + if(nwindows >= mwindows) { + // We have reached our memory limit. + windows = realloc(windows, sizeof(Window)*(++mwindows)); if(windows == NULL) WARN("Out of memory"); } - wtmp = malloc(sizeof(Window)); - if(wtmp == NULL) WARN("Out of memory"); - int wid = (++genwid); // Unique id + const int wid = (++genwid); // Unique id - wtmp->id = wid; + windows[nwindows].id = wid; - wtmp->x = x; - wtmp->y = y; - wtmp->h = h; - wtmp->w = w; - wtmp->t = t; + windows[nwindows].w = (double) w; + windows[nwindows].h = (double) h; + if((x == -1) && (y == -1)) { + // Center. + windows[nwindows].x = windows[nwindows].w/2.; + windows[nwindows].y = windows[nwindows].h/2.; + } else { + windows[nwindows].x = (double) x; + windows[nwindows].y = (double) y; + } + + windows[nwindows].widgets = NULL; + windows[nwindows].nwidgets = 0; - windows[nwindows++] = wtmp; + nwindows++; - if(toolkit == 0) toolkit = 1; // Enable the toolkit. + if(toolkit == 0) { + // Toolkit is enabled. + SDL_ShowCursor(SDL_ENABLE); + toolkit = 1; // Enable it. + } return wid; } +// Destroy a widget. +static void widget_cleanup(Widget* widget) { + if(widget->name) free(widget->name); + + if((widget->type == WIDGET_TEXT) && widget->string) + free(widget->string); +} + // Destroy a window. void window_destroy(unsigned int wid) { - int i; + int i, j; // Destroy the window. for(i = 0; i < nwindows; i++) - if(windows[i]->id == wid) { - free(windows[i]); + if(windows[i].id == wid) { + for(j = 0; j < windows[i].nwidgets; j++) + widget_cleanup(&windows[i].widgets[j]); + free(windows[i].widgets); break; } // Move the other windows down a layer. @@ -63,12 +153,138 @@ void window_destroy(unsigned int wid) { windows[i] = windows[i+1]; nwindows--; - if(nwindows == 0) toolkit = 0; // Disable the toolkit. + if(nwindows == 0) { + // No windows left. + SDL_ShowCursor(SDL_DISABLE); + toolkit = 0; // Disable the toolkit. + } +} + +// Render a window. +static void window_render(Window* w) { + int i, j; + double x, y; + Widget* wgt; + Vec2 v; + + x = w->x - (double)gl_screen.w/2.; + y = w->y - (double)gl_screen.h/2.; + + // Translate to window position (bottom left). + glMatrixMode(GL_PROJECTION); + glPushMatrix(); // Projection translation matrix. + glTranslated(x, y, 0.); + + // Window background. + glBegin(GL_TRIANGLE_STRIP); + COLOUR(cLightGrey); + + glVertex2d(0., 0.); + glVertex2d(w->w, 0.); + glVertex2d(0., w->h); + glVertex2d(w->w, w->h); + glEnd(); + + glPopMatrix(); // Gl Projection. + + // Widgets. + for(i = 0; i < w->nwidgets; i++) { + wgt = &w->widgets[i]; + + switch(wgt->type) { + case WIDGET_NULL: + break; + case WIDGET_BUTTON: + glMatrixMode(GL_PROJECTION); + glPushMatrix(); // Projection matrix. + glTranslated(x + wgt->x, y + wgt->y, 0.); + + glBegin(GL_TRIANGLE_STRIP); + switch(wgt->status) { + // Set the colour. + case WIDGET_STATUS_NORMAL: COLOUR(cDarkGrey); break; + case WIDGET_STATUS_MOUSEOVER: COLOUR(cGrey); break; + case WIDGET_STATUS_MOUSEDOWN: COLOUR(cGreen); break; + } + + glVertex2d(0., 0.); + glVertex2d(wgt->w, 0.); + glVertex2d(0., wgt->h); + glVertex2d(wgt->w, wgt->h); + glEnd(); + glPopMatrix(); + + j = gl_printWidth(NULL, wgt->string); + vect_csetmin(&v, w->x + wgt->x + (wgt->w - (double)j)/2., + w->y + wgt->y + (wgt->h - gl_defFont.h)/2.); + gl_print(NULL, &v, &cRed, wgt->string); + break; + case WIDGET_TEXT: + break; + } + } } // Render the window. void toolkit_render(void) { + int i; + for(i = 0; i < nwindows; i++) + window_render(&windows[i]); +} +// Input. +static int mouse_down = 0; +void toolkit_mouseEvent(SDL_Event* event) { + int i; + double x, y; + Window* w; + Widget* wgt; + + // Set mouse button status. + if(event->type == SDL_MOUSEBUTTONDOWN) mouse_down = 1; + else if(event->type == SDL_MOUSEBUTTONUP) mouse_down = 0; + // Ignore movements if mouse is down. + else if((event->type == SDL_MOUSEMOTION) && mouse_down) return; + + // Absolute positions. + if(event->type == SDL_MOUSEMOTION) { + x = (double)event->motion.x; + y = gl_screen.h - (double)event->motion.y; + } + else if((event->type == SDL_MOUSEBUTTONDOWN) || (event->type == SDL_MOUSEBUTTONUP)) { + x = (double)event->button.x; + y = gl_screen.h - (double)event->motion.y; + } + + w = &windows[nwindows-1]; + + if((x < w->x) || (x > (w->x + w->w)) || (y < w->y) || (y > (w->y + w->h))) + return; // Not in current window. + + // Relative positions. + x -= w->x; + y -= w->y; + + for(i = 0; i < w->nwidgets; i++) { + wgt = &w->widgets[i]; + if((x > wgt->x) && (x < (wgt->x + wgt->w)) && (y > wgt->y) && (y < (wgt->y + wgt->h))) { + switch(event->type) { + case SDL_MOUSEMOTION: + wgt->status = WIDGET_STATUS_MOUSEOVER; + break; + case SDL_MOUSEBUTTONDOWN: + wgt->status = WIDGET_STATUS_MOUSEDOWN; + break; + case SDL_MOUSEBUTTONUP: + if(wgt->status == WIDGET_STATUS_MOUSEDOWN) { + if(wgt->type == WIDGET_BUTTON) (*wgt->fptr)(wgt->name); + } + wgt->status = WIDGET_STATUS_NORMAL; + break; + } + } else + wgt->status = WIDGET_STATUS_NORMAL; + } } // Init. @@ -76,7 +292,7 @@ int toolkit_init(void) { windows = malloc(sizeof(Window)*MIN_WINDOWS); nwindows = 0; mwindows = MIN_WINDOWS; - + SDL_ShowCursor(SDL_DISABLE); return 0; } @@ -84,7 +300,7 @@ int toolkit_init(void) { void toolkit_exit(void) { int i; for(i = 0; i < nwindows; i++) { - window_destroy(windows[i]->id); + window_destroy(windows[i].id); free(windows); } } diff --git a/src/toolkit.h b/src/toolkit.h index ba55485..8b98af0 100644 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -1,17 +1,25 @@ #pragma once #include "opengl.h" +#include "SDL.h" extern int toolkit; // Creation. -unsigned int window_create(int x, int y, int w, int h, gl_texture* t); +unsigned int window_create(const int x, const int y, const int w, const int h); + +void window_addButton(const unsigned int wid, const int x, const int y, + const int w, const int h, char* name, char* display, + void(*call)(char*)); // Destroy window. -void window_destroy(unsigned int wid); +void window_destroy(const unsigned int wid); // Render. void toolkit_render(void); +// Input. +void toolkit_mouseEvent(SDL_Event* event); + // Init/Exit. int toolkit_init(void); void toolkit_exit(void); diff --git a/src/xml.h b/src/xml.h index 1d918f9..36e89aa 100644 --- a/src/xml.h +++ b/src/xml.h @@ -12,7 +12,7 @@ // Get the property s of node n. This mallocs. #define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s) -#define xml_get(n) (char*)(n)->children->content -#define xml_getInt(n) atoi((char*)(n)->children->content) -#define xml_getFloat(n) atof((char*)(n)->children->content) +#define xml_get(n) ((char*)(n)->children->content) +#define xml_getInt(n) (atoi((char*)(n)->children->content)) +#define xml_getFloat(n) (atof((char*)(n)->children->content))