Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL_DragEvent: Add SDL_DragEvents #13

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion include/SDL_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ typedef enum
/* Pan events */
SDL_PANEVENT = 0x2100,

/* Drag events */
SDL_DRAGFILE = 0x2200,
SDL_DRAGTEXT,
SDL_DRAGBEGIN,
SDL_DRAGCOMPLETE,

/** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use,
* and should be allocated with SDL_RegisterEvents()
*/
Expand Down Expand Up @@ -533,6 +539,16 @@ typedef struct SDL_DropEvent
} SDL_DropEvent;


typedef struct SDL_DragEvent
{
Uint32 type;
Uint32 timestamp;
char *file;
Uint32 windowID;
Sint32 x;
Sint32 y;
} SDL_DragEvent;

/**
* \brief Sensor event structure (event.sensor.*)
*/
Expand Down Expand Up @@ -624,7 +640,7 @@ typedef union SDL_Event
SDL_MultiGestureEvent mgesture; /**< Gesture event data */
SDL_DollarGestureEvent dgesture; /**< Gesture event data */
SDL_DropEvent drop; /**< Drag and drop event data */

SDL_DragEvent drag;
SDL_PanEvent pan; /**< Obsolesces mouse wheel events */

/* This is necessary for ABI compatibility between Visual C++ and GCC
Expand Down
64 changes: 64 additions & 0 deletions src/events/SDL_dragevents.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "../SDL_internal.h"

#include "SDL_events.h"
#include "SDL_events_c.h"
#include "SDL_dragevents_c.h"

#include "../video/SDL_sysvideo.h" /* for SDL_Window internals. */

const int
SDL_SendDrag(SDL_Window *window, const SDL_EventType evtype, const char *data, int x, int y)
zbaylin marked this conversation as resolved.
Show resolved Hide resolved
{
static SDL_bool app_is_dragging = SDL_FALSE;
int posted = 0;

const SDL_bool need_begin = window ? !window->is_dragging : !app_is_dragging;
SDL_Event event;

if (need_begin) {
SDL_zero(event);
event.type = SDL_DRAGBEGIN;
event.drag.x = x;
event.drag.y = y;

if (window) {
event.drag.windowID = window->id;
}

posted = (SDL_PushEvent(&event) > 0);
if (!posted) {
return 0;
}
Comment on lines +28 to +31
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment seems unnecessary, and a bit confusing. I'd expect posted to be read from again later, but it isn't. So it would be simpler to just check the result directly I think:

Suggested change
posted = (SDL_PushEvent(&event) > 0);
if (!posted) {
return 0;
}
if (SDL_PushEvent(&event) == 0) {
return 0;
}

if (window) {
window->is_dragging = SDL_TRUE;
} else {
app_is_dragging = SDL_TRUE;
}
}

SDL_zero(event);
event.type = evtype;
event.drag.file = data ? SDL_strdup(data) : NULL;
event.drag.windowID = window ? window->id : 0;
event.drag.x = x;
event.drag.y = y;
posted = (SDL_PushEvent(&event) > 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

posted is an ambiguous name. It's not immediately obvious whether it refers to a boolean or a count of items posted, for example. Therefore I prefer using isPosted for booleans.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. All the variable names I used I either borrowed from other functions (see SDL_dropevents.c) or modeled them closely after others. In this case it doesn't matter because I can remove the posted reference altogether though!


if (posted && (evtype == SDL_DRAGCOMPLETE)) {
if (window) {
window->is_dragging = SDL_FALSE;
} else {
app_is_dragging = SDL_FALSE;
}
}
return posted;
}

int SDL_SendDragFile(SDL_Window *window, const char *file, int x, int y)
{
return SDL_SendDrag(window, SDL_DRAGFILE, file, x, y);
}

int SDL_SendDragComplete(SDL_Window *window, int x, int y) {
return SDL_SendDrag(window, SDL_DRAGCOMPLETE, NULL, x, y);
}
8 changes: 8 additions & 0 deletions src/events/SDL_dragevents_c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "../SDL_internal.h"

#ifndef SDL_dragevents_c_h_
#define SDL_dragevents_c_h_

extern int SDL_SendDragFile(SDL_Window *window, const char *file, int x, int y);
extern int SDL_SendDragComplete(SDL_Window *window, int x, int y);
#endif
1 change: 1 addition & 0 deletions src/events/SDL_events_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include "SDL_clipboardevents_c.h"
#include "SDL_displayevents_c.h"
#include "SDL_dragevents_c.h"
#include "SDL_dropevents_c.h"
#include "SDL_gesture_c.h"
#include "SDL_keyboard_c.h"
Expand Down
5 changes: 3 additions & 2 deletions src/video/SDL_sysvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ struct SDL_Window
SDL_bool is_hiding;
SDL_bool is_destroying;
SDL_bool is_dropping; /* drag/drop in progress, expecting SDL_SendDropComplete(). */
SDL_bool is_dragging;

SDL_WindowShaper *shaper;

Expand Down Expand Up @@ -380,11 +381,11 @@ struct SDL_VideoDevice
/* Data private to this driver */
void *driverdata;
struct SDL_GLDriverData *gl_data;

#if SDL_VIDEO_OPENGL_EGL
struct SDL_EGL_VideoData *egl_data;
#endif

#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
struct SDL_PrivateGLESData *gles_data;
#endif
Expand Down
66 changes: 59 additions & 7 deletions src/video/cocoa/SDL_cocoawindow.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
#include "../../events/SDL_windowevents_c.h"
#include "../../events/SDL_dragevents_c.h"
#include "../../events/SDL_dropevents_c.h"
#include "SDL_cocoavideo.h"
#include "SDL_cocoashape.h"
Expand Down Expand Up @@ -139,6 +140,57 @@ - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
return NSDragOperationNone; /* no idea what to do with this, reject it. */
}

- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
{
NSPasteboard *pasteboard = [sender draggingPasteboard];
NSArray *types = [NSArray arrayWithObject:NSFilenamesPboardType];
NSString *desiredType = [pasteboard availableTypeFromArray:types];
SDL_Window *sdlwindow = [self findSDLWindow];
NSPoint point = [sender draggingLocation];

if (desiredType == nil) {
return NSDragOperationNone;
}

NSData *data = [pasteboard dataForType:desiredType];
if (data == nil) {
return NSDragOperationNone;
}

SDL_assert([desiredType isEqualToString:NSFilenamesPboardType]);
NSArray *array = [pasteboard propertyListForType:@"NSFilenamesPboardType"];

for (NSString *path in array) {
NSURL *fileURL = [NSURL fileURLWithPath:path];
NSNumber *isAlias = nil;

[fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];

if ([isAlias boolValue]) {
NSURLBookmarkResolutionOptions opts = NSURLBookmarkResolutionWithoutMounting | NSURLBookmarkResolutionWithoutUI;
NSData *bookmark = [NSURL bookmarkDataWithContentsOfURL:fileURL error:nil];
if (bookmark != nil) {
NSURL *resolvedURL = [NSURL URLByResolvingBookmarkData:bookmark
options:opts
relativeToURL:nil
bookmarkDataIsStale:nil
error:nil];

if (resolvedURL != nil) {
fileURL = resolvedURL;
}
}
}

if (!SDL_SendDragFile(sdlwindow, [[fileURL path] UTF8String], point.x, point.y)) {
return NSDragOperationNone;
}
}

SDL_SendDragComplete(sdlwindow, point.x, point.y);
return NSDragOperationGeneric;
}

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{ @autoreleasepool
{
Expand Down Expand Up @@ -711,7 +763,7 @@ - (void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification

isFullscreenSpace = NO;
inFullscreenTransition = NO;

[self windowDidExitFullScreen:nil];
}

Expand All @@ -727,7 +779,7 @@ - (void)windowDidEnterFullScreen:(NSNotification *)aNotification
pendingWindowOperation = PENDING_OPERATION_NONE;
[self setFullscreenSpace:NO];
} else {
/* Unset the resizable flag.
/* Unset the resizable flag.
This is a workaround for https://bugzilla.libsdl.org/show_bug.cgi?id=3697
*/
SetWindowStyle(window, [nswindow styleMask] & (~NSWindowStyleMaskResizable));
Expand Down Expand Up @@ -763,16 +815,16 @@ - (void)windowWillExitFullScreen:(NSNotification *)aNotification
- (void)windowDidFailToExitFullScreen:(NSNotification *)aNotification
{
SDL_Window *window = _data->window;

zbaylin marked this conversation as resolved.
Show resolved Hide resolved
if (window->is_destroying) {
return;
}

SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable));

isFullscreenSpace = YES;
inFullscreenTransition = NO;

[self windowDidEnterFullScreen:nil];
}

Expand Down Expand Up @@ -1474,7 +1526,7 @@ - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
if (!(window->flags & SDL_WINDOW_OPENGL)) {
return 0;
}

/* The rest of this macro mess is for OpenGL or OpenGL ES windows */
#if SDL_VIDEO_OPENGL_ES2
if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
Expand Down Expand Up @@ -1894,7 +1946,7 @@ - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent

NSArray *contexts = [[data->nscontexts copy] autorelease];
for (SDLOpenGLContext *context in contexts) {
/* Calling setWindow:NULL causes the context to remove itself from the context list. */
/* Calling setWindow:NULL causes the context to remove itself from the context list. */
[context setWindow:NULL];
}
[data->nscontexts release];
Expand Down