home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-30 | 33.5 KB | 1,375 lines |
- #import "Fiend.h"
- #import "ShelfView.h"
- #import "IconView.h"
- #import "IconDragView.h"
- #import "ProgressView.h"
- #import "Controller.h"
- #import "Dock.h"
- #import "DockMgrView.h"
- #import "compositeBackground.h"
-
- #import <math.h>
- #import <appkit/appkit.h>
- #import <3Dkit/3Dkit.h>
- #import <ansi/stdio.h>
- #import <ansi/string.h>
-
- @implementation ShelfView
-
- - initFrame:(const NXRect *) aFrame
- {
- int screenCount;
- char *backgroundString;
- NXScreen *screens;
- const char *fileString;
- const char *colorString;
- const char *const types[1] = {NXFilenamePboardType};
-
- gridValue = atoi(NXGetDefaultValue([NXApp appName], SGRID_VALUE));
-
- [super initFrame:aFrame];
- [[self window] setDelegate:self];
- [self registerForDraggedTypes:types count:1];
-
- useBGColor = NO;
- [NXApp getScreens:&screens count:&screenCount];
-
- if (screens[0].depth == NX_TwoBitGrayDepth)
- backgroundString = "BWBackgroundColor";
- else
- backgroundString = "BackgroundColor";
-
- colorString = NXGetDefaultValue("NeXT1", backgroundString);
- if (colorString) {
- float r, g, b;
- sscanf(colorString, "%f %f %f", &r, &g, &b );
- bgColor = NXConvertRGBAToColor(r, g, b, NX_NOALPHA);
- useBGColor = YES;
- }
-
- fiendSound = [Sound findSoundFor:"Fiend"];
- destroySound = [Sound findSoundFor:"Destroy"];
-
- // [window disableFlushWindow];
- [self readShelf:YES];
-
- tileImage = -1;
- fileString = NXGetDefaultValue([NXApp appName], IMAGE_NAME);
- [self setImageFileName:fileString];
- [self setTileImage:!strcmp(NXGetDefaultValue([NXApp appName], TILE_IMAGE), "YES")];
- // [[window reenableFlushWindow] flushWindowIfNeeded];
-
- return self;
- }
-
-
- - free
- {
- if (theImage != nil)
- [theImage free];
- return [super free];
- }
-
-
- - (BOOL) acceptsFirstMouse
- {
- return YES;
- }
-
-
- - (NXColor) backgroundColor
- {
- if (useBGColor)
- return bgColor;
- else
- return NX_COLORLTGRAY;
- }
-
-
- - (BOOL)isAnyViewAt:(NXPoint)aPoint besides:aView useSlimMargin:(BOOL)flag
- {
- id *testView;
- int i;
- NXRect rect;
- int count = [subviews count];
- id *viewListPtr = (count > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
- NXRect interRect = {{aPoint.x, aPoint.y}, {gridValue, gridValue}};
-
- if (!flag)
- NXInsetRect(&interRect, 0.35*gridValue, 0.35*gridValue);
- for (i = 0, testView = viewListPtr; i < count; i++, testView++) {
- if (*testView == aView)
- continue;
- [*testView getFrame:&rect];
- if (NXIntersectsRect(&rect, &interRect))
- return YES;
- }
-
- return NO;
- }
-
-
- - (void)alignSubviews
- {
- id *view;
- int i;
- int viewCount = [subviews count];
- id *viewListPtr = (viewCount > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
-
- [window disableFlushWindow];
- for (i = 0, view = viewListPtr; i < viewCount; i++, view++) {
- NXRect rect;
- NXPoint candidatePt;
- int count;
-
- if (![*view isKindOf:[IconView class]] || ![*view state])
- continue;
-
- [*view getFrame:&rect];
- candidatePt.x = gridValue * (int)(rect.origin.x/gridValue);
- candidatePt.y = gridValue * (int)(rect.origin.y/gridValue);
-
- count = bounds.size.height * bounds.size.width / gridValue;
- while (count-- > 0 && [self isAnyViewAt:candidatePt besides:*view useSlimMargin:NO]) {
- candidatePt.x -= gridValue;
- if (candidatePt.x < 0) {
- candidatePt.x = gridValue;
- candidatePt.y -= gridValue;
- if (candidatePt.y < gridValue) {
- candidatePt.y = gridValue;
- candidatePt.x -= gridValue;
- }
-
- }
- }
-
- [*view moveTo:candidatePt.x :candidatePt.y];
- [*view setState:NO];
- }
-
- [self display];
- [[window reenableFlushWindow] flushWindowIfNeeded];
- [self writeShelf];
- }
-
-
- - (BOOL)tileImage
- {
- return tileImage;
- }
-
- - setTileImage:(BOOL)flag
- {
- NXSize imageSize;
-
- if (flag != tileImage) {
- tileImage = flag;
- if (theImage) {
- [theImage getSize:&imageSize];
- if (!tileImage && (NX_WIDTH(&frame) != imageSize.width || NX_HEIGHT(&frame) != imageSize.height))
- [theImage setSize:&frame.size];
- else if (tileImage && (imageSize.height != origImageSize.height || imageSize.width != origImageSize.width))
- [theImage setSize:&origImageSize];
- }
- [self update];
- }
-
- return self;
- }
-
- - (char *)getImageFileName
- {
- return imageFileName;
- }
-
- - setImageFileName:(const char *)theName
- {
- id image;
- id repList;
- int i;
- NXImageRep *rep;
-
- if (!theName || !strlen(theName)) {
- theImage = nil;
- imageFileName[0] = '\0';
- NXWriteDefault([NXApp appName], IMAGE_NAME, "");
- }
- else if (strcmp(imageFileName, theName)) {
- image = [[NXImage allocFromZone:[self zone]] initFromFile:theName];
- strcpy(imageFileName, theName);
- // NXWriteDefault([NXApp appName], IMAGE_NAME, imageFileName);
-
- if (image != nil) {
- if ([image lockFocus]) {
- [image unlockFocus];
- if (theImage != nil)
- [theImage free];
- theImage = image;
- }
- else
- return nil;
- }
- else
- return nil;
-
- repList = [theImage representationList];
- for(i = 0; i < [repList count]; i++) {
- rep = [repList objectAt:i];
- if ([rep isKindOf:[N3DRIBImageRep class]]) {
- [(N3DRIBImageRep *)rep setSurfaceType:N3D_FacetedSolids];
- break;
- }
- }
- [theImage setScalable:YES];
- [theImage getSize:&origImageSize];
- if (!tileImage)
- [theImage setSize:&frame.size];
- }
-
- [self update];
-
- return self;
- }
-
- - (BOOL) gridEnabled
- {
- return !strcmp(NXGetDefaultValue([NXApp appName], GRID_ENABLE), "YES");
- }
-
-
- - (void)setGridEnabled:(BOOL) flag
- {
- (void) NXWriteDefault([NXApp appName], GRID_ENABLE, flag ? "YES" : "NO");
- }
-
-
- - (int)gridValue
- {
- return gridValue;
- }
-
-
- - setGridValue:(int)aValue
- {
- if (aValue == gridValue)
- return self;
-
- gridValue = aValue;
-
- if (gridValue < MIN_GRID_VALUE)
- gridValue = MIN_GRID_VALUE;
- else if (gridValue > MAX_GRID_VALUE)
- gridValue = MAX_GRID_VALUE;
-
- // gridChanged = YES;
- [window disableFlushWindow];
- [[self subviews] freeObjects];
- [IconView resetCachedShelfImages];
- [[self readShelf:NO] display];
- [[window reenableFlushWindow] flushWindowIfNeeded];
-
- return self;
- }
-
- - drawSelf:(const NXRect *) rects :(int) rectCount
- {
- int i;
-
- int j;
- int rectIndex;
- int vertCount;
- int horizCount;
- NXPoint thePoint;
- NXRect interRect;
- BOOL compositeShelf = !strcmp(NXGetDefaultValue([NXApp appName], CPST_SHLF), "YES");
- NXRect theRect = {{0.0, 0.0}, {0.0, 0.0}};
-
- if (theImage != nil) {
- NXSetColor(bgColor);
- NXRectFill(rects);
- [theImage getSize:&theRect.size];
- vertCount = NX_HEIGHT(&frame)/NX_HEIGHT(&theRect);
- horizCount = NX_WIDTH(&frame)/NX_WIDTH(&theRect);
- rectIndex = (rectCount == 3) ? 1 : 0;
- for(rectIndex = 0; rectIndex < rectCount; rectIndex++) {
- for(i = 0; i < horizCount+1; i++) {
- for(j = 0; j < vertCount+1; j++) {
- NXSetRect(&interRect, NX_WIDTH(&theRect)*i, NX_HEIGHT(&theRect)*j,
- NX_WIDTH(&theRect), NX_HEIGHT(&theRect));
- if (NXIntersectionRect(&rects[rectIndex], &interRect)) {
- thePoint = interRect.origin;
- NX_X(&interRect) = fmod(NX_X(&interRect), NX_WIDTH(&theRect));
- NX_Y(&interRect) = fmod(NX_Y(&interRect), NX_HEIGHT(&theRect));
- [theImage composite:NX_SOVER fromRect:&interRect toPoint:&thePoint];
- }
- }
- }
- }
- }
- else if (useBGColor && !compositeShelf) {
- NXSetColor(bgColor);
- NXRectFill(rects);
- }
- else
- compositeFromWorkspaceWindow(rects->origin.x, rects->origin.y,
- rects->size.width, rects->size.height);
-
- return self;
- }
-
-
- - deselectAll:sender
- {
- id *view;
- int i;
- int count = [subviews count];
- id *viewListPtr = (count > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
-
- [window disableFlushWindow];
- for(i = 0, view = viewListPtr; i < count; i++, view++) {
- if ([*view state])
- [*view setState:NO];
- }
- [[window reenableFlushWindow] flushWindowIfNeeded];
-
- [[NXApp delegate] updateMenus];
- return self;
- }
-
-
- - removeView:aView
- {
- NXRect viewFrame;
-
- [aView getFrame:&viewFrame];
- [aView removeFromSuperview];
- [self display:&viewFrame :1 :NO];
- return self;
- }
-
-
- - addView:aView
- {
- NXRect viewFrame;
-
- [aView getFrame:&viewFrame];
- [self addSubview:aView];
- [self display:&viewFrame :1 :NO];
- return self;
- }
-
-
- - deleteView:aView
- {
- [self removeView:aView];
- [aView free];
- return self;
- }
-
-
- /*
- * Return true if the point is in the area we use to get rid of views
- */
- - (BOOL) isDeadZone:(NXPoint *) aPoint
- {
- NXRect goodZone = bounds;
- NXInsetRect(&goodZone, 2, 2);
- return !NXMouseInRect(aPoint, &goodZone, NO);
- }
-
-
- - (void)createViewForPath:(const char *)path withImage:(NXImage *)image at:(NXPoint *)point
- {
- id newImage;
- id newView;
- BOOL drawThumbnail = !strcmp(NXGetDefaultValue([NXApp appName], DRAW_TNAIL), "YES");
- NXRect aRect = {{0.0, 0.0}, {gridValue, gridValue}};
-
- if (image == nil)
- newImage = [IconView getImageForPath:path fileIcon:!drawThumbnail zone:[self zone]];
- else
- newImage = [image copyFromZone:[self zone]];
- newView = [[IconDragView allocFromZone:[self zone]] initFrame:&aRect image:newImage
- data:path andLength:strlen(path)+1 useSize:YES onDock:NO];
-
- aRect.origin = *point;
- if (NX_MAXX(&aRect) > NX_WIDTH(&frame))
- NX_X(&aRect) = fmod(point->x, NX_WIDTH(&frame)-gridValue);
- if (NX_MAXY(&aRect) > NX_HEIGHT(&frame))
- NX_Y(&aRect) = fmod(point->y, NX_HEIGHT(&frame)-gridValue);
- [[newView setFrame:&aRect] display];
-
- [self addSubview:newView];
- [newView getFrame:&aRect];
- [self display:&aRect :1 :NO];
- }
-
-
- - (NXPoint)viewLocationForContext:(id <NXDraggingInfo>)dragContext
- {
- NXPoint newLoc;
- NXPoint imageOffset;
- NXPoint imagePt = [dragContext draggedImageLocation];
- NXPoint mousePt = [dragContext draggingLocation];
- BOOL gridEnabled = !strcmp(NXGetDefaultValue([NXApp appName], GRID_ENABLE), "YES");
-
- [draggedView getImagePoint:&imageOffset andHilitePoint:NULL];
-
- if (gridEnabled) {
- NXRect rect;
- [draggedView getFrame:&rect];
-
- newLoc.x = mousePt.x - ((int) mousePt.x % gridValue) +
- (gridValue - rect.size.width) / 2;
- newLoc.y = mousePt.y - (int) mousePt.y % gridValue;
- }
- else {
- newLoc.x = imagePt.x - imageOffset.x;
- newLoc.y = imagePt.y - imageOffset.y;
- }
- return newLoc;
- }
-
-
- - createDraggedView:(id <NXDraggingInfo>)sender
- {
- NXSize aSize;
- NXPoint newLoc;
- BOOL gridEnabled = !strcmp(NXGetDefaultValue([NXApp appName], GRID_ENABLE), "YES");
-
- aSize.width = [self gridValue];
- aSize.height = aSize.width;
- draggedView = [[IconView allocFromZone:[self zone]]
- initFromDragContext:sender andSize:&aSize onDock:NO];
-
- newLoc = [self viewLocationForContext:sender];
- [draggedView moveTo:newLoc.x :newLoc.y];
-
- [draggedView setGhost:YES];
- if (gridEnabled)
- [self addView:draggedView];
-
- return self;
- }
-
- - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender
- {
- id source = [sender draggingSource];
- BOOL localSrc = [sender isDraggingSourceLocal];
- BOOL strict = !strcmp(NXGetDefaultValue([NXApp appName], SSTRICT_COPY), "YES");
- NXDragOperation mask = [sender draggingSourceOperationMask];
-
- if (mask == NX_DragOperationPrivate || (localSrc && [source isKindOf:[IconView class]]) ||
- (!localSrc &&
- ((strict && mask != NX_DragOperationCopy) ||
- (!strict && !(mask & NX_DragOperationCopy))))) {
-
- draggedView = nil;
- return NX_DragOperationNone;
- }
-
- [self createDraggedView:sender];
- return (mask == NX_DragOperationCopy) ? NX_DragOperationCopy :
- ((localSrc)?NX_DragOperationGeneric:NX_DragOperationCopy);
- }
-
-
- - (NXDragOperation)draggingUpdated:(id <NXDraggingInfo>)sender
- {
- NXRect aFrame;
- NXPoint newLoc;
- id source = [sender draggingSource];
- BOOL localSrc = [sender isDraggingSourceLocal];
- NXDragOperation mask = [sender draggingSourceOperationMask];
- BOOL gridEnabled = !strcmp(NXGetDefaultValue([NXApp appName], GRID_ENABLE), "YES");
- BOOL strict = !strcmp(NXGetDefaultValue([NXApp appName], SSTRICT_COPY), "YES");
-
- if (mask == NX_DragOperationPrivate || (localSrc && [source isKindOf:[IconView class]]) ||
- (!localSrc &&
- ((strict && mask != NX_DragOperationCopy) ||
- (!strict && !(mask & NX_DragOperationCopy))))) {
-
- if (draggedView) {
- [self removeView:draggedView];
- [draggedView free];
- draggedView = nil;
- }
- return NX_DragOperationNone;
- }
-
- if (!draggedView)
- [self createDraggedView:sender];
- newLoc = [self viewLocationForContext:sender];
-
- if (gridEnabled) {
- [draggedView getFrame:&aFrame];
- if (aFrame.origin.x != newLoc.x || aFrame.origin.y != newLoc.y) {
- [draggedView moveTo:newLoc.x :newLoc.y];
- [self display:&aFrame :1 :NO]; /* erase old */
- aFrame.origin = newLoc;
- [self display:&aFrame :1 :NO]; /* draw new */
- }
- }
-
- if (localSrc)
- [source setKeepDraggedIcons:(mask == NX_DragOperationCopy)];
- return (mask == NX_DragOperationCopy) ? NX_DragOperationCopy :
- ((localSrc)?NX_DragOperationGeneric:NX_DragOperationCopy);
- }
-
-
- - (int)getHorizLimit:(char *)dragString sep:(char *)sep ctrl:(BOOL)ctrl
- {
- char *ptr;
- int horizLimit;
-
- horizLimit = 10000;
- if (strlen(dragString) && !ctrl) {
- horizLimit = 0;
- ptr = dragString;
- while(*ptr) {
- if (*ptr == *sep)
- horizLimit++;
- ptr++;
- }
- horizLimit = (int)sqrt((float)horizLimit);
- }
- return horizLimit;
- }
-
- /*
- * Get rid of the resources we used to drag the image around.
- */
- - draggingExited:(id <NXDraggingInfo>)sender
- {
- BOOL gridEnabled = !strcmp(NXGetDefaultValue([NXApp appName], GRID_ENABLE), "YES");
-
- if ([sender draggingSource] != self &&
- !([sender draggingSourceOperationMask] & NX_DragOperationCopy)) {
- if (draggedView) {
- [self removeView:draggedView];
- [draggedView free];
- draggedView = nil;
- }
- return self;
- }
-
- if (gridEnabled)
- [self removeView:draggedView];
- [draggedView free];
-
- return self;
- }
-
-
- /*
- * Eat the result...
- */
- - (BOOL)prepareForDragOperation:sender
- {
- // NXLogError("shelf prepareForDragOperation");
- return YES;
- }
-
-
- - (BOOL)performDragOperation:sender
- {
- NXPoint mouseLoc;
- NXPoint newLoc;
-
- newLoc = [self viewLocationForContext:sender];
- mouseLoc = [sender draggingLocation];
- if ([self isDeadZone:&mouseLoc]) {
- [self removeView:draggedView];
- [draggedView free];
- draggedView = nil;
- return NO;
- }
-
- [draggedView moveTo:newLoc.x :newLoc.y];
- return YES;
- }
-
-
- - selectViewsInRect:(NXRect *)theRect deselect:(BOOL)flag
- {
- id *theView;
- int i;
- NXRect viewRect;
- NXPoint thePoint;
- BOOL found = NO;
- int count = [subviews count];
- id *viewListPtr = (count > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
-
- [window disableFlushWindow];
- for(i = 0, theView = viewListPtr; i < count; i++, theView++) {
- if (*theView == nil || ![*theView isKindOf:[IconView class]])
- continue;
- [*theView getFrame:&viewRect];
- thePoint.x = NX_MIDX(&viewRect);
- thePoint.y = NX_MIDY(&viewRect);
- if (NXIntersectsRect(&viewRect, theRect)) {
- if (!flag)
- [*theView setState:![*theView state]];
- else
- [*theView setState:YES];
- found = YES;
- }
- else if (flag)
- [*theView setState:NO];
- }
- [[window reenableFlushWindow] flushWindowIfNeeded];
-
- if (found) {
- [NXApp unhide:self];
- [[NXApp delegate] updateMenus];
- }
- return self;
- }
-
- - nukeViewsInRect:(NXRect *)theRect
- {
- id *theView;
- id *killListPtr;
- int i;
- NXRect viewRect;
- NXPoint thePoint;
- int count = [subviews count];
- id killList = [[List allocFromZone:[self zone]] init];
- id *viewListPtr = (count > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
- BOOL useSound = !strcmp(NXGetDefaultValue([NXApp appName], USE_SOUND), "YES");
-
- [window disableFlushWindow];
- for(i = 0, theView = viewListPtr; i < count; i++, theView++) {
- if (*theView == nil || ![*theView isKindOf:[IconView class]])
- continue;
- [*theView getFrame:&viewRect];
- thePoint.x = NX_MIDX(&viewRect);
- thePoint.y = NX_MIDY(&viewRect);
- if (NXIntersectsRect(&viewRect, theRect))
- [killList addObject:*theView];
- }
- count = [killList count];
- killListPtr = (count > 0) ? NX_ADDRESS(killList) : (id *)NULL;
- for(i = 0, theView = killListPtr; i < count; i++, theView++)
- [self deleteView:*theView];
- [[window reenableFlushWindow] flushWindowIfNeeded];
-
- [killList free];
- if (count) {
- if (useSound)
- [destroySound play:self];
- [[NXApp delegate] updateMenus];
- [self writeShelf];
- }
- return self;
- }
-
- - deleteSelectedCells
- {
- id *view;
- int i;
- id *cutListPtr = (id *)NULL;
- int count = [subviews count];
- id cutList = [[List allocFromZone:[self zone]] init];
- id *viewListPtr = (count > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
-
- [window disableFlushWindow];
- for(i = 0, view = viewListPtr; i < count; i++, view++) {
- if ([*view state])
- [cutList addObject:*view];
- }
- count = [cutList count];
- cutListPtr = (count > 0) ? NX_ADDRESS(cutList) : (id *)NULL;
- for(i = 0, view = cutListPtr; i < count; i++, view++)
- [self deleteView:*view];
-
- [[window reenableFlushWindow] flushWindowIfNeeded];
- [cutList free];
- if (count) {
- [[NXApp delegate] updateMenus];
- [self writeShelf];
- }
-
- return self;
- }
-
- - mouseDown:(NXEvent *)event
- {
- int selCnt;
- int savedMask;
- NXPoint p;
- NXRect theRect;
- BOOL started = NO;
- NXPoint origPt = event->location;
- int mask = NX_MOUSEDRAGGEDMASK|NX_MOUSEUPMASK;
- BOOL alt = (event->flags & NX_ALTERNATEMASK) ? YES : NO;
- BOOL cmd = (event->flags & NX_COMMANDMASK) ? YES : NO;
- BOOL ctrl = (event->flags & NX_CONTROLMASK) ? YES : NO;
- BOOL shift = (event->flags & NX_SHIFTMASK) ? YES : NO;
-
- if (event->data.mouse.click == 2) {
- [NXApp unhide:self];
- [[NXApp delegate] updateMenus];
- return self;
- }
-
- savedMask = [window addToEventMask:NX_MOUSEDRAGGEDMASK];
- if (!shift && !ctrl && (cmd || alt) && ((selCnt = [self hasSelectedCells]) != 0)) {
- NXImage *dragImage;
- Pasteboard *pb = [Pasteboard newName:NXDragPboard];
-
- if (selCnt == 1)
- dragImage = [IconView getImageForPath:[self selectedCellPath] fileIcon:YES zone:[self zone]];
- else
- dragImage = [[NXImage allocFromZone:[self zone]] initFromSection:"Sheaf"];
-
- dragSourceView = nil;
- origPt.x -= 32.0; origPt.y -= 32.0;
-
- keepDraggedIcons = alt;
- [self copy:self toPasteboard:pb andCut:NO];
- [self dragImage:dragImage at:&origPt offset:&frame.origin
- event:event pasteboard:pb source:self slideBack:YES];
- [dragImage free];
-
- [self deselectAll:self];
- [window setEventMask:savedMask];
- [[NXApp delegate] updateMenus];
- return self;
- }
- do {
- if (!started) {
- [self lockFocus];
- PSsetgray(NX_BLACK);
- PSsetinstance(YES);
- started = YES;
- }
-
- p = event->location;
- NX_X(&theRect) = (origPt.x < p.x) ? origPt.x : p.x;
- NX_Y(&theRect) = (origPt.y < p.y) ? origPt.y : p.y;
- NX_WIDTH(&theRect) = fabs(origPt.x - p.x);
- NX_HEIGHT(&theRect) = fabs(origPt.y - p.y);
- PSnewinstance();
- NXFrameRect(&theRect);
- event = [NXApp getNextEvent:mask];
- } while (event && event->type != NX_MOUSEUP);
-
- if (started) {
- PSnewinstance();
- PSsetinstance(NO);
- [self unlockFocus];
- PSsetgray(NX_BLACK);
- if (ctrl)
- [self nukeViewsInRect:&theRect];
- else {
- [[NXApp delegate] deselectDock];
- [self selectViewsInRect:&theRect deselect:!shift];
- }
- }
-
- [window setEventMask:savedMask];
- [[NXApp delegate] updateMenus];
- return self;
- }
-
- - setKeepDraggedIcons:(BOOL)flag
- {
- keepDraggedIcons = flag;
- return self;
- }
-
- - getNextFrame:(NXRect *)theFrame firstFrame:(NXRect *)firstFrame limit:(float)limit useSlimMargin:(BOOL)flag
- {
- int maxTries;
- NXRect origFrame = *theFrame;
- BOOL goingDown = TRUE;
-
- if (NXContainsRect(&frame, theFrame) &&
- ![self isAnyViewAt:theFrame->origin besides:draggedView useSlimMargin:flag])
- return self;
-
- theFrame->origin = firstFrame->origin;
- maxTries = NX_WIDTH(&frame) * NX_HEIGHT(&frame)/(gridValue * gridValue);
- while (maxTries) {
- /* scan left */
- do {
- maxTries--;
- NX_X(theFrame) -= NX_WIDTH(theFrame);
- } while ((NX_X(theFrame) > 0.0) && ((NX_X(firstFrame) - NX_X(theFrame))/NX_WIDTH(theFrame) <= limit) &&
- ([self isAnyViewAt:theFrame->origin besides:draggedView useSlimMargin:flag]));
-
- /* if we're within bounds, we're done */
- if (NX_X(theFrame) > 0.0 && ((NX_X(firstFrame) - NX_X(theFrame))/NX_WIDTH(theFrame) <= limit))
- return self;
- else {
- if (goingDown) {
- if (NX_Y(theFrame) >= NX_HEIGHT(theFrame))
- NX_Y(theFrame) -= NX_HEIGHT(theFrame);
- else {
- goingDown = NO;
- NX_Y(theFrame) = NX_MAXY(&origFrame);
- }
- }
- else {
- if (NX_MAXY(theFrame) <= NX_HEIGHT(&frame))
- NX_Y(theFrame) += NX_HEIGHT(theFrame);
- else {
- limit = 100.0;
- goingDown = YES;
- NX_Y(theFrame) = NX_Y(firstFrame);
- }
- }
- NX_X(theFrame) = NX_MAXX(firstFrame);
- }
- }
-
- return self;
- }
-
-
- - concludeDragOperation:(id <NXDraggingInfo>)sender
- {
- id oldImage;
- int len;
- int count;
- int horizLimit;
- int horizCount;
- char *ptr;
- char *path;
- char *dragString;
- NXRect newFrame;
- NXRect viewFrame;
- BOOL useSound = !strcmp(NXGetDefaultValue([NXApp appName], USE_SOUND), "YES");
- BOOL srcIsDockMgr = [[sender draggingSource] isKindOf:[DockMgrView class]];
-
- [draggedView getFrame:&viewFrame];
- newFrame = viewFrame;
- // NX_X(&newFrame) = NX_MAXX(&viewFrame);
-
- count = 0;
- horizCount = 0;
- horizLimit = 1000;
- [draggedView getData:(void **)&dragString andLength:&len];
- if ([sender draggingSourceOperationMask]/* & NX_DragOperationCopy*/) {
- ptr = dragString;
- while(*ptr) {
- if (*ptr == '\t')
- count++;
- ptr++;
- }
- horizLimit = (int)sqrt((float)count);
- }
-
- [window disableFlushWindow];
- path = strtok(dragString, "\t");
- while(path && strlen(path)) {
- oldImage = (!count && [sender isDraggingSourceLocal] && !srcIsDockMgr)? [draggedView image] : nil;
- [self getNextFrame:&newFrame firstFrame:&viewFrame limit:(float)horizLimit useSlimMargin:NO];
- [self createViewForPath:path withImage:oldImage at:&newFrame.origin];
- NXPing();
- path = strtok(NULL, "\t");
- }
- [[window reenableFlushWindow] flushWindowIfNeeded];
-
- if (useSound && (![sender isDraggingSourceLocal] || srcIsDockMgr))
- [fiendSound play];
-
- if (draggedView != nil) {
- [self removeView:draggedView];
- [draggedView free];
- }
- [[NXApp delegate] updateMenus];
- [self perform:@selector(writeShelf) with:nil afterDelay:1000.0 cancelPrevious:YES];
- return self;
- }
-
- - setDragView:aView onEvent:(NXEvent *) e withOffset:(NXPoint *) offset
- atLocation:(const NXPoint *) location
- {
- void *data;
- int length;
- NXPoint myLoc;
- // NXSize viewSize = {gridValue, gridValue};
- id pb = [Pasteboard newName:NXDragPboard];
- // NXImage *dragImage = [[NXImage allocFromZone:[self zone]] initSize:&viewSize];
-
- dragSourceView = aView;
- keepDraggedIcons = (e->flags & NX_ALTERNATEMASK) ? YES : NO;
-
- [aView getData:&data andLength:&length];
- [pb declareTypes:&NXFilenamePboardType num:1 owner:nil];
- [pb writeType:NXFilenamePboardType data:data length:length];
-
- /*
- [aView allocateGState];
- [aView lockFocus]; [aView unlockFocus];
- if ([dragImage lockFocus]) {
- PScompositerect(0.0, 0.0, gridValue, gridValue, NX_CLEAR);
- PScomposite(0.0, 0.0, gridValue, gridValue, [aView gState], 0.0, 0.0, NX_COPY);
- [dragImage unlockFocus];
- }
- [aView freeGState];
- */
- myLoc = *location;
- [aView convertPoint:&myLoc toView:self];
- [self dragImage:[aView image] at:&myLoc offset:offset event:e pasteboard:pb
- source:self slideBack:YES];
-
- // [dragImage free];
- [self deselectAll:self];
- // [self display];
-
- return self;
- }
-
- - draggedImage:(NXImage *)image beganAt:(NXPoint *)screenPoint
- {
- NXRect theFrame;
-
- if (dragSourceView != nil) {
- [dragSourceView getFrame:&theFrame];
- [self display:&theFrame :1 :NO];
- if (!keepDraggedIcons)
- [self removeView:dragSourceView];
- }
-
- return self;
- }
-
-
- - draggedImage:(NXImage *)image endedAt:(NXPoint *)screenPoint
- deposited:(BOOL)didDeposit
- {
- if (dragSourceView != nil) {
- if (didDeposit && !keepDraggedIcons)
- [self deleteView:dragSourceView];
- else
- [self addView:dragSourceView];
- }
- else if (didDeposit && !keepDraggedIcons)
- [self deleteSelectedCells];
-
- [[NXApp delegate] updateMenus];
- return self;
- }
-
-
- - (NXDragOperation) draggingSourceOperationMaskForLocal:(BOOL)flag
- {
- return NX_DragOperationAll;
- }
-
-
- - (const char *)selectedCellPath
- {
- id *view;
- int i;
- int len;
- char *path = "";
- int count = [subviews count];
- id *viewListPtr = (count > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
-
- for(i = 0, view = viewListPtr; i < count; i++, view++) {
- if ([*view state]) {
- [*view getData:(void *)&path andLength:&len];
- break;
- }
- }
- return (const char *)path;
- }
-
- - (int)hasSelectedCells
- {
- id *view;
- int i;
- int selCnt = 0;
- int count = [subviews count];
- id *viewListPtr = (count > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
-
- for(i = 0, view = viewListPtr; i < count; i++, view++) {
- if ([*view state])
- selCnt++;
- }
- return selCnt;
- }
-
- - copy:sender toPasteboard:pb andCut:(BOOL)cutFlag
- {
- id *aView;
- id *cutListPtr;
- int i;
- int junk;
- int length;
- int maxLength;
- char *viewPath;
- NXRect frameRect;
- char *cutString;
- NXPoint refPt = {-16000.0, -16000.0};
- int count = [subviews count];
- id *viewListPtr = (count > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
- id cutList = [[List allocFromZone:[self zone]] init];
- BOOL useSound = !strcmp(NXGetDefaultValue([NXApp appName], USE_SOUND), "YES");
- NXStream *theStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- const char *types[] = {FIEND_PBTYPE, NXFilenamePboardType, NXAsciiPboardType};
-
- [pb declareTypes:types num:3 owner:nil];
-
- for(i = 0, aView = viewListPtr; i < count; i++, aView++) {
- if ([*aView state]) {
- [*aView getFrame:&frameRect];
- refPt.x = (refPt.x > NX_MAXX(&frameRect)) ? refPt.x : NX_MAXX(&frameRect);
- refPt.y = (refPt.y > NX_MAXY(&frameRect)) ? refPt.y : NX_MAXY(&frameRect);
- [cutList addObject:*aView];
- }
- }
-
- NXPrintf(theStream, "SHELF\t");
- count = [cutList count];
- cutListPtr = (count > 0) ? NX_ADDRESS(cutList) : (id *)NULL;
- for(i = 0, aView = cutListPtr; i < count; i++, aView++) {
- [*aView getFrame:&frameRect];
- [*aView getData:(void **)&viewPath andLength:&junk];
- NXPrintf(theStream,"%6d%7.2f%7.2f %s\t", 0,
- (NX_MAXX(&frameRect) - refPt.x)/gridValue,
- (NX_MAXY(&frameRect) - refPt.y)/gridValue,
- viewPath);
- }
- NXGetMemoryBuffer(theStream, &cutString, &length, &maxLength);
- [pb writeType:FIEND_PBTYPE data:cutString length:strlen(cutString)];
- NXClose(theStream);
-
- length = 0;
- theStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- for(i = 0, aView = cutListPtr; i < count; i++, aView++) {
- [*aView getData:(void **)&viewPath andLength:&junk];
- NXPrintf(theStream, "%s\t", viewPath);
- }
- NXGetMemoryBuffer(theStream, &cutString, &length, &maxLength);
- cutString[strlen(cutString)-1] = '\0';
- [pb writeType:NXFilenamePboardType data:cutString length:strlen(cutString)];
-
- for(i = 0; i < strlen(cutString); i++) {
- if (cutString[i] == '\t')
- cutString[i] = '\n';
- }
- if (cutString[strlen(cutString)-1] != '\n') strcat(cutString, "\n");
- [pb writeType:NXAsciiPboardType data:cutString length:strlen(cutString)];
- NXClose(theStream);
-
- if (cutFlag) {
- if (useSound)
- [destroySound play:self];
- [window disableFlushWindow];
- for(i = 0, aView = cutListPtr; i < count; i++, aView++)
- [self deleteView:*aView];
- [[window reenableFlushWindow] flushWindowIfNeeded];
- }
-
- [cutList free];
- [[NXApp delegate] updateMenus];
- [self perform:@selector(writeShelf) with:nil afterDelay:1000.0 cancelPrevious:YES];
-
- return self;
- }
-
- - showInsertCursor:(NXPoint *)locus ctrl:(BOOL *)ctrl
- {
- NXEvent *event;
-
- [NXIBeam push];
- do {
- event = [NXApp getNextEvent:NX_MOUSEDOWNMASK|NX_MOUSEDRAGGEDMASK];
- } while (event && event->type != NX_MOUSEDOWN);
- *ctrl = (event->flags & NX_CONTROLMASK) ? YES : NO;
- [NXIBeam pop];
- *locus = event->location;
-
- return self;
- }
-
- - paste:sender toPasteboard:pb
- {
- int len;
- int horizLimit;
- int horizCount;
- int launchFlag;
- char *path;
- char *dragString;
- char tokenString[500];
- BOOL ctrl;
- BOOL fromDock;
- BOOL fromShelf;
- NXRect newFrame;
- NXCoord x;
- NXCoord y;
- NXPoint locus;
- NXPoint newPoint;
- NXPoint maxOffset;
- const char *type;
- char *sep = "\t";
- NXRect bogusFrame = {{-1000.0, -1000.0}, {gridValue, gridValue}};
- NXRect viewFrame = {{0.0, 0.0}, {gridValue, gridValue}};
- BOOL gridEnabled = !strcmp(NXGetDefaultValue([NXApp appName], GRID_ENABLE), "YES");
- BOOL useSound = !strcmp(NXGetDefaultValue([NXApp appName], USE_SOUND), "YES");
- const char *types[] = {FIEND_PBTYPE, NXFilenamePboardType};
-
- type = [pb findAvailableTypeFrom:types num:2];
- if (type && !strcmp(type, FIEND_PBTYPE)) {
- if (![pb readType:FIEND_PBTYPE data:&dragString length:&len])
- return self;
- sep = "\t";
- }
- else if (type && !strcmp(type, NXFilenamePboard)) {
- if (![pb readType:NXFilenamePboardType data:&dragString length:&len])
- return self;
- sep = "\t";
- }
- /*
- else if (!strcmp(type, NXAsciiPboard)) {
- if (![pb readType:NXAsciiPboardType data:&dragString length:&len])
- return self;
- sep = "\n";
- }
- */
- else {
- NXBeep();
- return self;
- }
-
- if (len == 0) {
- NXBeep();
- return self;
- }
-
- if (pb != [Pasteboard new]) {
- NXRunAlertPanel([NXApp appName],
- "Click mouse to choose site...",
- "Ok", NULL, NULL);
- }
-
- [self showInsertCursor:&locus ctrl:&ctrl];
- if (gridEnabled) {
- locus.x = locus.x - (int)locus.x % gridValue;
- locus.y = locus.y - (int)locus.y % gridValue;
- }
-
- viewFrame.origin = newPoint = locus;
- newFrame = viewFrame;
-
- horizCount = 0;
- horizLimit = [self getHorizLimit:dragString sep:sep ctrl:ctrl];
- [window disableFlushWindow];
- path = strtok(dragString, sep);
- fromDock = (!strcmp(path, "DOCK")) ? YES : NO;
- fromShelf = (!strcmp(path, "SHELF")) ? YES : NO;
- if (fromDock) {
- path = strtok(NULL, sep);
- sscanf(path, "%f %f", &maxOffset.x, &maxOffset.y);
- }
- if (fromDock || fromShelf)
- path = strtok(NULL, sep);
- while(path && strlen(path)) {
- if (!strcmp(type, FIEND_PBTYPE)) {
- sscanf(path, "%d %f %f %[^\n\t]", &launchFlag, &x, &y, tokenString);
- if (fromDock) {
- x -= maxOffset.x;
- y -= maxOffset.y;
- }
- NX_X(&newFrame) = locus.x + (x - 1.0) * gridValue;
- NX_Y(&newFrame) = locus.y + (y - 1.0) * gridValue;
- }
- else
- strcpy(tokenString, path);
- if (ctrl) newFrame = bogusFrame;
- [self getNextFrame:&newFrame firstFrame:&viewFrame
- limit:(float)horizLimit useSlimMargin:NO];
- [self createViewForPath:tokenString withImage:nil at:&newFrame.origin];
- NXPing();
- path = strtok(NULL, sep);
- }
- [[window reenableFlushWindow] flushWindowIfNeeded];
- if (useSound)
- [fiendSound play:self];
-
- [pb deallocatePasteboardData:dragString length:len];
- [[NXApp delegate] updateMenus];
- [self perform:@selector(writeShelf) with:nil afterDelay:1000.0 cancelPrevious:YES];
- return self;
- }
-
- - paste:sender
- {
- return [self paste:sender toPasteboard:[Pasteboard new]];
- }
-
- - (FILE *)openShelfFor:(char *)how path:(char *)path
- {
- char *path2 = "";
- FILE *f;
-
- sprintf(path, "%s/.AppInfo/Fiend/%s.%.0f.%.0f", NXHomeDirectory(),
- FIENDSHELF_FILE, NX_WIDTH(&frame), NX_HEIGHT(&frame));
-
- if (*how == 'w') {
- path2 = (char *)malloc(strlen(path)+2);
- sprintf(path2, "%s~", path);
- rename(path, path2);
- }
-
- f = fopen(path, how);
- if (*how == 'r') {
- if (f == (FILE *)NULL) {
- NXLogError("Couldn't find %s, trying %s~", path, path);
- strcat(path, "~");
- if ((f = fopen(path, how)) == (FILE *)NULL) {
- sprintf(path, "%s/.AppInfo/Fiend/%s", NXHomeDirectory(), FIENDSHELF_FILE);
- NXLogError("...trying %s", path);
- if ((f = fopen(path, how)) == (FILE *)NULL) {
- sprintf(path, "%s/.FiendShelf", NXHomeDirectory());
- NXLogError("...trying %s", path);
- if ((f = fopen(path, how)) == (FILE *)NULL)
- NXLogError("No FiendShelf file!!");
- }
- }
- }
- else {
- fseek(f, 0L, SEEK_END);
- if (ftell(f) <= 5) {
- NXLogError("%s is empty - trying backup", path);
- fclose(f);
- strcat(path, "~");
- if ((f = fopen(path, how)) != (FILE *)NULL) {
- fseek(f, 0L, SEEK_END);
- if (ftell(f) <= 5)
- NXLogError("Backup is empty - building empty shelf");
- }
- }
- if (f != (FILE *)NULL)
- rewind(f);
- }
- return f;
- }
- else if (f == (FILE *)NULL) {
- NXBeep();
- NXRunAlertPanel([NXApp appName],
- "Could not open %s to save Fiend Shelf!!",
- NULL, NULL, NULL, path);
- rename(path2, path);
- free(path2);
- return f;
- }
-
- if (*how == 'w') free(path2);
- return f;
- }
-
-
- - closeShelf:(FILE *)file
- {
- fclose(file);
- return self;
- }
-
-
- - readShelf:(BOOL)showProgress
- {
- float i;
- float count;
- FILE *file;
- char line[MAXPATHLEN + 30];
- char *path;
- NXPoint point;
-
- file = [self openShelfFor:"r" path:line];
- if (file == NULL)
- return self;
-
- count = 0.0;
- if (showProgress) {
- while(fgets(line, sizeof(line), file))
- count++;
- rewind(file);
- [[NXApp delegate] setProgressViewRatio:0.0];
- if (count == 0) {
- [self closeShelf:file];
- [[NXApp delegate] setProgressViewRatio:0.85];
- return self;
- }
- }
-
- i = 1.0;
- while (fgets(line, sizeof(line), file)) {
- if (showProgress)
- [[NXApp delegate] setProgressViewRatio:0.85*i++/count];
-
- sscanf(line, "%f %f", &point.x, &point.y);
- if (strlen(line) > 14) {
- path = line + 14;
- if (rindex(path, '\n') != NULL)
- *rindex(path, '\n') = '\0';
- }
- else
- continue;
-
- [self createViewForPath:path withImage:nil at:&point];
- }
-
- [self closeShelf:file];
-
- return self;
- }
-
-
- - writeShelf
- {
- id *view;
- int i;
- int length;
- int statRet;
- char *iconPath;
- char path[MAXPATHLEN];
- char path2[MAXPATHLEN];
- FILE *file;
- NXRect rect;
- struct stat theStat;
- int count = [subviews count];
- id *viewListPtr = (count > 0) ? NX_ADDRESS(subviews) : (id *)NULL;
-
- file = [self openShelfFor:"w" path:path];
- if (file == NULL)
- return self;
-
- for(i = 0, view = viewListPtr; i < count; i++, view++) {
- if (![*view isKindOf:[IconView class]])
- continue;
-
- [*view getData:(void **)&iconPath andLength:&length];
- [*view getFrame:&rect];
-
- if (fprintf(file, "%6.0f %6.0f %s\n", rect.origin.x, rect.origin.y, iconPath) < 0) {
- perror("Fiend 'writeShelf'");
- fclose(file);
- sprintf(path, "%s/.AppInfo/Fiend/%s.%.0f.%.0f", NXHomeDirectory(),
- FIENDSHELF_FILE, NX_WIDTH(&frame), NX_HEIGHT(&frame));
- sprintf(path2, "%s~", path);
- fclose(file);
- unlink(path);
- rename(path, path2);
- return nil;
- }
- }
-
- [self closeShelf:file];
- sprintf(path2, "%s/.AppInfo/Fiend/FiendShelf", NXHomeDirectory());
- statRet = stat(path2, &theStat);
- if (((statRet != -1) && (theStat.st_mode & S_IFLNK)) || statRet == -1) {
- unlink(path2);
- symlink(path, path2);
- }
- return self;
- }
-
- @end
-