Interface Builder Drag & Drop

January 26, 2009

I’ve been trying to implement a drag and drop feature like the one in Interface Builder where the image is one thing over the source window and a different image when over the target window. Having tried various ways to achieve this it looked to me like it’s not possible. I wondered whether IB was actually using real drag & drop at all.

So I tried dragging from the IB library to my own destination window, with a breakpoint on the draggingEntered: method. Sure enough it wasn’t called.

Then it struck me. When you initially drag a window out of the IB Library, you then drag it to nothingness. The desktop doesn’t know what it is. So real drag & drop wouldn’t work for IB. It’s an internal implementation of drag&drop.


Improved NSView to NSImage for Drag and Drop

January 26, 2009

Drag and Drop in Interface Builder

Here’s an improvement on the last post’s method for grabbing a view and converting it into a drag image. This copies the bitmap directly instead of redrawing ir with a PDF, so is faster, and pixel perfect.

// Take a snapshot of the view bitmap.
[self lockFocus];
NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc]
    initWithFocusedViewRect: [self bounds]];
[self unlockFocus];
NSImage* viewSnapshot = [[NSImage alloc]
                        initWithSize:[self bounds].size];
[viewSnapshot addRepresentation:bitmap];

// Copy the snapshot to make a seeThru drag image.
NSImage* dragImage = [[NSImage alloc] initWithSize:viewSnapshot.size];
[dragImage lockFocus];
[viewSnapshot dissolveToPoint:NSMakePoint(1,0) fraction:1];
[dragImage unlockFocus];

How to grab an NSImage from an NSView

January 23, 2009

Here’s one way to create an image of a view. There may be a better way, but this certainly works. If you do know of a better way, then please comment.
Self is an NSView.

NSRect boxrect = self.bounds;
NSData* pdf = [self dataWithPDFInsideRect:boxrect];
NSImage* viewSnapshot = [[NSImage alloc] initWithData:pdf];

You can then go on to make a translucent version of the image. This is useful for drag & drop.

NSImage* dragImage = [[NSImage alloc] initWithSize:viewSnapshot.size];
[dragImage lockFocus];
[viewSnapshot dissolveToPoint:NSZeroPoint fraction:0.85];
[dragImage unlockFocus];

Note that I’m using garbage collection here.  Alter as necessary if you need to manage memory.

On Apple’s site there’s a demo of how to do screenshots of windows or the whole screen.  It’s called SonOfGrab and it’s Leopard only.  I’ve not yet tried it myself.


Design a site like this with WordPress.com
Get started