home *** CD-ROM | disk | FTP | other *** search
- //
- // A View that implements Dragging in 3.0
- // Greg Burd
- // Copyright NeXT Computer, Inc 1992 All Rights Reserved
- //
- // Created 7-4-92 -- (Improved from existing code by Randy Nelson)
- //
- // You may freely copy, distribute and reuse the code in this example.
- // NeXT disclaims any warranty of any kind, expressed or implied, as to
- // its fitness for any particular use.
- //
-
- #import "DragView.h"
- #import "Text_Console.h" // text category that allows formated printf:
- #import <appkit/Application.h>
- #import <appkit/Pasteboard.h>
- #import <appkit/OpenPanel.h>
- #import <appkit/graphics.h> // for NXFrameRectWithWidth
-
- @implementation DragView
-
- /*-------------------- methods to get things set up */
-
- - initFrame:(const NXRect *)theFrame
- {
- const char *const types[] = {NXPostScriptPboardType};
-
- [textObj printf:"In initFrame:\n"];
- [super initFrame:theFrame];
-
- //register which pasteboard types you will accept
- [self registerForDraggedTypes:(const char *const*)&types count:1];
- drawBackground = YES;
-
- return self;
- }
-
- - awakeFromNib
- {
- [textObj printf:"In awakeFromNib:\n"];
-
- framed = NO;
- [window makeKeyAndOrderFront:self];
- return self;
- }
-
- /*-------------------- methods to be the source of a dragging operation */
-
- - mouseDown:(NXEvent *)theEvent
- {
- NXPoint zero = {0.0, 0.0};
- id thePboard;
-
- [textObj printf:"In mouseDown:\n"];
-
- // Prevent default window ordering (this is a new appkit feature)
- [NXApp preventWindowOrdering];
-
- //get the Pboard
- thePboard = [Pasteboard newName:NXDragPboard];
- [thePboard declareTypes:&NXPostScriptPboardType num:1 owner:self];
-
- //put an EPS of the image on the Pboard
- drawBackground = NO;
- [self writePSCodeInside:&bounds to:thePboard];
- drawBackground = YES;
-
- //start the drag
- [self dragImage:theImage // visable on screen during drag
- at:&zero // offset the mouse point for the drag
- offset:&zero // offset the inital mouse pt
- event:theEvent // theEvent structure
- pasteboard:thePboard // a Pasteboard with data on it
- source:self // source object
- slideBack:YES]; // if no destination animate back to source
-
- return self;
- }
-
- - draggedImage:(NXImage *)image beganAt:(NXPoint *)screenPoint
- {
- [textObj printf:"In draggedImage::\n"];
- return self;
- }
-
- - (NXDragOperation)draggingSourceOperationMaskForLocal:(BOOL)flag
- {
- [textObj printf:"In draggingSourceOperationMaskForLocal:\n"];
-
- return (NX_DragOperationCopy | NX_DragOperationGeneric);
- }
-
- - draggedImage:(NXImage *)image endedAt:(NXPoint *)screenPoint deposited:(BOOL)flag
- {
- [textObj printf:"In draggedImage:\n"];
-
- return self;
- }
-
- /*-------------------- methods to be the destination of a dragging operation */
-
- - (NXDragOperation)draggingEntered:sender
- {
- [textObj printf:"In draggingEntered:\n"];
-
- // check to make sure we are not the source and this operation is a copy
- if (([sender draggingSourceOperationMask] & NX_DragOperationCopy) &&
- ([sender draggingSource] != self)) {
- framed = YES;
- [self display];
- //return the type of operation we want to do, this will dictate
- //the type of cursor will show up when accepting the drag
- return NX_DragOperationCopy;
- }
- return NX_DragOperationNone;
- }
-
- - (NXDragOperation)draggingUpdated:sender
- {
- [textObj printf:"In draggingUpdated:\n"];
-
- // make sure that this is a copy operation, and that this instance
- // of DragView is not the source
- if (([sender draggingSourceOperationMask] & NX_DragOperationCopy) &&
- ([sender draggingSource] != self)) {
- framed = YES;
- [self display];
- return NX_DragOperationCopy;
- }
- return NX_DragOperationNone;
- }
-
- - draggingExited:sender
- {
- [textObj printf:"In draggingExited:\n"];
- if (framed) {
- framed = NO;
- [self display];
- }
- return self;
- }
-
- - (BOOL)prepareForDragOperation:sender
- {
- [textObj printf:"In performDragOperation:\n"];
-
- return YES;
- }
-
- - (BOOL)performDragOperation:sender
- {
- [textObj printf:"In performDragOperation:\n"];
-
- // make sure that what we are getting is from the same application
- // and did not originate from this view.
- if ([sender isDraggingSourceLocal] && ([sender draggingSource] != self)) {
-
- // if I had an image free it
- if (theImage) [theImage free];
-
- // new call in NXImage allows you to initFromPasteboard
- theImage = [[NXImage alloc] initFromPasteboard:
- [sender draggingPasteboard]];
-
- [theImage setDataRetained:YES]; // otherwise it scales poorly
- [theImage setScalable:YES]; // scaleable yes
- [theImage setSize:&bounds.size];// rescale to the same size as view
- framed = NO;
- [self display];
- }
- if(framed) {
- framed = NO;
- [self display];
- }
- return YES;
- }
-
- - concludeDragOperation:sender
- {
- [textObj printf:"In concludeDragOperation:\n"];
- // This is within a oneway call, so you can send a call to Workspace
- // without it getting 'hung up' waiting for a return
-
- return self;
- }
-
- /*-------------------- methods to display, and other useful stuff */
-
- - (BOOL)acceptsFirstMouse
- {
- [textObj printf:"In acceptsFirstMouse:\n"];
- return YES;
- }
-
- - (BOOL)shouldDelayWindowOrderingForEvent:(NXEvent *)theEvent
- {
- // This is the other portion of the new appkit functionality
- // which allows you to drag a partially obscure object without
- // making the source window become main, and without making the
- // source application the current app.
- [textObj printf:"In shouldDelayWindowOrderingForEvent:\n"];
- return YES;
- }
-
- - sizeTo:(NXCoord)x :(NXCoord)y
- {
- [textObj printf:"In sizeTo::\n"];
-
- [super sizeTo:x :y];
- [theImage setSize:&bounds.size];
- return self;
- }
-
- - open:sender
- {
- static const char *const types[] = {"tiff", "eps", NULL};
-
- [textObj printf:"In open:\n"];
-
- // get a filename to open
- if ([[OpenPanel new] runModalForTypes:types] == 0) return nil;
-
- // create an image from the file
- // it'll be whatever size the file tells it to be
- [self setImage:[[NXImage alloc] initFromFile:[[OpenPanel new] filename]]];
-
- return self;
- }
-
- - setImage:(id)anImage
- {
- [textObj printf:"In setImage:\n"];
-
- // free theImage it if is been used
- if(theImage) [theImage free];
-
- framed = NO;
- theImage = anImage;
- [theImage setScalable:YES]; // scaleable yes
- [theImage setSize:&bounds.size]; // rescale to the same size as view
- [self display];
-
- return self;
- }
-
- - drawSelf:(const NXRect *)rects :(int)num
- {
- // if we are copying the PS code onto the Pboard, then we don't want
- // the white background. Only the image.
- if (drawBackground) NXEraseRect(rects);
-
- // Composite the image into the view.
- [theImage composite:NX_SOVER toPoint:&bounds.origin];
- // if we are in the middle of a drag operation then we can frame the
- // view rect to show our acceptance of the incomming data. Another way
- // would be to create a ghost image similar to the shelf in Workspace.
- if(framed) {
- NXFrameRectWithWidth(&bounds, (NXCoord)3.0);
- }
- return self;
- }
-
- - free
- {
- [textObj printf:"In free:\n"];
-
- // be a good object and free things up
- [theImage free];
- return [super free];
- }
-
- @end
-