|
|
|
@@ -142,45 +142,113 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy |
|
|
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool /*canMoveFiles*/)
|
|
|
|
static NSRect getDragRect (NSView* view, NSEvent* event)
|
|
|
|
{
|
|
|
|
if (files.size() == 0)
|
|
|
|
return false;
|
|
|
|
auto eventPos = [event locationInWindow];
|
|
|
|
|
|
|
|
return [view convertRect: NSMakeRect (eventPos.x - 16.0f, eventPos.y - 16.0f, 32.0f, 32.0f)
|
|
|
|
fromView: nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0);
|
|
|
|
NSView* getNSViewForDragEvent()
|
|
|
|
{
|
|
|
|
if (auto* draggingSource = Desktop::getInstance().getDraggingMouseSource(0))
|
|
|
|
if (auto* sourceComp = draggingSource->getComponentUnderMouse())
|
|
|
|
return (NSView*) sourceComp->getWindowHandle();
|
|
|
|
|
|
|
|
jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event!
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (draggingSource == nullptr)
|
|
|
|
struct TextDragDataProviderClass : public ObjCClass<NSObject>
|
|
|
|
{
|
|
|
|
TextDragDataProviderClass() : ObjCClass<NSObject> ("JUCE_NSTextDragDataProvider_")
|
|
|
|
{
|
|
|
|
jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event!
|
|
|
|
return false;
|
|
|
|
addIvar<String*> ("text");
|
|
|
|
addMethod (@selector (dealloc), dealloc, "v@:");
|
|
|
|
addMethod (@selector (pasteboard:item:provideDataForType:), provideDataForType, "v@:@@@");
|
|
|
|
addProtocol (@protocol (NSPasteboardItemDataProvider));
|
|
|
|
registerClass();
|
|
|
|
}
|
|
|
|
|
|
|
|
Component* sourceComp = draggingSource->getComponentUnderMouse();
|
|
|
|
static void setText (id self, const String& text)
|
|
|
|
{
|
|
|
|
object_setInstanceVariable (self, "text", new String (text));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sourceComp == nullptr)
|
|
|
|
private:
|
|
|
|
static void dealloc (id self, SEL)
|
|
|
|
{
|
|
|
|
jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event!
|
|
|
|
delete getIvar<String*> (self, "text");
|
|
|
|
sendSuperclassMessage (self, @selector (dealloc));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void 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];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
|
|
|
|
{
|
|
|
|
if (text.isEmpty())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (auto* view = getNSViewForDragEvent())
|
|
|
|
{
|
|
|
|
JUCE_AUTORELEASEPOOL
|
|
|
|
{
|
|
|
|
if (auto* event = [[view window] currentEvent])
|
|
|
|
{
|
|
|
|
static TextDragDataProviderClass dataProviderClass;
|
|
|
|
id delegate = [dataProviderClass.createInstance() init];
|
|
|
|
TextDragDataProviderClass::setText (delegate, text);
|
|
|
|
|
|
|
|
auto* pasteboardItem = [[NSPasteboardItem new] autorelease];
|
|
|
|
[pasteboardItem setDataProvider: delegate
|
|
|
|
forTypes: [NSArray arrayWithObjects: NSPasteboardTypeString, nil]];
|
|
|
|
|
|
|
|
auto* dragItem = [[[NSDraggingItem alloc] initWithPasteboardWriter: pasteboardItem] autorelease];
|
|
|
|
|
|
|
|
NSImage* image = [[NSWorkspace sharedWorkspace] iconForFile: nsEmptyString()];
|
|
|
|
[dragItem setDraggingFrame: getDragRect (view, event) contents: image];
|
|
|
|
|
|
|
|
auto* draggingSession = [view beginDraggingSessionWithItems: [NSArray arrayWithObject: dragItem]
|
|
|
|
event: event
|
|
|
|
source: delegate];
|
|
|
|
|
|
|
|
draggingSession.animatesToStartingPositionsOnCancelOrFail = YES;
|
|
|
|
draggingSession.draggingFormation = NSDraggingFormationNone;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
JUCE_AUTORELEASEPOOL
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, bool /*canMoveFiles*/)
|
|
|
|
{
|
|
|
|
if (files.isEmpty())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (auto* view = getNSViewForDragEvent())
|
|
|
|
{
|
|
|
|
if (NSView* view = (NSView*) sourceComp->getWindowHandle())
|
|
|
|
JUCE_AUTORELEASEPOOL
|
|
|
|
{
|
|
|
|
if (NSEvent* event = [[view window] currentEvent])
|
|
|
|
if (auto* event = [[view window] currentEvent])
|
|
|
|
{
|
|
|
|
NSPoint eventPos = [event locationInWindow];
|
|
|
|
NSRect dragRect = [view convertRect: NSMakeRect (eventPos.x - 16.0f, eventPos.y - 16.0f, 32.0f, 32.0f)
|
|
|
|
fromView: nil];
|
|
|
|
auto dragRect = getDragRect (view, event);
|
|
|
|
|
|
|
|
for (int i = 0; i < files.size(); ++i)
|
|
|
|
{
|
|
|
|
if (! [view dragFile: juceStringToNS (files[i])
|
|
|
|
fromRect: dragRect
|
|
|
|
slideBack: YES
|
|
|
|
event: event])
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
@@ -190,12 +258,6 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi |
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/)
|
|
|
|
{
|
|
|
|
jassertfalse; // not implemented!
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
bool Desktop::canUseSemiTransparentWindows() noexcept
|
|
|
|
{
|
|
|
|
@@ -206,8 +268,8 @@ Point<float> MouseInputSource::getCurrentRawMousePosition() |
|
|
|
{
|
|
|
|
JUCE_AUTORELEASEPOOL
|
|
|
|
{
|
|
|
|
const NSPoint p ([NSEvent mouseLocation]);
|
|
|
|
return Point<float> ((float) p.x, (float) (getMainScreenHeight() - p.y));
|
|
|
|
auto p = [NSEvent mouseLocation];
|
|
|
|
return { (float) p.x, (float) (getMainScreenHeight() - p.y) };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|