Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

benkenobi

macrumors member
Original poster
May 27, 2009
33
0
I've been trying to make it so that an image can be dragged out of NSImageView and onto Finder etc(the destination).

I've went over the documentation for drag and drop many times but everything seems to be in place. I even copied a sample which does just about the same thing as my program and it still won't show a green + sign when dragging over Finder. The plus sign shows only when I drag over the NSImageView

The code here is copied over from the sample program which works without a problem. :confused: Can anyone give a hint on what might be missing?
Code:
@implementation MAImageView

- (id)initWithCoder:(NSCoder *)coder
{
    /*------------------------------------------------------
     Init method called for Interface Builder objects
     --------------------------------------------------------*/
    if(self==[super initWithCoder:coder]){
        //register for all the image types we can display
        [self registerForDraggedTypes:[NSImage imagePasteboardTypes]];
    }
    return self;
}

-(BOOL) acceptsFirstMouse:(NSEvent *)theEvent{
    return YES;
}

-(void)mouseDown:(NSEvent *)theEvent{

    /*------------------------------------------------------
     catch mouse down events in order to start drag
     --------------------------------------------------------*/
    //get the Pasteboard used for drag and drop operations
    NSPasteboard* dragPasteboard=[NSPasteboard pasteboardWithName:NSDragPboard];
    //create a new image for our semi-transparent drag image
    NSImage* dragImage=[[NSImage alloc] initWithSize:[[self image] size]]; 
    //add the image types we can send the data as(we'll send the actual data when it's requested)
    [dragPasteboard declareTypes:[NSArray arrayWithObject: NSTIFFPboardType] owner:self];
    
    [dragImage lockFocus];//draw inside of our dragImage
    //draw our original image as 50% transparent
    [[self image] dissolveToPoint: NSZeroPoint fraction: .5];
    [dragImage unlockFocus];//finished drawing
    [dragImage setScalesWhenResized:YES];//we want the image to resize
    [dragImage setSize:[self bounds].size];//change to the size we are displaying
    //execute the drag
    [self dragImage: dragImage//image to be displayed under the mouse
                 at: [self bounds].origin//point to start drawing drag image
             offset: NSZeroSize//no offset, drag starts at mousedown location
              event:theEvent//mousedown event
         pasteboard:dragPasteboard//pasteboard to pass to receiver
             source: self//object where the image is coming from
          slideBack: YES];//if the drag fails slide the icon back
    [dragImage release];//done with our dragImage
      

}

- (void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
{
    /*------------------------------------------------------
     method called by pasteboard to support promised 
     drag types.
     --------------------------------------------------------*/
    //sender has accepted the drag and now we need to send the data for the type we promised
    if([type compare: NSTIFFPboardType]==NSOrderedSame){
        //set data for TIFF type on the pasteboard as requested
        [sender setData:[[self image] TIFFRepresentation] forType:NSTIFFPboardType];
    }else if([type compare: NSPDFPboardType]==NSOrderedSame){
        [sender setData:[self dataWithPDFInsideRect:[self bounds]] forType:NSPDFPboardType];
    }
}

- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal{
    return NSDragOperationGeneric;//destination object is in a different application.
}
    
}
 
Does the Finder support the types you are offering? I would expect the Finder only accepts files, or possibly file names, not image data. i.e. the Finder will accept an image if it's a file but it will not create a file for you from image data.

What happens if you promise the type NSFileContentsPboardType? Do you get messages in pasteboard:provideDataForType: ?
 
EDIT: works with Finder now!

Changed: return NSDragOperationGeneric; to return NSDragOperationCopy;
Code:
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal{
    if(!isLocal){
        return NSDragOperationCopy;//destination object is in a different application.
    }else{
        return NSDragOperationNone;
    }
    
}



Making progess.

I rewrote the code so it's all done with file names like you suggested. I can drop into texteditor and other programs but not Finder. hmm

Code:
-(void)mouseDown:(NSEvent *)theEvent{
    NSURL *fileURL;
    NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
    
    //get fileURL of dragged image
    [[self image] initWithPasteboard:pboard];
    fileURL=[NSURL URLFromPasteboard:pboard];
    
    NSString *filePath1= [fileURL path];
    
    NSImage *dragImage;
    NSPoint dragPosition;
    
    // Write data to the pasteboard
    NSArray *fileList = [NSArray arrayWithObjects:filePath1, nil];
    pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
    [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType]
                   owner:nil];
    [pboard setPropertyList:fileList forType:NSFilenamesPboardType];
    
    // Start the drag operation
    dragImage = [[NSWorkspace sharedWorkspace] iconForFile:filePath1];
    dragPosition = [self convertPoint:[theEvent locationInWindow]
                             fromView:nil];
    dragPosition.x -= 16;
    dragPosition.y -= 16;
    [self dragImage:dragImage
                 at:dragPosition
             offset:NSZeroSize
              event:theEvent
         pasteboard:pboard
             source:self
          slideBack:YES];
    

}
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.