From f5d5441fd2e2362e031eb445cd0e389b79ad60ab Mon Sep 17 00:00:00 2001 From: Allanis Date: Sun, 10 Mar 2013 15:07:30 +0000 Subject: [PATCH] [Add] More control with mouse events on custom widgets, you can drag map and also select planets. --- src/map.c | 64 +++++++++++++++++++++++++++++++++++++++++++-------- src/toolkit.c | 23 +++++++++++------- src/toolkit.h | 2 +- 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/map.c b/src/map.c index 9e3d3d5..6c2af33 100644 --- a/src/map.c +++ b/src/map.c @@ -5,17 +5,22 @@ #include "opengl.h" #include "map.h" -#define MAP_WIDTH 550 -#define MAP_HEIGHT 400 +#define WINDOW_WIDTH 550 +#define WINDOW_HEIGHT 400 -#define BUTTON_WIDTH 60 -#define BUTTON_HEIGHT 40 +#define MAP_WIDTH (WINDOW_WIDTH-150) +#define MAP_HEIGHT (WINDOW_HEIGHT-60) + +#define BUTTON_WIDTH 60 +#define BUTTON_HEIGHT 40 static int map_wid = 0; static double map_xpos = 0.; static double map_ypos = 0.; static int map_selected = 0; +static int map_drag = 0; // Is the user dragging the map? + // Extern. extern StarSystem* systems_stack; extern int systems_nstack; @@ -23,7 +28,7 @@ extern int systems_nstack; static void map_close(char* str); static void map_update(void); static void map_render(double bx, double by, double w, double h); -static void map_mouse(Uint8 type, double mx, double my); +static void map_mouse(SDL_Event* event, double mx, double my); // Open the map window. void map_open(void) { @@ -33,7 +38,7 @@ void map_open(void) { map_xpos = cur_system->pos.x; map_ypos = cur_system->pos.y; - map_wid = window_create("Star Map", -1, -1, MAP_WIDTH, MAP_HEIGHT); + map_wid = window_create("Star Map", -1, -1, WINDOW_WIDTH, WINDOW_HEIGHT); window_addText(map_wid, -20, -20, 100, 20, 1, "txtSysname", &gl_defFont, &cDConsole, systems_stack[map_selected].name); @@ -50,7 +55,7 @@ void map_open(void) { window_addText(map_wid, -20, -110-gl_smallFont.h-5, 80, 100, 0, "txtPlanets", &gl_smallFont, &cBlack, NULL); - window_addCust(map_wid, 20, 20, MAP_WIDTH - 150, MAP_HEIGHT - 60, + window_addCust(map_wid, 20, 20, MAP_WIDTH, MAP_HEIGHT, "cstMap", 1, map_render, map_mouse); window_addButton(map_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, @@ -128,7 +133,8 @@ static void map_render(double bx, double by, double w, double h) { glVertex2d(bx+w, by); glEnd(); - COLOUR(cYellow); + //COLOUR(cYellow); + // Render the star systems. for(i = 0; i < systems_nstack; i++) { if(&systems_stack[i] == cur_system) COLOUR(cRadar_targ); else COLOUR(cYellow); @@ -143,7 +149,47 @@ static void map_render(double bx, double by, double w, double h) { } // Map event handling. -static void map_mouse(Uint8 type, double mx, double my) { +static void map_mouse(SDL_Event* event, double mx, double my) { + int i; + double x, y, t; + t = 13.*13.; // Threshold. + + mx -= MAP_WIDTH/2 - map_xpos; + my -= MAP_HEIGHT/2 - map_ypos; + + switch(event->type) { + case SDL_MOUSEBUTTONDOWN: + // Selecting star system. + if(event->button.button == SDL_BUTTON_LEFT) { + for(i = 0; i < systems_nstack; i++) { + x = systems_stack[i].pos.x; + y = systems_stack[i].pos.y; + + if((pow2(mx-x)+pow2(my-y)) < t) { + map_selected = i; + map_update(); + break; + } + } + } + // Start dragging. + else if(event->button.button == SDL_BUTTON_RIGHT) + map_drag = 1; + break; + + case SDL_MOUSEBUTTONUP: + if((event->button.button == SDL_BUTTON_RIGHT) && map_drag) + map_drag = 0; + break; + + case SDL_MOUSEMOTION: + if(map_drag) { + // Axis is inverted. + map_xpos -= event->motion.xrel; + map_ypos += event->motion.yrel; + } + break; + } } diff --git a/src/toolkit.c b/src/toolkit.c index 08afb14..bbfc5fb 100644 --- a/src/toolkit.c +++ b/src/toolkit.c @@ -66,7 +66,7 @@ typedef struct Widget_ { struct { int border; void(*render) (double bx, double by, double bw, double bh); - void(*mouse) (Uint8 type, double bx, double by); + void(*mouse) (SDL_Event* event, double bx, double by); } cst; } dat; } Widget; @@ -251,7 +251,7 @@ void window_addRect(const unsigned int wid, const int x, const int y, void window_addCust(const unsigned int wid, const int x, const int y, const int w, const int h, char* name, const int border, void(*render) (double x, double y, double w, double h), - void(*mouse) (Uint8 type, double x, double y)) { + void(*mouse) (SDL_Event* event, double x, double y)) { Window* wdw = window_wget(wid); Widget* wgt = window_newWidget(wdw); @@ -885,8 +885,6 @@ static void toolkit_mouseEvent(SDL_Event* event) { // 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) { @@ -900,7 +898,9 @@ static void toolkit_mouseEvent(SDL_Event* event) { w = &windows[nwindows-1]; - if((x < w->x) || (x > (w->x + w->w)) || (y < w->y) || (y > (w->y + w->h))) + // Always treat button ups to stop hanging states. + if((event->type != SDL_MOUSEBUTTONUP) && + ((x < w->x) || (x > (w->x + w->w)) || (y < w->y) || (y > (w->y + w->h)))) return; // Not in current window. // Relative positions. @@ -909,14 +909,17 @@ static void toolkit_mouseEvent(SDL_Event* event) { for(i = 0; i < w->nwidgets; i++) { wgt = &w->widgets[i]; + // Widget in range? if((x > wgt->x) && (x < (wgt->x + wgt->w)) && (y > wgt->y) && (y < (wgt->y + wgt->h))) { + // Custom widgets take it from here. if((wgt->type == WIDGET_CUST) && wgt->dat.cst.mouse) - (*wgt->dat.cst.mouse)(event->type, x-wgt->x, y-wgt->y); + (*wgt->dat.cst.mouse)(event, x-wgt->x, y-wgt->y); else switch(event->type) { case SDL_MOUSEMOTION: - wgt->status = WIDGET_STATUS_MOUSEOVER; + if(!mouse_down) + wgt->status = WIDGET_STATUS_MOUSEOVER; break; case SDL_MOUSEBUTTONDOWN: wgt->status = WIDGET_STATUS_MOUSEDOWN; @@ -941,7 +944,11 @@ static void toolkit_mouseEvent(SDL_Event* event) { wgt->status = WIDGET_STATUS_NORMAL; break; } - } else + } + else if((wgt->type == WIDGET_CUST) && + (event->type == SDL_MOUSEBUTTONUP) && wgt->dat.cst.mouse) + (*wgt->dat.cst.mouse) (event, x-wgt->x, y-wgt->y); + else if(!mouse_down) wgt->status = WIDGET_STATUS_NORMAL; } } diff --git a/src/toolkit.h b/src/toolkit.h index 1b274ba..f511563 100644 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -36,7 +36,7 @@ void window_addCust(const unsigned int wid, const int w, const int h, // Size. char* name, const int border, void(*render) (double x, double y, double w, double h), - void(*mouse) (Uint8 type, double x, double y)); + void(*mouse) (SDL_Event* event, double x, double y)); // Popups and alerts. void toolkit_alert(const char* fmt, ...);