Nimrand
Nimrand

Reputation: 1768

Drag/drop a NSImage

I'm making an application from which I want to be able to drag an image to into a specific 3rd party application, Anki. The image is loaded from the Internet, and so does not exist on the hard drive. The API documentation seems to offer three methods of doing this (note that I purposely omitted alternatives that use API functions that are now deprecated):

So, my question is 2-part:

Can method #2 be made to work? This would avoid creating unnecessary temporary files, and so would be ideal. NSImage supports NSPasteboardWriter, so it seems like it should work. But, I can't find an example of how to do it.

If I must use method #1, where is the recommended place to put temporary files like these? If I must create a temporary file in order to drop the image into my target application, then where is the recommended place to put files like these?

//
//  DraggableImageView.swift
//  Lang Search
//
//  Created by Kevin Yancey on 11/21/14.
//  Copyright (c) 2014 Kevin Yancey. All rights reserved.
//

import Foundation
import Cocoa
import AppKit

class DraggableImageView : NSImageView, NSDraggingSource {
    //Method #1 - It works, but isn't ideal yet...
    override func mouseDragged(theEvent: NSEvent) {
        if let image = self.image {
            let imgRep = image.representations[0] as! NSBitmapImageRep;
            let data = imgRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: NSDictionary() as [NSObject : AnyObject])!;
            data.writeToFile("/Users/kpyancey/Desktop/copiedImage.png", atomically: false);
            let draggingItem : NSDraggingItem = NSDraggingItem(pasteboardWriter: NSURL.fileURLWithPath("/Users/kpyancey/Desktop/copiedImage.png")!)
            let draggingItems : [AnyObject] = [draggingItem]
            let draggingSession = beginDraggingSessionWithItems(draggingItems, event: theEvent, source: self)
        }
    }

    //Method #2 - doesn't seem to work at all
    /*override func mouseDragged(theEvent: NSEvent) {
        if let image = self.image {
            let draggingItem : NSDraggingItem = NSDraggingItem(pasteboardWriter: image)
            let draggingItems : [AnyObject] = [draggingItem]
            let draggingSession = beginDraggingSessionWithItems(draggingItems, event: theEvent, source: self)
        }
    }*/
    //Method #3 - works, but not with the target application (Anki)
    /*
    override func mouseDragged(theEvent: NSEvent) {
        if let image = self.image {
            let draggingItem : NSDraggingItem = NSDraggingItem(pasteboardWriter: image)
            let draggingItems : [AnyObject] = [draggingItem]
            let draggingSession = beginDraggingSessionWithItems(draggingItems, event: theEvent, source: self)
        }
    }*/
    /*
    override func mouseDragged(theEvent: NSEvent) {
        var dragPosition = convertPoint(theEvent.locationInWindow, fromView: nil)
        dragPosition.x -= 16
        dragPosition.y -= 16
        let imageLocation = NSRect(origin: dragPosition, size: NSMakeSize(32, 32))
        self.dragPromisedFilesOfTypes(["png"], fromRect: imageLocation, source: self, slideBack: true, event: theEvent)
    }

    override func namesOfPromisedFilesDroppedAtDestination(dropDestination: NSURL) -> [AnyObject]? {
        let imgRep = image!.representations[0] as! NSBitmapImageRep;
        let data = imgRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: NSDictionary() as [NSObject : AnyObject])!;
        let filePath = dropDestination.URLByAppendingPathComponent("test.png")
        data.writeToURL(filePath, atomically: false);
        return [filePath]
    }*/

    func draggingSession(session: NSDraggingSession, sourceOperationMaskForDraggingContext context: NSDraggingContext) -> NSDragOperation {
        return NSDragOperation.Copy
    }
}

Upvotes: 2

Views: 954

Answers (1)

Rupert Pupkin
Rupert Pupkin

Reputation: 790

Apparently Anki wants a url on pasteboard. Method#1 is great, but use NSCachesDirectory instead of hard-coding to desktop:

NSURL* osURL = [[[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil] URLByAppendingPathComponent:@"copiedImage.png"]; 

Upvotes: 2

Related Questions