PDA

View Full Version : More Drag & drop, drawRect question




mdeh
Oct 28, 2009, 09:08 PM
I have written a little app to **finally** try and answer a Hillegass challenge, which tries to further my understanding of Drag & Drop.

So, I have a subclassed NSView, which has the following methods implemented.

To register:

-(void) awakeFromNib
{

NSArray *pbTypes = [ NSArray arrayWithObjects:NSPasteboardTypeString, NSPasteboardTypeSound, NSColorPboardType, nil];
[self registerForDraggedTypes : pbTypes];

NSLog(@"Registered for drop: \"String\", \"Sound\", \"Color\"");
}


On entering ( with the drag)

- (NSDragOperation)draggingEntered: (id < NSDraggingInfo >)sender
{

NSDragOperation sourceDragMask;
NSPasteboard *pboard;

pboard = [ sender draggingPasteboard];
sourceDragMask = [ sender draggingSourceOperationMask];

if ( [[ pboard types] containsObject: NSColorPboardType])
{
if ( sourceDragMask & NSDragOperationGeneric)
{
NSLog(@"Will respond to color");
return NSDragOperationGeneric;


}
}

....code to check for StringType......

return NSDragOperationNone;

}

And on the "drop"

- (BOOL)performDragOperation: (id <NSDraggingInfo>)sender
{
NSPasteboard *pboard;
NSDragOperation sourceDragMask;

sourceDragMask = [ sender draggingSourceOperationMask];
pboard = [ sender draggingPasteboard];

if ( [[ pboard types] containsObject:NSColorPboardType] )
{
NSColor *newColor = [ NSColor colorFromPasteboard:pboard];
[newColor set];
[self setNeedsDisplay:YES];
....other code....

return YES;



Now, here is the problem:

in drawRect: I set the current graphics context to the fill/stroke color. However, in order to use the "dragged" color, I clearly have to somehow take the "newColor" from the "performDragOperation" and use *that* in drawRect. Initially, I tried to see if there is a way I can interrogate the current Context from drawRect, and in that way, I could set an initial value for NSColor, say from awakeFromNib, but I cannot find a way to do this. Then I thought of extracting the color directly from the draggingPasteBoard, but could not figure out a way of referencing that from drawRect. This is cocoa, so I **know** there is an easy way to do this. :D :D
It might well be that my approach is ( in **all** likelyhood )fundamentally flawed but hopefully someone can point me in the correct direction and I can vault another hurdle to the cocoa finishing line!!

Thanks in advance.


- (void)drawRect: (NSRect)dirtyRect {

[self completeTheDrawing: dirtyRect];
NSRect bounds = [ self bounds];
NSBezierPath *path = [ NSBezierPath bezierPathWithRect: bounds];
[[NSColor redColor] set];
[path fill];
[[NSColor redColor]set];
[path setLineWidth:8];
[path stroke];
[[NSColor blackColor]set];
[path setLineWidth:4];
[path stroke];


}



chown33
Oct 28, 2009, 10:00 PM
What kinds of view have a settable color, which they will remember and use to draw in? For example, what has a settable background or foreground color? Subclass that instead of subclassing NSView.

Otherwise, subclass NSView and give it a settable color property. Set that property in the drop-handler. Fill with that color in drawRect.

If this were more complex I'd say create a Model object that has a settable color property. Your view then communicates with its model object to know what color to draw, and your drop-handler communicates with the model object to set the color. It's overkill here, but get used to this pattern, because Model-View-Controller is the way to write things in Cocoa.

mdeh
Oct 28, 2009, 10:28 PM
Otherwise, subclass NSView and give it a settable color property. Set that property in the drop-handler. Fill with that color in drawRect.


Works beautifully!!!! Thank you.



What kinds of view have a settable color, which they will remember and use to draw in? For example, what has a settable background or foreground color? Subclass that instead of subclassing NSView.

Chown...you have lost me on this one. The only views I see in IB are custom and scroll views. But, perhaps, that is yet to come in Hillegass :-)




If this were more complex I'd say create a Model object that has a settable color property. Your view then communicates with its model object to know what color to draw, and your drop-handler communicates with the model object to set the color. It's overkill here, but get used to this pattern, because Model-View-Controller is the way to write things in Cocoa.

Well, even though I do not have a **formal** controller, I think the way it is set up is indeed with a model, but your point is well taken. I am working my way through mmalc's excellent series on bindings, and I think I am about to be introduced to this in a big way. But, I really do not like to push on ahead without overcoming the little things like this, as there are often concepts hidden in there that are useful.

chown33
Oct 29, 2009, 01:08 AM
Chown...you have lost me on this one. The only views I see in IB are custom and scroll views. But, perhaps, that is yet to come in Hillegass

Yes, there's much more to come.

What I meant was to look at the classes which are subclasses of NSView, such as NSControl and its subclasses. In a more general sense, look at the Application Kit class hierarchy, and notice all the subclasses of NSView, either direct or by intermediate classes.

mdeh
Oct 29, 2009, 05:56 AM
Yes, there's much more to come.

What I meant was to look at the classes which are subclasses of NSView, such as NSControl and its subclasses. In a more general sense, look at the Application Kit class hierarchy, and notice all the subclasses of NSView, either direct or by intermediate classes.

Thank you again. Much appreciated.