[Add] More control with mouse events on custom widgets, you can drag map and also select planets.

This commit is contained in:
Allanis 2013-03-10 15:07:30 +00:00
parent 43a1bb019f
commit f5d5441fd2
3 changed files with 71 additions and 18 deletions

View File

@ -5,8 +5,11 @@
#include "opengl.h"
#include "map.h"
#define MAP_WIDTH 550
#define MAP_HEIGHT 400
#define WINDOW_WIDTH 550
#define WINDOW_HEIGHT 400
#define MAP_WIDTH (WINDOW_WIDTH-150)
#define MAP_HEIGHT (WINDOW_HEIGHT-60)
#define BUTTON_WIDTH 60
#define BUTTON_HEIGHT 40
@ -16,6 +19,8 @@ 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;
}
}

View File

@ -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,13 +909,16 @@ 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:
if(!mouse_down)
wgt->status = WIDGET_STATUS_MOUSEOVER;
break;
case SDL_MOUSEBUTTONDOWN:
@ -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;
}
}

View File

@ -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, ...);