This is MiscDragView.m in view mode; [Download] [Up]
/* MiscDragView.m Copyright (C) 1995, 1996 Todd Thomas Use is governed by the MiscKit license This object is included in the MiscKit by permission from the author and its use is governed by the MiscKit license, found in the file "LICENSE.rtf" in the MiscKit distribution. Please refer to that file for a list of all applicable permissions and restrictions. */ // RCS identification information static char *rcsID = "$Id: MiscDragView.m,v 1.2 1996/10/07 02:49:17 todd Exp $"; static void __AvoidCompilerWarning(void) {if(!rcsID)__AvoidCompilerWarning();} #import <AppKit/AppKit.h> #import "MiscDragCell.h" #import "MiscDragView.h" // **** Archiving: READ ME **** This is the current and defined version of the // class. It is used to identify what data will be written and how that will // happen. If the read/write stuff is modified AT ALL, this must be bumped up // (I always bump by one) and the other comments must be followed. Failure to // do so will result in palettes and nibs that cannot be read. BJM 5/24/94 #define MISC_DRAG_VIEW_VERSION 4 // Our default drag cell class. static Class _dragCellClass = nil; @implementation MiscDragView /*" MiscDragView defines an NSView subclass that can be either the source or sink of a dragging session. The behavior of the drag view almost completely depends upon the class of drag cell you make use of. You can set the drag cell that we use in many ways. You can either create a MiscDragView instance and use #setCell: (from NSControl) to set a concrete instance of a subclass of MiscDragCell, or you can create a subclass of MiscDragView that overrides #{+cellClass} to return a subclass of MiscDragCell. For an example of the latter, see MiscFileDragView. "*/ //------------------------------------------------------------------- // Class initialization //------------------------------------------------------------------- + (void) initialize /*" Sets our class verison for archiving and sets our cell class to MiscDragCell by default. "*/ { if (self == [MiscDragView class]) { /* * **** Archiving: READ ME **** After bumping the _VERSION, it is * considered common practice to add a comment line indicating the new * version number, date, and modifier. Optionally, the reason for the * change. There is no need to modify the setVersion message. BJM * 5/24/94 */ // version 0: initial. (bjm) // version 1: add target/action support (Steve_Hayman@Objectario.com) // version 2: add accepting image (e.g. opening folder) // version 3: created a MiscDragCell class which does most of the work. // version 4: OpenStep conversion (Cell now has ivars) [self setVersion:MISC_DRAG_VIEW_VERSION]; [self setCellClass:[MiscDragCell class]]; } } + (Class) cellClass /*" Returns our cell class. By default it is MiscDragCell, though you should override these methods (#cellClass/setCellClass:) in any subclasses because MiscDragCell is an abstract class. "*/ { return _dragCellClass; } + (void) setCellClass:(Class)newDragCellClass /*" Sets our cell class. By default it is MiscDragCell. "*/ { _dragCellClass = newDragCellClass; } //------------------------------------------------------------------- // Initialization/deallocation //------------------------------------------------------------------- - initWithFrame:(NSRect)frameRect /*" Our designated initializer. We call our #initializeDragTypes method (to register the types of pasteboard data we will accept) and set our border type to NSBezelBorder. "*/ { BOOL error = ([super initWithFrame:frameRect] == nil); if (!error) { [self initializeDragTypes]; [self setBorderType:NSBezelBorder]; } return error ? nil : self; } - (void) dealloc /*" Releases our resources, which right now seem to be nothing. "*/ { [super dealloc]; } //------------------------------------------------------------------- // Our images //------------------------------------------------------------------- - (NSImage*) image /*" Returns our current image or nil if we don't have one. "*/ { return [[self cell] image]; } - (void) setImage:(NSImage*)newImage /*" Sets our image. If newImage is nil it will clear any image we used to have. "*/ { [[self cell] setImage:newImage]; } - (NSImage*) acceptingImage /*" Returns the image that's dislayed when we are accepting a drag, or nil if we don't have an accepting image. If we do have an accepting image then the usual "dimmed" icoming image won't be shown. "*/ { // return [[self cell] acceptingImage]; } - (void) setAcceptingImage:(NSImage *)newImage /*" Sets the image that's dislayed when we are accepting a drag. If we do have an accepting image then the usual "dimmed" icoming image won't be shown. If newImage is nil then we revert back to using the "dimmed" incoming image. "*/ { [[self cell] setAcceptingImage:newImage]; } - (NSImage*) dragImage /*" Returns the image we use as the drag image. If it is nil then by default we use the image returned by sending ourself an #image message. "*/ { return [[self cell] dragImage]; } - (void) setDragImage:(NSImage *)anImage /*" Sets our drag image. If we don't have a drag image then we use the image we are currently displaying. "*/ { [[self cell] setDragImage:anImage]; } //------------------------------------------------------------------- // Options //------------------------------------------------------------------- - (NSBorderType) borderType /*" Returns our current border type, which will be one of NSNoBorder, NSLineBorder, NSBezelBorder or NSGrooveBorder. By default we use NSGrooveBorder. "*/ { return [[self cell] borderType]; } - (void) setBorderType:(NSBorderType)aType /*" Sets our current border type. aType can be one of NSNoBorder, NSLineBorder, NSBezelBorder or NSGrooveBorder. By default we use NSBezelBorder. "*/ { [[self cell] setBorderType:aType]; [self setNeedsDisplay:YES]; } - (BOOL) allowsSourceDragging /*" Returns YES if we are allowed to begin a dragging session. The default is YES. "*/ { return [[self cell] allowsSourceDragging]; } - (void) setAllowsSourceDragging:(BOOL)aBool /*" Sets whether we are allowed to begin a dragging session. The default is YES. "*/ { [[self cell] setAllowsSourceDragging:aBool]; } - (BOOL) allowsDestinationDragging /*" Returns YES if we are allowed to accept a drag. The default is YES. "*/ { return [[self cell] allowsDestinationDragging]; } - (void) setAllowsDestinationDragging:(BOOL)aBool /*" Sets whether we are allowed to accept a drag. The default is YES. "*/ { [[self cell] setAllowsDestinationDragging:aBool]; } - (BOOL) acceptsForeignDrag /*" Returns YES if we accept drags that don't originate from within our own application. The default is YES. "*/ { return [[self cell] acceptsForeignDrag]; } - (BOOL) acceptsLocalDrag /*" Returns YES if we accept drags that originate from within our own application. The default is YES. "*/ { return [[self cell] acceptsLocalDrag]; } - (BOOL) acceptsSelfDrag /*" Returns YES if we accept drags that originated from our own drag cell. The default is YES. You see this behavior in the Workspace shelf. If you drag a file from one of the cells you are still able to put it back in the same cell. "*/ { return [[self cell] acceptsSelfDrag]; } - (BOOL) retainsData /*" Returns YES if when we drag that we leave a copy of ourselves behind. If you were to emulate the Workspace shelf then this would return NO. The default is NO. "*/ { return [[self cell] acceptsLocalDrag]; } - (BOOL) shadowsIncoming /*" Returns YES if we show a dimmed image when there is an incoming drag. This assumes that we are currently accepting drags. The default is YES. "*/ { return [[self cell] shadowsIncoming]; } - (void) setShadowsIncoming:(BOOL)shadows /*" Sets whether we show a dimmed image when there is an incoming drag. The default is YES. "*/ { [[self cell] setShadowsIncoming:shadows]; } - (NSColor*) shadowColor /*" Returns the color used to created a dimmed appearance for a destination image. The default is to return a partially transparent gray. If you want a different appearance for shadowing, you can override this method. "*/ { return [[self cell] shadowColor]; } - (BOOL) dragImageSlidesBack /*" Returns YES if the dragging image should slide back to it's destination when it isn't deposited in another view. The default is to slide back only if we retain our data (#retainsData returns YES). "*/ { return [[self cell] dragImageSlidesBack]; } //------------------------------------------------------------------- // Title manipulation //------------------------------------------------------------------- - (NSString*) title /*" Returns our title. This may or may not be displayed depending on the return value of #displaysTitle. "*/ { return [[self cell] title]; } - (void) setTitle:(NSString*)newTitle /*" Sets our title. In subclasses it is your responsibility to set the title when you accept a drag. "*/ { [[self cell] setTitle:newTitle]; } - (BOOL) displaysTitle /*" Returns YES if we display a title in our view. The default is YES. "*/ { return [[self cell] displaysTitle]; } - (void) setDisplaysTitle:(BOOL)displays /*" Sets whether we display a title in our view. The default is YES. "*/ { [[self cell] setDisplaysTitle:displays]; } - (BOOL) isTitleEditable /*" Returns whether single or double clicking on the title will allow you to edit it. (Title editing NOT IMPLEMENTED YET) "*/ { return [[self cell] isTitleEditable]; } - (void) setTitleEditable:(BOOL)isEditable /*" Sets whether single or double clicking on the title will allow you to edit it. (Title editing NOT IMPLEMENTED YET) "*/ { [[self cell] setTitleEditable:isEditable]; } - (BOOL) isTitleMultiline /*" NOT IMPLEMENTED YET "*/ { return [[self cell] isTitleMultiline]; } - (void) setTitleMultiline:(BOOL)isMultiline /*" NOT IMPLEMENTED YET "*/ { [[self cell] setTitleMultiline:isMultiline]; } //------------------------------------------------------------------- // Delegation //------------------------------------------------------------------- - (id) delegate /*" Returns our delegate or nil if we don't have one. Right now there are no delegate messages but there will be soon (similar to the ones from the old drag view). "*/ { return _delegate; } - (void) setDelegate:(id)newDelegate /*" Sets our delegate to newDelegate. "*/ { _delegate = newDelegate; } //------------------------------------------------------------------- // Destination dragging setup //------------------------------------------------------------------- - (void) initializeDragTypes /*" This method registers the dragging types our cell is interested in receiving, by calling our drag cell's #acceptingPasteboardTypes method and registering them. This is called from both our #init method and #initWithCoder: so both new and unarchived drag views will be registered. "*/ { NSArray* draggedTypes; draggedTypes = [[self cell] acceptingPasteboardTypes]; if ([draggedTypes count] > 0) { [self registerForDraggedTypes:draggedTypes]; } } //------------------------------------------------------------------- // Overridden NSView methods //------------------------------------------------------------------- - (BOOL) acceptsFirstMouse:(NSEvent*)theEvent /*" Returns YES otherwise we wouldn't even get a #mouseDown: message. "*/ { return YES; } - (BOOL) shouldDelayWindowOrderingForEvent:(NSEvent*)theEvent /*" Returns YES but I'm not sure why any more? "*/ { return YES; } //------------------------------------------------------------------- // Archiving methods //------------------------------------------------------------------- - (id) initWithCoder:(NSCoder*)aDecoder /*" Unarchives an instance of MiscDragView. Returns self. "*/ { int version; // What used to be ivars in the older versions. NSSize imageSize; int border; BOOL allowSourceDragging; BOOL allowDestinationDragging; BOOL acceptForeignDrag; BOOL acceptLocalDrag; BOOL acceptSelfDrag; BOOL retainData; BOOL shadowIncoming; BOOL dragImageIsMyImage; id target; SEL action; [super initWithCoder:aDecoder]; version = [aDecoder versionForClassName:@"MiscDragView"]; /* * **** Archiving: READ ME **** This code (and its analogue in write:) is * critical. When you bump MISC_DRAG_VIEW_VERSION, copy the whole _current_ * case ("case MISC_DRAG_VIEW_VERSION: ... break;"), and duplicate it. * Change the "MISC_DRAG_VIEW_VERSION" in the old case to the OLD * (pre-bump) version number. Now, dork the "new current" version into * whatever you want. See how this code can now read EITHER version out of * the typed stream? * * If you are adding yet another version, leave the previous versions in * place. That way you can still read archived objects that are more than * one version old. Don't forget to take whatever actions are necessary to * harmonize those old values. For example, if you converted an "int" ivar * to "double", you'd need to (in the old version) to read the int version * into a temp variable, and convert it in to the double var. BJM 5/24/94 */ switch (version) { case 0: [self setImage:[aDecoder decodeObject]]; // We don't deal with image sizes anymore. imageSize = [aDecoder decodeSize]; [aDecoder decodeValuesOfObjCTypes:"i", &border]; [self setDelegate:[aDecoder decodeObject]]; [aDecoder decodeValuesOfObjCTypes:"c", &allowSourceDragging]; [aDecoder decodeValuesOfObjCTypes:"c", &allowDestinationDragging]; // We don't have ivars for the rest of these any more. [aDecoder decodeValuesOfObjCTypes:"cc", &acceptForeignDrag, &acceptLocalDrag]; [aDecoder decodeValuesOfObjCTypes:"cc", &acceptSelfDrag, &retainData]; // Keep the attributes that we still care about. [self setBorderType:(NSBorderType)border]; [self setAllowsSourceDragging:allowSourceDragging]; [self setAllowsDestinationDragging:allowDestinationDragging]; break; case 1: [self setImage:[aDecoder decodeObject]]; // We don't care about image size anymore. imageSize = [aDecoder decodeSize]; [aDecoder decodeValuesOfObjCTypes:"i", &border]; [self setDelegate:[aDecoder decodeObject]]; [aDecoder decodeValuesOfObjCTypes:"c", &allowSourceDragging]; [aDecoder decodeValuesOfObjCTypes:"c", &allowDestinationDragging]; // We don't use these values any more. [aDecoder decodeValuesOfObjCTypes:"cc", &acceptForeignDrag, &acceptLocalDrag]; [aDecoder decodeValuesOfObjCTypes:"cc", &acceptSelfDrag, &retainData]; // Version 1 adds target/action stuff -- shayman [aDecoder decodeValuesOfObjCTypes:"@:", &target, &action]; // Keep the attributes we still care about. [self setBorderType:(NSBorderType)border]; [self setAllowsSourceDragging:allowSourceDragging]; [self setAllowsDestinationDragging:allowDestinationDragging]; [self setTarget:target]; [self setAction:action]; break; case 2: [self setImage:[aDecoder decodeObject]]; // We don't care about image size anymore. imageSize = [aDecoder decodeSize]; [aDecoder decodeValuesOfObjCTypes:"i", &border]; [self setDelegate:[aDecoder decodeObject]]; [aDecoder decodeValuesOfObjCTypes:"c", &allowSourceDragging]; [aDecoder decodeValuesOfObjCTypes:"c", &allowDestinationDragging]; [aDecoder decodeValuesOfObjCTypes:"@:", &target, &action]; // Keep the attributes we still care about. [self setBorderType:(NSBorderType)border]; [self setAllowsSourceDragging:allowSourceDragging]; [self setAllowsDestinationDragging:allowDestinationDragging]; [self setTarget:target]; [self setAction:action]; break; case 3: [self setImage:[aDecoder decodeObject]]; // We don't care about the image size anymore. imageSize = [aDecoder decodeSize]; [aDecoder decodeValuesOfObjCTypes:"i", &border]; [self setDelegate:[aDecoder decodeObject]]; [aDecoder decodeValuesOfObjCTypes:"c", &allowSourceDragging]; [aDecoder decodeValuesOfObjCTypes:"c", &allowDestinationDragging]; [aDecoder decodeValuesOfObjCTypes:"@:", &target, &action]; [aDecoder decodeValuesOfObjCTypes:"cc", &shadowIncoming,&dragImageIsMyImage]; [self setAcceptingImage:[aDecoder decodeObject]]; break; case MISC_DRAG_VIEW_VERSION: // We now only have an ivar for our delegate. [self setDelegate:[aDecoder decodeObject]]; break; default: NSLog(@"[%@ %@] - unknown version of MiscDragView encountered.", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); break; } [self initializeDragTypes]; return self; } - (void) encodeWithCoder:(NSCoder *)aCoder /*" Encodes an instance of MiscDragView. "*/ { [super encodeWithCoder:aCoder]; [aCoder encodeConditionalObject:[self delegate]]; } @end @implementation MiscDragView (NSDraggingSource) /*" As you can see we just pass all these onto our cell. "*/ - (unsigned int) draggingSourceOperationMaskForLocal:(BOOL)flag { return [[self cell] draggingSourceOperationMaskForLocal:flag]; } - (void) draggedImage:(NSImage *)image endedAt:(NSPoint)screenPoint deposited:(BOOL)flag { [[self cell] draggedImage:image endedAt:screenPoint deposited:flag]; } @end @implementation MiscDragView (NSDraggingDestination) /*" All destination dragging is also handled by the cell. "*/ - (unsigned int) draggingEntered:(id <NSDraggingInfo>)sender { return [[self cell] draggingEntered:sender]; } - (unsigned int) draggingUpdated:(id <NSDraggingInfo>)sender { return [[self cell] draggingUpdated:sender]; } - (void) draggingExited:(id <NSDraggingInfo>)sender { [[self cell] draggingExited:sender]; } - (BOOL) prepareForDragOperation:(id <NSDraggingInfo>)sender { return [[self cell] prepareForDragOperation:sender]; } - (BOOL) performDragOperation:(id <NSDraggingInfo>)sender { return [[self cell] performDragOperation:sender]; } - (void) concludeDragOperation:(id <NSDraggingInfo>)sender { return [[self cell] concludeDragOperation:sender]; } @end /*************************************************************************** CHANGES: July 13, 1996 (1) Converted the code to OpenStep and moved all the dragging logic into MiscDragCell so down the road I (or someone else) can write a MiscDragMatrix. ****************************************************************************/
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.