Online Book Reader

Home Category

Cocoa Programming for Mac OS X - Aaron Hillegass [98]

By Root 874 0
message returns YES, then a performDragOperation: message is sent. This is typically where the application reads data off the pasteboard.

6. Finally, if performDragOperation: returned YES, concludeDragOperation: is sent. The appearance may change. This is where you might generate the big gulping sound that implies a successful drop.

registerForDraggedTypes:


Add a call to registerForDraggedTypes: to the initWithFrame: method in BigLetterView.m:

- (id)initWithFrame:(NSRect)rect

{

self = [super initWithFrame:rect];

if (self) {

NSLog(@"initializing view");

[self prepareAttributes];

bgColor = [NSColor yellowColor];

string = @"";

[self registerForDraggedTypes:

[NSArray arrayWithObject:NSPasteboardTypeString]];

}

return self;

}

Add Highlighting


To signal the user that the drop is acceptable, your view will highlight itself. Add a highlighted instance variable to BigLetterView.h:

@interface BigLetterView : NSView

{

NSColor *bgColor;

NSString *string;

NSMutableDictionary *attributes;

NSEvent *mouseDownEvent;

BOOL highlighted;

}

Now you are going to add highlighting to drawRect:. The class NSGradient makes it easy to draw with gradients. In this case, you are going to draw a radial gradient: white in the center and fading into the bgColor.

- (void)drawRect:(NSRect)rect

{

NSRect bounds = [self bounds];

// Draw gradient background if highlighted

if (highlighted) {

NSGradient *gr;

gr = [[NSGradient alloc] initWithStartingColor:[NSColor whiteColor]

endingColor:bgColor];

[gr drawInRect:bounds relativeCenterPosition:NSZeroPoint];

} else {

[bgColor set];

[NSBezierPath fillRect:bounds];

}

[self drawStringCenteredIn:bounds];

Implement the Dragging Destination Methods


So far, we have seen two ways to declare a pointer to an object. If the pointer can refer to any type of object, we would declare it like this:

id foo;

If the pointer should refer to an instance of a particular class, we can declare it like this:

MyClass *foo;

A third possibility also exists. If we have a pointer that should refer to an object that conforms to a particular protocol, we can declare it like this:

id foo;

NSDraggingInfo is a protocol, not a class. All the dragging destination methods expect an object that conforms to the NSDraggingInfo protocol.

Add the following methods to BigLetterView.m:

#pragma mark Dragging Destination

- (NSDragOperation)draggingEntered:(id )sender

{

NSLog(@"draggingEntered:");

if ([sender draggingSource] == self) {

return NSDragOperationNone;

}

highlighted = YES;

[self setNeedsDisplay:YES];

return NSDragOperationCopy;

}

- (void)draggingExited:(id )sender

{

NSLog(@"draggingExited:");

highlighted = NO;

[self setNeedsDisplay:YES];

}

- (BOOL)prepareForDragOperation:(id )sender

{

return YES;

}

- (BOOL)performDragOperation:(id )sender

{

NSPasteboard *pb = [sender draggingPasteboard];

if(![self readFromPasteboard:pb]) {

NSLog(@"Error: Could not read from dragging pasteboard");

return NO;

}

return YES;

}

- (void)concludeDragOperation:(id )sender

{

NSLog(@"concludeDragOperation:");

highlighted = NO;

[self setNeedsDisplay:YES];

}

Add a Second BigLetterView


Open MainMenu.xib and add another BigLetterView to the window. Delete the text fields. Make sure to set the nextKeyView for each BigLetterView so that you can tab between them (Figure 23.2).

Figure 23.2. Set nextKeyView for Each BigLetterView

Build and run the application. Note that you can drag characters between the views and from other applications.

For the More Curious: Operation Mask


For some apps, the negotiations of what operation will occur when the user drops can be quite complicated. After all, the source advertises its willingness to participate in some kinds of operations through draggingSourceOperationMaskForLocal:. The user may also indicate preferences by holding down the Control, Option, or Command key. It is the

Return Main Page Previous Page Next Page

®Online Book Reader