Skip to content

Commit

Permalink
MacOS drag and drop support
Browse files Browse the repository at this point in the history
  • Loading branch information
djowel committed Oct 10, 2023
1 parent ef47082 commit 1d85cf8
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
56 changes: 56 additions & 0 deletions lib/host/macos/base_view.mm
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ @interface ELEMENTS_VIEW_CLASS : NSView <NSTextInputClient>

bool _text_inserted;
}

@end

@compatibility_alias ElementsView ELEMENTS_VIEW_CLASS;
Expand Down Expand Up @@ -251,6 +252,8 @@ - (void) elements_init : (ph::base_view*) view_

[self setPostsBoundsChangedNotifications : YES];
_text_inserted = false;

[self registerForDraggedTypes:@[NSPasteboardTypeURL]];
}

- (void) dealloc
Expand Down Expand Up @@ -668,6 +671,59 @@ -(void) windowDidResignKey : (NSNotification*) notification
_view->end_focus();
}

-(void) makeDropInfo : (id <NSDraggingInfo>) sender : (ph::drop_info*) info
{
auto pos = [sender draggingLocation];
pos = [self convertPoint : pos fromView : nil];

NSPasteboard* pasteboard = [sender draggingPasteboard];
NSDictionary* options = @{NSPasteboardURLReadingFileURLsOnlyKey:@YES};
NSArray* urls = [pasteboard readObjectsForClasses:@[[NSURL class]]
options:options];
const NSUInteger count = [urls count];
if (count)
{
info->where = ph::point{ float(pos.x), float(pos.y) };
for (NSUInteger i = 0; i < count; ++i)
info->paths.push_back([urls[i] fileSystemRepresentation]);
}
}

- (BOOL)performDragOperation : (id <NSDraggingInfo>) sender
{
ph::drop_info info;
[self makeDropInfo : sender : &info];
if (info.paths.size())
{
if (_view->drop(info))
return YES;
}
return NO;
}

- (BOOL)wantsPeriodicDraggingUpdates
{
return YES;
}

- (NSDragOperation)draggingEntered : (id <NSDraggingInfo>) sender
{
ph::drop_info info;
[self makeDropInfo : sender : &info];
if (info.paths.size())
_view->track_drop(info);
return NSDragOperationGeneric;
}

- (NSDragOperation)draggingUpdated : (id<NSDraggingInfo>) sender
{
ph::drop_info info;
[self makeDropInfo : sender : &info];
if (info.paths.size())
_view->track_drop(info);
return NSDragOperationGeneric;
}

@end // @implementation ElementsView

namespace cycfi { namespace elements
Expand Down
13 changes: 13 additions & 0 deletions lib/include/elements/base_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,12 @@ namespace cycfi { namespace elements
int modifiers;
};

struct drop_info
{
std::vector<fs::path> paths;
point where;
};

////////////////////////////////////////////////////////////////////////////
// The base view base class
////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -315,6 +321,8 @@ namespace cycfi { namespace elements
virtual bool text(text_info const& info);
virtual void begin_focus();
virtual void end_focus();
virtual void track_drop(drop_info const& info);
virtual bool drop(drop_info const& info);
virtual void poll();

virtual void refresh();
Expand All @@ -341,6 +349,11 @@ namespace cycfi { namespace elements
inline bool base_view::text(text_info const& /* info */) { return false; }
inline void base_view::begin_focus() {}
inline void base_view::end_focus() {}
inline void base_view::track_drop(drop_info const& /*info*/) {}
inline bool base_view::drop(drop_info const& /*info*/)
{
return false;
}
inline void base_view::poll() {}

////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 1d85cf8

Please # to comment.