Browse Source

Windowing: Tidy up macOS drag+drop implementation

v7.0.9
reuk 3 years ago
parent
commit
ac0ec5a7cc
No known key found for this signature in database GPG Key ID: FCB43929F012EE5C
1 changed files with 49 additions and 49 deletions
  1. +49
    -49
      modules/juce_gui_basics/native/juce_mac_Windowing.mm

+ 49
- 49
modules/juce_gui_basics/native/juce_mac_Windowing.mm View File

@@ -266,25 +266,9 @@ static NSView* getNSViewForDragEvent (Component* sourceComp)
return nil;
}
struct NSDraggingSourceHelper : public ObjCClass<NSObject<NSDraggingSource>>
class NSDraggingSourceHelper : public ObjCClass<NSObject<NSDraggingSource>>
{
NSDraggingSourceHelper() : ObjCClass<NSObject<NSDraggingSource>> ("JUCENSDraggingSourceHelper_")
{
addIvar<std::function<void()>*> ("callback");
addIvar<String*> ("text");
addIvar<NSDragOperation*> ("operation");
addMethod (@selector (dealloc), dealloc);
addMethod (@selector (pasteboard:item:provideDataForType:), provideDataForType);
addMethod (@selector (draggingSession:sourceOperationMaskForDraggingContext:), sourceOperationMaskForDraggingContext);
addMethod (@selector (draggingSession:endedAtPoint:operation:), draggingSessionEnded);
addProtocol (@protocol (NSPasteboardItemDataProvider));
registerClass();
}
public:
static void setText (id self, const String& text)
{
object_setInstanceVariable (self, "text", new String (text));
@@ -300,44 +284,60 @@ struct NSDraggingSourceHelper : public ObjCClass<NSObject<NSDraggingSource>>
object_setInstanceVariable (self, "operation", new NSDragOperation (op));
}
private:
static void dealloc (id self, SEL)
static NSDraggingSourceHelper& get()
{
delete getIvar<String*> (self, "text");
delete getIvar<std::function<void()>*> (self, "callback");
delete getIvar<NSDragOperation*> (self, "operation");
sendSuperclassMessage<void> (self, @selector (dealloc));
static NSDraggingSourceHelper draggingSourceHelper;
return draggingSourceHelper;
}
static void provideDataForType (id self, SEL, NSPasteboard* sender, NSPasteboardItem*, NSString* type)
private:
NSDraggingSourceHelper()
: ObjCClass ("JUCENSDraggingSourceHelper_")
{
if ([type compare: NSPasteboardTypeString] == NSOrderedSame)
if (auto* text = getIvar<String*> (self, "text"))
[sender setData: [juceStringToNS (*text) dataUsingEncoding: NSUTF8StringEncoding]
forType: NSPasteboardTypeString];
}
addIvar<std::function<void()>*> ("callback");
addIvar<String*> ("text");
addIvar<NSDragOperation*> ("operation");
static NSDragOperation sourceOperationMaskForDraggingContext (id self, SEL, NSDraggingSession*, NSDraggingContext)
{
return *getIvar<NSDragOperation*> (self, "operation");
}
addMethod (@selector (dealloc), [] (id self, SEL)
{
delete getIvar<String*> (self, "text");
delete getIvar<std::function<void()>*> (self, "callback");
delete getIvar<NSDragOperation*> (self, "operation");
static void draggingSessionEnded (id self, SEL, NSDraggingSession*, NSPoint p, NSDragOperation)
{
// Our view doesn't receive a mouse up when the drag ends so we need to generate one here and send it...
if (auto* view = getNSViewForDragEvent (nullptr))
if (auto* cgEvent = CGEventCreateMouseEvent (nullptr, kCGEventLeftMouseUp, CGPointMake (p.x, p.y), kCGMouseButtonLeft))
if (id e = [NSEvent eventWithCGEvent: cgEvent])
[view mouseUp: e];
if (auto* cb = getIvar<std::function<void()>*> (self, "callback"))
cb->operator()();
sendSuperclassMessage<void> (self, @selector (dealloc));
});
addMethod (@selector (pasteboard:item:provideDataForType:), [] (id self, SEL, NSPasteboard* sender, NSPasteboardItem*, NSString* type)
{
if ([type compare: NSPasteboardTypeString] == NSOrderedSame)
if (auto* text = getIvar<String*> (self, "text"))
[sender setData: [juceStringToNS (*text) dataUsingEncoding: NSUTF8StringEncoding]
forType: NSPasteboardTypeString];
});
addMethod (@selector (draggingSession:sourceOperationMaskForDraggingContext:), [] (id self, SEL, NSDraggingSession*, NSDraggingContext)
{
return *getIvar<NSDragOperation*> (self, "operation");
});
addMethod (@selector (draggingSession:endedAtPoint:operation:), [] (id self, SEL, NSDraggingSession*, NSPoint p, NSDragOperation)
{
// Our view doesn't receive a mouse up when the drag ends so we need to generate one here and send it...
if (auto* view = getNSViewForDragEvent (nullptr))
if (auto* cgEvent = CGEventCreateMouseEvent (nullptr, kCGEventLeftMouseUp, CGPointMake (p.x, p.y), kCGMouseButtonLeft))
if (id e = [NSEvent eventWithCGEvent: cgEvent])
[view mouseUp: e];
if (auto* cb = getIvar<std::function<void()>*> (self, "callback"))
cb->operator()();
});
addProtocol (@protocol (NSPasteboardItemDataProvider));
registerClass();
}
};
static NSDraggingSourceHelper draggingSourceHelper;
bool DragAndDropContainer::performExternalDragDropOfText (const String& text, Component* sourceComponent,
std::function<void()> callback)
{
@@ -350,7 +350,7 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text, Co
{
if (auto event = [[view window] currentEvent])
{
id helper = [draggingSourceHelper.createInstance() init];
id helper = [NSDraggingSourceHelper::get().createInstance() init];
NSDraggingSourceHelper::setText (helper, text);
NSDraggingSourceHelper::setDragOperation (helper, NSDragOperationCopy);
@@ -413,7 +413,7 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi
[dragItem release];
}
auto helper = [draggingSourceHelper.createInstance() autorelease];
auto helper = [NSDraggingSourceHelper::get().createInstance() autorelease];
if (callback != nullptr)
NSDraggingSourceHelper::setCompletionCallback (helper, callback);


Loading…
Cancel
Save