This is IKShelf.m in view mode; [Download] [Up]
#pragma .h #import <Foundation/NSString.h> #pragma .h #import "IKIconPath.h" #pragma .h #import "IKDependency.h" #pragma .h #pragma .h @interface NSObject (IKShelfAnnouncements) #pragma .h + (unsigned int) shelf: sender willDrag: objectToPaste from: (id <NSDraggingInfo>) source; #pragma .h + shelf: sender dragWillEnter: (id <NSDraggingInfo>) source; #pragma .h + shelf: sender dragWillExit: (id <NSDraggingInfo>) source; #pragma .h + shelf: sender dragWillComplete: (id <NSDraggingInfo>) source; #pragma .h @end #pragma .h #import <AppKit/AppKit.h> #import <InterfaceBuilder/InterfaceBuilder.h> #import <objc/objc-runtime.h> #import "IKAnnouncer.h" #import "IKfunctions.h" #import "IKShelf.h" #import "NSObject.LoadImage.h" @implementation IKShelf:IKIconPath #pragma .h <IKDependency> #pragma .h { #pragma .h id users, #pragma .h objectToPaste; #pragma .h #pragma .h NSString *classToHold; #pragma .h BOOL dynamic, #pragma .h lastIsEmptyContainer; #pragma .h } static NSImage * folder = nil; static NSSize defaultCellSize = { 70.0, 74.0 }; + (void)initialize { if (self == [IKShelf class]) { IKInitIDpboardType(); folder = [self loadImageFromBundle:@"IKFolder"]; } } - (NSString *) inspectorClassName { return ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) ? [super inspectorClassName] : @"IKShelfInspector"; } /* ========================================================================== */ - initWithFrame:(NSRect)frameRect { if ((self = [self initWithFrame:frameRect mode: NSHighlightModeMatrix cellClass: [IKCell class] numberOfRows: 0 numberOfColumns: 0]) != nil) { IKCell *aCell = [[IKCell alloc] init]; [aCell setLocked: YES]; [aCell setReallyLocked: NO]; [aCell setContainer: YES]; [self setPrototype:aCell]; if ([NSApp conformsTo: @protocol(IB)]) { id newVar = [self prototype]; [newVar setTitle:@"IconKit"]; [newVar setImage:folder]; } [self fillWithCells]; [self sizeToCells]; } return self; } - initWithFrame:(NSRect)frameRect mode:(int)aMode cellClass:class numberOfRows:(int)rows numberOfColumns:(int)cols { if ((self = [super initWithFrame:frameRect mode:aMode cellClass:class numberOfRows:rows numberOfColumns:cols]) != nil) { users = [[IKAnnouncer alloc] initOwner: self]; objectToPaste = nil; lastIsEmptyContainer = NO; dynamic = YES; [self setAutosizesCells:NO]; [self setClassToHold: @""]; [self setCellSize: defaultCellSize]; [self sizeCellsToFit]; } return self; } - (void)dealloc { [self unregisterDraggedTypes]; [users announce: @selector(willFree:)]; [users release]; [super dealloc]; } /* ========================================================================== */ - (id)initWithCoder:(NSCoder *)aDecoder { char * name; [super initWithCoder:aDecoder]; users = [[IKAnnouncer alloc] initOwner: self]; [aDecoder decodeValuesOfObjCTypes:"*c", &name, &dynamic]; [self setPrototype: [[aDecoder decodeObject] retain]]; [self setClassToHold:[NSString stringWithCString:name]]; free(name); return self; } - (void)encodeWithCoder:(NSCoder *)aCoder { const char *className = [classToHold cString]; [super encodeWithCoder:aCoder]; [aCoder encodeValuesOfObjCTypes:"*c", &className, &dynamic]; [aCoder encodeObject:[self prototype]]; } - (void)addUser: who { [users addUser: who]; } - (void)addListener: who { [users addListener: who]; } - (void)removeUser: who { [users removeUser: who]; } - (void)removeListener: who { [users removeListener: who]; } - (BOOL) isDynamic { return dynamic; } - (NSString *) classToHold { return classToHold; } - setDynamic: (BOOL) flag { dynamic = flag; return self; } - (void)setClassToHold: (NSString *) name { NSArray * pasteTypes; id class; if (classToHold) [classToHold release]; classToHold = name ? [name retain] : NULL; class = classToHold ? objc_lookUpClass([name cString]) : nil; pasteTypes = classToHold == NULL ? NULL: [class respondsTo: @selector(pasteTypes)] ? [class pasteTypes]: [classToHold length] == 0 ? IKIDPasteTypes(): NULL; if (pasteTypes != NULL) { [self unregisterDraggedTypes]; [self registerForDraggedTypes:pasteTypes]; } } - delegate { return [[self selectedCell] delegate]; } - (void)setFrameSize:(NSSize)_newSize { [super setFrameSize:(NSSize)_newSize]; if (dynamic) [[self fillWithCells] sizeCellsToFit]; } - fillWithCells { int rows = [self frame].size.height / [self cellSize].height, cols = [self frame].size.width / [self cellSize].width; [self renewRows:rows columns:cols]; [self sizeCellsToFit]; return self; } - sizeCellsToFit { NSSize gap; gap.height = _numRows > 1 ? ([self frame].size.height - [self cellSize].height * _numRows) / (_numRows - 1) : 0.0; gap.width = _numCols > 1 ? ([self frame].size.width - [self cellSize].width * _numCols) / (_numCols - 1) : 0.0; [self setIntercellSpacing:gap]; return self; } - (void)mouseDown:(NSEvent *)event { [super mouseDown:event]; if ([self mode] == NSHighlightModeMatrix) { [[self selectedCell] setState:0]; [self drawCell: [self selectedCell]]; [self selectCellAtRow:-1 column:-1]; } } - (unsigned int) draggingOperation: (id <NSDraggingInfo>) sender { id delegates = [users usersAndListeners], who; int i = [delegates count]; while (i--) { who = [delegates objectAtIndex: i]; if ([who respondsToSelector: @selector(shelf:willDrag:from:)]) return [who shelf: self willDrag: objectToPaste from: sender]; } return objectToPaste != nil ? NSDragOperationAll: NSDragOperationNone; } - (unsigned int) draggingEntered: (id <NSDraggingInfo>) sender { id class; [users announce: @selector(shelf: dragWillEnter:) with: sender]; lastIsEmptyContainer = NO; class = classToHold ? objc_lookUpClass([classToHold cString]) : nil; objectToPaste = class && [class respondsTo: @selector(readFromPasteboard:)] ? [class readFromPasteboard: [sender draggingPasteboard]] : IKReadID ([sender draggingPasteboard]); [objectToPaste addUser: self]; return [super draggingEntered: sender]; } - (void)draggingExited:(id <NSDraggingInfo>)sender { [users announce: @selector(shelf: dragWillExit:) with: sender]; [objectToPaste removeUser:self]; [super draggingExited:sender]; } - (unsigned int) cellEntered: (id <NSDraggingInfo>) sender { unsigned int op; if ( [current isEmptyContainer] && ((op = [self draggingOperation: sender]) != NSDragOperationNone)) { [current setGhosted: YES]; [current setDelegate:objectToPaste]; [self drawCell:current]; lastIsEmptyContainer = YES; return op; } else { return [super cellEntered: sender]; } } - (unsigned int) cellUpdated: (id <NSDraggingInfo>) sender { return lastIsEmptyContainer ? [self draggingOperation: sender]: [super cellUpdated: sender]; } - (void)cellExited:(id <NSDraggingInfo>)sender { if (lastIsEmptyContainer) { if(last) { [last setGhosted: NO]; [last setDelegate:nil]; [self drawCell:last]; } lastIsEmptyContainer = NO; } else { [super cellExited:sender]; } } - (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender { return !lastIsEmptyContainer ? [super prepareForDragOperation: sender] : YES; } - (BOOL) performDragOperation: (id <NSDraggingInfo>) sender { [objectToPaste removeUser: self]; objectToPaste = nil; if (lastIsEmptyContainer) { [current setGhosted: NO]; [self drawCell:current]; } return !lastIsEmptyContainer ? [super performDragOperation: sender] : YES; } - (void)concludeDragOperation:(id <NSDraggingInfo>)sender { [users announce: @selector(shelf:dragWillComplete:)]; return !lastIsEmptyContainer ? [super concludeDragOperation:sender] : nil; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.