Drag to save

Sage
Posts: 1,403
Joined: 2005.07
Post: #1
Trying to make a custom NSView with a picture in it that you can drag the image out to the desktop to save, or maybe drag it into photoshop to edit it, Ive got this far:

Code:
- (void)mouseDown:(NSEvent*)theEvent
{
        NSImage *im = [[NSImage alloc] initWithSize:NSMakeSize(256, 256)];
        
        [im lockFocus];
        [[NSColor redColor] set];
        NSRectFill(NSMakeRect(0, 0, 256, 256));
        [im unlockFocus];
        
        NSData *imgData = [im TIFFRepresentation];
        
        NSPasteboard *paste = [NSPasteboard pasteboardWithName:NSDragPboard];
        
        [paste declareTypes:[NSArray arrayWithObject:NSPDFPboardType] owner:self];
        [paste setPropertyList:[NSArray arrayWithObject:imgData] forType:NSPDFPboardType];
        
        [self dragImage:im at:NSMakePoint(0, 0) offset:NSMakeSize(0, 0) event:theEvent pasteboard:paste source:self slideBack:NO];
}

A good example of what I want to do is where you can take an image from a webpage and drag it to the desktop to save it with safari.

Thanks in advance.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #2
some one help me please Cry

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Moderator
Posts: 3,573
Joined: 2003.06
Post: #3
Here's what I do in my NSView for an app I have which plots a graph. If you drag the view to the desk it is saved as a PNG, and if you drag it into an existing Photoshop window it draws as a PDF so it can be resized as a vector graphic. If you drag it onto the Photoshop icon it will open it as a PNG. If you hold down shift it will not draw the background, which you probably don't need, but I didn't bother modifying my code here. It's just a flag that my drawRect routine looks at to determine whether or not to draw a white background rectangle before the rest of the drawind commences. Hope it offers some hints that might help.

Code:
#pragma mark -

//-----------------------------------------------------------------------------
- (void)mouseDragged:(NSEvent *)event
{
    NSPasteboard        *pb;
    NSImage                *image1, *image2;
    unsigned int        modFlags;
    
    pb = [NSPasteboard pasteboardWithName:NSDragPboard];
    image1 = [[NSImage alloc] initWithSize:[self bounds].size];
    image2 = [[NSImage alloc] initWithSize:[self bounds].size];
    
    // don't allow window to move forward since it's just being dragged from
    [NSApp preventWindowOrdering];
    
    // check for shift key to see if don't draw background
    modFlags = [[NSApp currentEvent] modifierFlags];
    if (modFlags & NSShiftKeyMask) drawBackground = false;
    
    // draw the dragged image
    [image1 lockFocus];
    [self drawRect:[self bounds]];
    [image1 unlockFocus];
    
    // redraw the "dragged" image to be semi-transparent
    [image2 lockFocus];
    [image1 dissolveToPoint:NSZeroPoint fraction:0.5f];
    [image2 unlockFocus];
    
    [pb declareTypes:[NSArray arrayWithObject:NSPDFPboardType] owner:self];
    [pb addTypes:[NSArray arrayWithObject:NSFilesPromisePboardType] owner:self];
    
    [self dragImage:image2 at:NSZeroPoint offset:NSZeroSize event:event
                                    pasteboard:pb source:self slideBack:YES];
    [image1 release];
    [image2 release];
}

//-----------------------------------------------------------------------------
- (NSData *)PNG
{
    NSBitmapImageRep    *bitmapRep;
    NSImage                *image;
    NSData                *PNGData;
    
    image = [[NSImage alloc] initWithSize:[self bounds].size];
    [image lockFocus];
    [self drawRect:[self bounds]];
    bitmapRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[self bounds]];
    [image unlockFocus];
    PNGData = [bitmapRep representationUsingType:NSPNGFileType properties:nil];
    [image release];
    [bitmapRep release];
    
    return PNGData;
}

//-----------------------------------------------------------------------------
- (void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
{
    NSImage            *image;
    unsigned int    modFlags;
    
    // check for shift key to see if don't draw background
    modFlags = [[NSApp currentEvent] modifierFlags];
    
    if([type compare:NSTIFFPboardType]==NSOrderedSame)
    {
        if (modFlags & NSShiftKeyMask) drawBackground = false;
        image = [[NSImage alloc] initWithSize:[self bounds].size];
        [image lockFocus];
        [self drawRect:[self bounds]];
        [image unlockFocus];
        [sender setData:[image TIFFRepresentation] forType:NSTIFFPboardType];
        [image release];
    }
    else if([type compare:NSPDFPboardType]==NSOrderedSame)
    {
        if (modFlags & NSShiftKeyMask) drawBackground = false;
        [sender setData:[self dataWithPDFInsideRect:[self bounds]] forType:NSPDFPboardType];
    }
    else if([type compare:NSFilesPromisePboardType]==NSOrderedSame)
    {
        [sender setPropertyList:[NSArray arrayWithObject:@"png"] forType:NSFilesPromisePboardType];
    }
}

// - gets called by the drag and drop destination if it was an accepted type
// - good place to write the file since it's a quick operation
//-----------------------------------------------------------------------------
- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
{
    NSFileManager        *fm;
    NSString            *basePath;
    NSString            *path;
    int                    i;
    unsigned int    modFlags;
    
    // again check for control key to see if don't draw background
    modFlags = [[NSApp currentEvent] modifierFlags];
    if (modFlags & NSShiftKeyMask) drawBackground = false;
    
    // determine a valid name for the file to write to
    fm = [NSFileManager defaultManager];
    basePath = [[dropDestination path] stringByAppendingPathComponent:[[self window] title]];
    path = [basePath stringByAppendingPathExtension:@"png"];
    i = 1;
    while ([fm fileExistsAtPath:path])
    {
        path = [[basePath stringByAppendingFormat:@"-%i", i++] stringByAppendingPathExtension:@"png"];
    }
    [[self PNG] writeToFile:path atomically:YES];
    
    return [NSArray arrayWithObject:[path lastPathComponent]];
}

//-----------------------------------------------------------------------------
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)flag
{
    return NSDragOperationCopy;
}

//-----------------------------------------------------------------------------
- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent
{
    // allows time to prevent window ordering in mouseDragged so it doesn't
    // come to the front when dragged from another app.
    return YES;
}

//-----------------------------------------------------------------------------
- (BOOL)acceptsFirstMouse:(NSEvent *)event
{
    // so source doesn't have to be the active window to start a drag and drop
    return YES;
}

Oh yeah, and I have it set so that the app doesn't come to the foreground if you're just dragging the image from it. You don't have to do that either.
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #4
Thank you very much AnotherJake thats really helpful, just need to find some time to read through this, thanks again!

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Click-and-Drag Box bwalters 2 2,344 Mar 4, 2006 08:27 PM
Last Post: bwalters
  How would I save an NSView as a JPG? Joseph Duchesne 0 3,034 Sep 30, 2005 07:51 PM
Last Post: Joseph Duchesne
  Save GIF file... alert 6 4,476 Jan 11, 2005 08:48 AM
Last Post: ThemsAllTook
  Where to save sprites in memory in OpenGL? forseti 6 4,505 Aug 6, 2002 10:06 AM
Last Post: DaFalcon