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
// <<HACK>> This should be moved intot he Palette code !!
{
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;
// <<HACK>> The naming should be changed here...
[classToHold release];
classToHold = [name copy];
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 retain];
[objectToPaste addUser: self];
return [super draggingEntered: sender];
}
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
[users announce: @selector(shelf: dragWillExit:) with: sender];
[objectToPaste removeUser:self];
[objectToPaste release];
objectToPaste = nil;
[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 release];
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.