Add Drag and drop position, for x11, wayland and MACOSX
parent
813c586edb
commit
a946a34452
|
@ -172,6 +172,7 @@ typedef enum
|
|||
SDL_EVENT_DROP_TEXT, /**< text/plain drag-and-drop event */
|
||||
SDL_EVENT_DROP_BEGIN, /**< A new set of drops is beginning (NULL filename) */
|
||||
SDL_EVENT_DROP_COMPLETE, /**< Current set of drops is now complete (NULL filename) */
|
||||
SDL_EVENT_DROP_POSITION, /**< Position while moving over the window */
|
||||
|
||||
/* Audio hotplug events */
|
||||
SDL_EVENT_AUDIO_DEVICE_ADDED = 0x1100, /**< A new audio device is available */
|
||||
|
@ -515,10 +516,12 @@ typedef struct SDL_TouchFingerEvent
|
|||
*/
|
||||
typedef struct SDL_DropEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_DROP_BEGIN or ::SDL_EVENT_DROP_FILE or ::SDL_EVENT_DROP_TEXT or ::SDL_EVENT_DROP_COMPLETE */
|
||||
Uint32 type; /**< ::SDL_EVENT_DROP_BEGIN or ::SDL_EVENT_DROP_FILE or ::SDL_EVENT_DROP_TEXT or ::SDL_EVENT_DROP_COMPLETE or ::SDL_EVENT_DROP_POSITION */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */
|
||||
SDL_WindowID windowID;/**< The window that was dropped on, if any */
|
||||
SDL_WindowID windowID; /**< The window that was dropped on, if any */
|
||||
float x; /**< X coordinate, relative to window (not on begin) */
|
||||
float y; /**< Y coordinate, relative to window (not on begin) */
|
||||
} SDL_DropEvent;
|
||||
|
||||
|
||||
|
|
|
@ -27,9 +27,11 @@
|
|||
|
||||
#include "../video/SDL_sysvideo.h" /* for SDL_Window internals. */
|
||||
|
||||
static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data)
|
||||
static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data, float x, float y)
|
||||
{
|
||||
static SDL_bool app_is_dropping = SDL_FALSE;
|
||||
static float last_drop_x = 0;
|
||||
static float last_drop_y = 0;
|
||||
int posted = 0;
|
||||
|
||||
/* Post the event, if desired */
|
||||
|
@ -58,6 +60,13 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
|
|||
event.common.timestamp = 0;
|
||||
event.drop.file = data ? SDL_strdup(data) : NULL;
|
||||
event.drop.windowID = window ? window->id : 0;
|
||||
|
||||
if (evtype == SDL_EVENT_DROP_POSITION) {
|
||||
last_drop_x = x;
|
||||
last_drop_y = y;
|
||||
}
|
||||
event.drop.x = last_drop_x;
|
||||
event.drop.y = last_drop_y;
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
|
||||
if (posted && (evtype == SDL_EVENT_DROP_COMPLETE)) {
|
||||
|
@ -66,6 +75,9 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
|
|||
} else {
|
||||
app_is_dropping = SDL_FALSE;
|
||||
}
|
||||
|
||||
last_drop_x = 0;
|
||||
last_drop_y = 0;
|
||||
}
|
||||
}
|
||||
return posted;
|
||||
|
@ -73,15 +85,21 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
|
|||
|
||||
int SDL_SendDropFile(SDL_Window *window, const char *file)
|
||||
{
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, file);
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, file, 0, 0);
|
||||
}
|
||||
|
||||
int SDL_SendDropPosition(SDL_Window *window, const char *file, float x, float y)
|
||||
{
|
||||
/* Don't send 'file' since this is an malloc per position, which may be forgotten to be freed */
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_POSITION, NULL, x, y);
|
||||
}
|
||||
|
||||
int SDL_SendDropText(SDL_Window *window, const char *text)
|
||||
{
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, text);
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, text, 0, 0);
|
||||
}
|
||||
|
||||
int SDL_SendDropComplete(SDL_Window *window)
|
||||
{
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL);
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL, 0, 0);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define SDL_dropevents_c_h_
|
||||
|
||||
extern int SDL_SendDropFile(SDL_Window *window, const char *file);
|
||||
extern int SDL_SendDropPosition(SDL_Window *window, const char *file, float x, float y);
|
||||
extern int SDL_SendDropText(SDL_Window *window, const char *text);
|
||||
extern int SDL_SendDropComplete(SDL_Window *window);
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
|
||||
/* Handle drag-and-drop of files onto the SDL window. */
|
||||
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender;
|
||||
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender;
|
||||
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender;
|
||||
- (BOOL)wantsPeriodicDraggingUpdates;
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
|
||||
|
@ -158,6 +159,21 @@
|
|||
return NSDragOperationNone; /* no idea what to do with this, reject it. */
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
if (([sender draggingSourceOperationMask] & NSDragOperationGeneric) == NSDragOperationGeneric) {
|
||||
SDL_Window *sdlwindow = [self findSDLWindow];
|
||||
NSPoint point = [sender draggingLocation];
|
||||
float x, y;
|
||||
x = point.x;
|
||||
y = (sdlwindow->h - point.y);
|
||||
SDL_SendDropPosition(sdlwindow, NULL, x, y); /* FIXME, should we get the filename */
|
||||
return NSDragOperationGeneric;
|
||||
}
|
||||
|
||||
return NSDragOperationNone; /* no idea what to do with this, reject it. */
|
||||
}
|
||||
|
||||
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
|
|
@ -96,6 +96,8 @@ struct SDL_WaylandTouchPointList
|
|||
|
||||
static struct SDL_WaylandTouchPointList touch_points = { NULL, NULL };
|
||||
|
||||
static char *Wayland_URIToLocal(char *uri);
|
||||
|
||||
static void touch_add(SDL_TouchID id, float x, float y, struct wl_surface *surface)
|
||||
{
|
||||
struct SDL_WaylandTouchPoint *tp = SDL_malloc(sizeof(struct SDL_WaylandTouchPoint));
|
||||
|
@ -1845,6 +1847,30 @@ static void data_device_handle_leave(void *data, struct wl_data_device *wl_data_
|
|||
static void data_device_handle_motion(void *data, struct wl_data_device *wl_data_device,
|
||||
uint32_t time, wl_fixed_t x, wl_fixed_t y)
|
||||
{
|
||||
SDL_WaylandDataDevice *data_device = data;
|
||||
|
||||
if (data_device->drag_offer != NULL) {
|
||||
/* TODO: SDL Support more mime types */
|
||||
size_t length;
|
||||
void *buffer = Wayland_data_offer_receive(data_device->drag_offer,
|
||||
&length, FILE_MIME, SDL_TRUE);
|
||||
if (buffer) {
|
||||
char *saveptr = NULL;
|
||||
char *token = SDL_strtokr((char *)buffer, "\r\n", &saveptr);
|
||||
while (token != NULL) {
|
||||
char *fn = Wayland_URIToLocal(token);
|
||||
if (fn) {
|
||||
double dx;
|
||||
double dy;
|
||||
dx = wl_fixed_to_double(x);
|
||||
dy = wl_fixed_to_double(y);
|
||||
SDL_SendDropPosition(data_device->dnd_window, fn, (float)dx, (float)dy);
|
||||
}
|
||||
token = SDL_strtokr(NULL, "\r\n", &saveptr);
|
||||
}
|
||||
SDL_free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Decodes URI escape sequences in string buf of len bytes
|
||||
|
|
|
@ -1222,6 +1222,18 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
|
|||
}
|
||||
printf("Action requested by user is : %s\n", X11_XGetAtomName(display, act));
|
||||
#endif
|
||||
{
|
||||
/* Drag and Drop position */
|
||||
int root_x, root_y, window_x, window_y;
|
||||
Window ChildReturn;
|
||||
root_x = xevent->xclient.data.l[2] >> 16;
|
||||
root_y = xevent->xclient.data.l[2] & 0xffff;
|
||||
/* Translate from root to current window position */
|
||||
X11_XTranslateCoordinates(display, DefaultRootWindow(display), data->xwindow,
|
||||
root_x, root_y, &window_x, &window_y, &ChildReturn);
|
||||
|
||||
SDL_SendDropPosition(data->window, NULL, (float)window_x, (float)window_y); /* FIXME, can we get the filename ? */
|
||||
}
|
||||
|
||||
/* reply with status */
|
||||
SDL_memset(&m, 0, sizeof(XClientMessageEvent));
|
||||
|
|
|
@ -29,6 +29,9 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
int i, done;
|
||||
SDL_Event event;
|
||||
SDL_bool is_hover = SDL_FALSE;
|
||||
float x = 0.0f, y = 0.0f;
|
||||
unsigned int windowID = 0;
|
||||
|
||||
/* Enable standard application logging */
|
||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||
|
@ -60,12 +63,6 @@ int main(int argc, char *argv[])
|
|||
quit(2);
|
||||
}
|
||||
|
||||
for (i = 0; i < state->num_windows; ++i) {
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
SDL_SetEventEnabled(SDL_EVENT_DROP_FILE, SDL_TRUE);
|
||||
|
||||
|
@ -75,19 +72,43 @@ int main(int argc, char *argv[])
|
|||
/* Check for events */
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_EVENT_DROP_BEGIN) {
|
||||
SDL_Log("Drop beginning on window %u", (unsigned int)event.drop.windowID);
|
||||
SDL_Log("Drop beginning on window %u at (%f, %f)", (unsigned int)event.drop.windowID, event.drop.x, event.drop.y);
|
||||
} else if (event.type == SDL_EVENT_DROP_COMPLETE) {
|
||||
SDL_Log("Drop complete on window %u", (unsigned int)event.drop.windowID);
|
||||
is_hover = SDL_FALSE;
|
||||
SDL_Log("Drop complete on window %u at (%f, %f)", (unsigned int)event.drop.windowID, event.drop.x, event.drop.y);
|
||||
} else if ((event.type == SDL_EVENT_DROP_FILE) || (event.type == SDL_EVENT_DROP_TEXT)) {
|
||||
const char *typestr = (event.type == SDL_EVENT_DROP_FILE) ? "File" : "Text";
|
||||
char *dropped_filedir = event.drop.file;
|
||||
SDL_Log("%s dropped on window %u: %s", typestr, (unsigned int)event.drop.windowID, dropped_filedir);
|
||||
SDL_Log("%s dropped on window %u: %s at (%f, %f)", typestr, (unsigned int)event.drop.windowID, dropped_filedir, event.drop.x, event.drop.y);
|
||||
/* Normally you'd have to do this, but this is freed in SDLTest_CommonEvent() */
|
||||
/*SDL_free(dropped_filedir);*/
|
||||
} else if (event.type == SDL_EVENT_DROP_POSITION) {
|
||||
is_hover = SDL_TRUE;
|
||||
x = event.drop.x;
|
||||
y = event.drop.y;
|
||||
windowID = event.drop.windowID;
|
||||
SDL_Log("Drop position on window %u at (%f, %f) file = %s", (unsigned int)event.drop.windowID, event.drop.x, event.drop.y, event.drop.file);
|
||||
}
|
||||
|
||||
SDLTest_CommonEvent(state, &event, &done);
|
||||
}
|
||||
|
||||
for (i = 0; i < state->num_windows; ++i) {
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
|
||||
SDL_RenderClear(renderer);
|
||||
if (is_hover) {
|
||||
if (windowID == SDL_GetWindowID(SDL_GetRenderWindow(renderer))) {
|
||||
int len = 2000;
|
||||
SDL_SetRenderDrawColor(renderer, 0x0A, 0x0A, 0x0A, 0xFF);
|
||||
SDL_RenderLine(renderer, x, y - len, x, y + len);
|
||||
SDL_RenderLine(renderer, x - len, y, x + len, y);
|
||||
}
|
||||
}
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
SDL_Delay(16);
|
||||
}
|
||||
|
||||
quit(0);
|
||||
|
|
Loading…
Reference in New Issue