mirror of https://github.com/encounter/SDL.git
Added support for double-clicks, through a new "clicks" field in the mouse button event.
This commit is contained in:
parent
3666c1f7ca
commit
746928350f
|
@ -239,8 +239,8 @@ typedef struct SDL_MouseButtonEvent
|
|||
Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
|
||||
Uint8 button; /**< The mouse button index */
|
||||
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
|
||||
Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */
|
||||
Uint8 padding1;
|
||||
Uint8 padding2;
|
||||
Sint32 x; /**< X coordinate, relative to window */
|
||||
Sint32 y; /**< Y coordinate, relative to window */
|
||||
} SDL_MouseButtonEvent;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
/* General mouse handling code for SDL */
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_events_c.h"
|
||||
#include "default_cursor.h"
|
||||
|
@ -32,6 +33,8 @@
|
|||
|
||||
/* The mouse state */
|
||||
static SDL_Mouse SDL_mouse;
|
||||
static Uint32 SDL_double_click_time = 500;
|
||||
static int SDL_double_click_radius = 1;
|
||||
|
||||
static int
|
||||
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
|
||||
|
@ -64,6 +67,12 @@ SDL_GetMouse(void)
|
|||
return &SDL_mouse;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SetDoubleClickTime(Uint32 interval)
|
||||
{
|
||||
SDL_double_click_time = interval;
|
||||
}
|
||||
|
||||
SDL_Window *
|
||||
SDL_GetMouseFocus(void)
|
||||
{
|
||||
|
@ -272,6 +281,23 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
|
|||
return posted;
|
||||
}
|
||||
|
||||
static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button)
|
||||
{
|
||||
if (button >= mouse->num_clickstates) {
|
||||
int i, count = button + 1;
|
||||
mouse->clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate));
|
||||
if (!mouse->clickstate) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = mouse->num_clickstates; i < count; ++i) {
|
||||
SDL_zero(mouse->clickstate[i]);
|
||||
}
|
||||
mouse->num_clickstates = count;
|
||||
}
|
||||
return &mouse->clickstate[button];
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
|
||||
{
|
||||
|
@ -279,6 +305,8 @@ SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8
|
|||
int posted;
|
||||
Uint32 type;
|
||||
Uint32 buttonstate = mouse->buttonstate;
|
||||
SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
|
||||
Uint8 click_count;
|
||||
|
||||
/* Figure out which event to perform */
|
||||
switch (state) {
|
||||
|
@ -306,6 +334,27 @@ SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8
|
|||
}
|
||||
mouse->buttonstate = buttonstate;
|
||||
|
||||
if (clickstate) {
|
||||
if (state == SDL_PRESSED) {
|
||||
Uint32 now = SDL_GetTicks();
|
||||
|
||||
if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) ||
|
||||
SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius ||
|
||||
SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) {
|
||||
clickstate->click_count = 0;
|
||||
}
|
||||
clickstate->last_timestamp = now;
|
||||
clickstate->last_x = mouse->x;
|
||||
clickstate->last_y = mouse->y;
|
||||
if (clickstate->click_count < 255) {
|
||||
++clickstate->click_count;
|
||||
}
|
||||
}
|
||||
click_count = clickstate->click_count;
|
||||
} else {
|
||||
click_count = 1;
|
||||
}
|
||||
|
||||
/* Post the event, if desired */
|
||||
posted = 0;
|
||||
if (SDL_GetEventState(type) == SDL_ENABLE) {
|
||||
|
@ -315,6 +364,7 @@ SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8
|
|||
event.button.which = mouseID;
|
||||
event.button.state = state;
|
||||
event.button.button = button;
|
||||
event.button.clicks = click_count;
|
||||
event.button.x = mouse->x;
|
||||
event.button.y = mouse->y;
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
|
@ -376,6 +426,10 @@ SDL_MouseQuit(void)
|
|||
mouse->FreeCursor(mouse->def_cursor);
|
||||
}
|
||||
|
||||
if (mouse->clickstate) {
|
||||
SDL_free(mouse->clickstate);
|
||||
}
|
||||
|
||||
SDL_zerop(mouse);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,13 @@ struct SDL_Cursor
|
|||
void *driverdata;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int last_x, last_y;
|
||||
Uint32 last_timestamp;
|
||||
Uint8 click_count;
|
||||
} SDL_MouseClickState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Create a cursor from a surface */
|
||||
|
@ -69,6 +76,10 @@ typedef struct
|
|||
/* the x and y coordinates when relative mode was activated */
|
||||
int original_x, original_y;
|
||||
|
||||
/* Data for double-click tracking */
|
||||
int num_clickstates;
|
||||
SDL_MouseClickState *clickstate;
|
||||
|
||||
SDL_Cursor *cursors;
|
||||
SDL_Cursor *def_cursor;
|
||||
SDL_Cursor *cur_cursor;
|
||||
|
@ -85,6 +96,9 @@ extern int SDL_MouseInit(void);
|
|||
/* Get the mouse state structure */
|
||||
SDL_Mouse *SDL_GetMouse(void);
|
||||
|
||||
/* Set the default double-click interval */
|
||||
extern void SDL_SetDoubleClickTime(Uint32 interval);
|
||||
|
||||
/* Set the default mouse cursor */
|
||||
extern void SDL_SetDefaultCursor(SDL_Cursor * cursor);
|
||||
|
||||
|
|
|
@ -1042,13 +1042,13 @@ SDLTest_PrintEvent(SDL_Event * event)
|
|||
event->motion.windowID);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
fprintf(stderr, "Mouse: button %d pressed at %d,%d in window %d",
|
||||
event->button.button, event->button.x, event->button.y,
|
||||
fprintf(stderr, "Mouse: button %d pressed at %d,%d with click count %d in window %d",
|
||||
event->button.button, event->button.x, event->button.y, event->button.clicks,
|
||||
event->button.windowID);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
fprintf(stderr, "Mouse: button %d released at %d,%d in window %d",
|
||||
event->button.button, event->button.x, event->button.y,
|
||||
fprintf(stderr, "Mouse: button %d released at %d,%d with click count %d in window %d",
|
||||
event->button.button, event->button.x, event->button.y, event->button.clicks,
|
||||
event->button.windowID);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
|
|
|
@ -250,6 +250,8 @@ WIN_InitMouse(_THIS)
|
|||
mouse->SetRelativeMouseMode = WIN_SetRelativeMouseMode;
|
||||
|
||||
SDL_SetDefaultCursor(WIN_CreateDefaultCursor());
|
||||
|
||||
SDL_SetDoubleClickTime(GetDoubleClickTime());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue