diff --git a/modules/juce_gui_basics/native/juce_mac_Windowing.mm b/modules/juce_gui_basics/native/juce_mac_Windowing.mm index aaa892da6c..f04b323614 100644 --- a/modules/juce_gui_basics/native/juce_mac_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_mac_Windowing.mm @@ -266,25 +266,9 @@ static NSView* getNSViewForDragEvent (Component* sourceComp) return nil; } -struct NSDraggingSourceHelper : public ObjCClass> +class NSDraggingSourceHelper : public ObjCClass> { - NSDraggingSourceHelper() : ObjCClass> ("JUCENSDraggingSourceHelper_") - { - addIvar*> ("callback"); - addIvar ("text"); - addIvar ("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> object_setInstanceVariable (self, "operation", new NSDragOperation (op)); } -private: - static void dealloc (id self, SEL) + static NSDraggingSourceHelper& get() { - delete getIvar (self, "text"); - delete getIvar*> (self, "callback"); - delete getIvar (self, "operation"); - - sendSuperclassMessage (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 (self, "text")) - [sender setData: [juceStringToNS (*text) dataUsingEncoding: NSUTF8StringEncoding] - forType: NSPasteboardTypeString]; - } + addIvar*> ("callback"); + addIvar ("text"); + addIvar ("operation"); - static NSDragOperation sourceOperationMaskForDraggingContext (id self, SEL, NSDraggingSession*, NSDraggingContext) - { - return *getIvar (self, "operation"); - } + addMethod (@selector (dealloc), [] (id self, SEL) + { + delete getIvar (self, "text"); + delete getIvar*> (self, "callback"); + delete getIvar (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*> (self, "callback")) - cb->operator()(); + sendSuperclassMessage (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 (self, "text")) + [sender setData: [juceStringToNS (*text) dataUsingEncoding: NSUTF8StringEncoding] + forType: NSPasteboardTypeString]; + }); + + addMethod (@selector (draggingSession:sourceOperationMaskForDraggingContext:), [] (id self, SEL, NSDraggingSession*, NSDraggingContext) + { + return *getIvar (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*> (self, "callback")) + cb->operator()(); + }); + + addProtocol (@protocol (NSPasteboardItemDataProvider)); + + registerClass(); } }; -static NSDraggingSourceHelper draggingSourceHelper; - bool DragAndDropContainer::performExternalDragDropOfText (const String& text, Component* sourceComponent, std::function 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);