Dragging text strings from NSMatrix cells (solution)
Dragging text strings from NSMatrix cells (solution)
- Subject: Dragging text strings from NSMatrix cells (solution)
- From: Andy <email@hidden>
- Date: Sat, 20 Jul 2002 14:53:40 -0400
I just spent a couple of days combining code fragmenets to make an
NSMatrix / NSCell subclass pair that allow you to grab ahold of the text
in the cells and drag and drop it elsewhere.
I figured I'd post this to save anyone else the effort, as I think this
solution looks pretty good.
In you NSMatrix subclass, implement the following methods:
- (BOOL) acceptsFirstMouse: (NSEvent *) theEvent {
return YES;
}
- (NSDragOperation) draggingSourceOperationMarkForLocal: (BOOL) flag {
return NSDragOperationCopy;
}
- (void) copyToPasteboard: (NSPasteboard *) a_pboard {
NSString *title = [[self selectedCell] title];
NSAttributedString *attTitle = [[self selectedCell] attributedTitle];
[a_pboard declareTypes: [NSArray arrayWithObjects: NSRTFPboardType,
NSStringPboardType, nil] owner: self];
[a_pboard setData: [attTitle RTFFromRange: NSMakeRange(0, [attTitle
length]) documentAttributes: nil] forType:NSRTFPboardType];
[a_pboard setString: title forType: NSStringPboardType];
//[a_pboard setData: [[self title] dataUsingEncoding: some custom
encoding? forType: NSStringPboardType];
//NSLog(@"Types in drag: %@\n", [a_pboard types]);
}
/* Have to override this becuase NSMatrix eats drag events in this
method by default, and we want to handle dragging.
Naturally, this means we have to guess what NSMatrix does in response to
a moueDown event and try to emulate
every part of it _except_ for the eating of the drag events...*/
- (void) mouseDown: (NSEvent *) a_theEvent {
int row = -1, column = -1;
if ( [self getRow: &row column: &column forPoint: [self
convertPoint:[a_theEvent locationInWindow] fromView: nil]] &&
[[self cellAtRow:row column: column] isEnabled]) {
[self selectCellAtRow: row column: column];
[self sendAction];
} else {
[super mouseDown: a_theEvent];
}
}
- (void) mouseDragged: (NSEvent *) a_theEvent {
NSPasteboard *pboard;
NSImage *image = nil;
NSImage *translucent = nil;
NSPoint dragPoint = NSZeroPoint;
pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
[self copyToPasteboard: pboard];
image = [((ColouredBorderButtonCell *)[self selectedCell]) getImageOfContents];
dragPoint = [self convertPoint: [a_theEvent locationInWindow]
fromView: nil];
dragPoint.x -= ([image size].width * 0.5);
dragPoint.y += ([image size].height * 0.5);
translucent = [[[NSImage alloc] initWithSize: [image size]] autorelease];
[translucent lockFocus];
[image dissolveToPoint: NSZeroPoint fraction: 0.5];
[translucent unlockFocus];
[self dragImage: translucent
at: dragPoint
offset: NSZeroSize
event: a_theEvent
pasteboard: pboard
source: self
slideBack: YES];
}:
ColouredBorderButtonCell is my cutom NSCell - it does a bunch of stuff,
but from drag and drop, the piece you care about is:
- (NSImage *) getImageOfContents {
NSImage *image = nil;
NSBitmapImageRep *bits = nil;
NSRect textFrame;
textFrame.size = [self cellSize];
textFrame.origin = NSZeroPoint;
image = [[NSImage alloc] initWithSize: textFrame.size];
[image setBackgroundColor:[NSColor clearColor]];
[image lockFocus];
[self drawInteriorWithFrame: textFrame inView: [NSView focusView]];
bits = [[NSBitmapImageRep alloc] initWithFocusedViewRect: textFrame];
[image unlockFocus];
[bits release];
return [image autorelease];
}
Damn this toolset is powerful once you start to know it well enough!
--
AndyT (lordpixel - the cat who walks through walls)
A little bigger on the inside
I think we finally found the killer app for Flash: animated stick men
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.