This is IconView.m in view mode; [Download] [Up]
#import "Fiend.h" #import "IconView.h" #import "ShelfView.h" #import "Controller.h" #import <appkit/workspaceRequest.h> #import <appkit/appkit.h> #import <mach/mach.h> #import <bsd/sys/file.h> #define IMAGE_OFFSET 2 @implementation NXImage(UsefulMethod) - (NXSize)scaleToFitInside:(NXSize)size max:(NXSize)maxSize onDock:(BOOL)dockFlag isApp:(BOOL)isApp { NXSize imageSize; float scale; [self getSize:&imageSize]; scale = MIN(size.width/imageSize.width, size.height/imageSize.height); scale *= 0.98; size.width = scale * imageSize.width; size.height = scale * imageSize.height; if (size.width > maxSize.width) size.width = maxSize.width; if (size.height > maxSize.height) size.height = maxSize.height; size.width = (int)size.width; size.height = (int)size.height; [self setSize:&size]; return size; } @end @implementation IconView : View static id processTable; static id scaledDockHilite; static id scaledShelfHilite; static id scaledShelfAppHilite; static id scaledAppTile; static id scaledDotsTile; + initialize { scaledDockHilite = scaledShelfHilite = scaledShelfAppHilite = nil; [self resetCachedShelfImages]; [self resetCachedDockImages]; return self; } + resetCachedShelfImages { [scaledShelfHilite free]; scaledShelfHilite = [[NXImage findImageNamed:"hilite"] setScalable:YES]; [scaledShelfAppHilite free]; scaledShelfAppHilite = [[[NXImage findImageNamed:"hilite"] copy] setScalable:YES]; return self; } + resetCachedDockImages { [scaledDockHilite free]; scaledDockHilite = [[[NXImage findImageNamed:"hilite"] copy] setScalable:YES]; [scaledAppTile free]; scaledAppTile = [[[NXImage findImageNamed:"NXAppTile"] copy] setScalable:YES]; [scaledDotsTile free]; scaledDotsTile = [[NXImage findImageNamed:"dots"] setScalable:YES]; return self; } + shelfHilite { return scaledShelfHilite; } + dockHilite { return scaledDockHilite; } + shelfAppHilite { return scaledShelfAppHilite; } + getImageForPath:(const char *)path fileIcon:(BOOL)flag { id newImage = nil; const char *const *typeArray = [NXImage imageFileTypes]; if (!flag) { newImage = nil; do { if ((strstr(path, *typeArray) - path) == (strlen(path) - strlen(*typeArray++))) { newImage = [[NXImage alloc] initFromFile:path]; break; } } while (*typeArray != NULL); if (newImage != nil) { if ([newImage lockFocus]) { [newImage unlockFocus]; return newImage; } [newImage free]; newImage = nil; } } if (newImage == nil) newImage = [[Application workspace] getIconForFile:path]; [newImage setScalable:YES]; return newImage; } + processTable { return processTable; } + resetProcessTable { int pid; char junk[25]; char appName[100]; char inLine[1000]; NXAtom atom; FILE *pfile; static char *cmd = "/bin/ps axc"; if (!processTable) processTable = [[HashTable alloc] initKeyDesc:"%" valueDesc:"i"]; [processTable empty]; if ((pfile = popen(cmd, "r")) == NULL) return nil; while(fgets(inLine, 999, pfile) != NULL) { sscanf(inLine, "%d %s %s %s %s", &pid, junk, junk, junk, appName); atom = NXUniqueString(appName); [processTable insertKey:(const void *)atom value:(void *)pid]; } fclose(pfile); return self; } + (int)getLastPidFor:(char *)aName { int pid; NXAtom atom = NXUniqueString(aName); if ([processTable isKey:atom]) { pid = (int)[processTable valueForKey:atom]; return pid; } else return -1; } + (BOOL)pidExists:(int)testPid { const int value; const void *key; NXHashState state = [processTable initState]; while ([processTable nextState:&state key:&key value:(void *)&value]) { if (testPid == value) return YES; } return NO; } /* * Create a copy of an IconView (or an IconView subclass). Note that this * method cheats by potentially changing the class of the copied image. */ + copyIconView:aView { NXRect aFrame; void *oldData; unsigned int len; [aView getFrame:&aFrame]; [aView getData:&oldData andLength:&len]; return [[self allocFromZone:[aView zone]] initFrame:&aFrame image:[[aView image] copy] data:oldData andLength:len useSize:YES onDock:NO]; } - initFrame:(const NXRect *) newFrame image:anImage data:(const void *) someData andLength:(unsigned int) newLength useSize:(BOOL) sizeValid onDock:(BOOL)dockFlag; { id hilite; int count; char hostname[40]; NXScreen *screens; NXSize imageSize = {400, 400}; [NXApp getScreens:&screens count:&count]; screenSize = screens[0].screenBounds.size; if (newLength > 0 && *((char *)someData + newLength - 1)) length = newLength + 1; else length = newLength; data = (char **)malloc(length+1); bcopy(someData, data, length+1); ghost = NO; selected = NO; isLaunched = NO; onDock = dockFlag; isApp = !strcmp(data+strlen((char *)data)-4, ".app"); if (isApp) { char appName[100]; char *appFileName = strrchr((char *)data, '/'); strncpy(appName, appFileName+1, strlen(appFileName)-4); appName[strlen(appFileName)-5] = '\0'; appPid = [IconView getLastPidFor:appName]; if (appPid != -1) isLaunched = YES; } shelfHilite = [IconView shelfHilite]; dockHilite = [IconView dockHilite]; shelfAppHilite = [IconView shelfAppHilite]; hilite = (onDock) ? dockHilite : ((isApp) ? shelfAppHilite : shelfHilite); hiliteMax.width = 400; hiliteMax.height = 400; image = anImage; imageMax = imageSize; /* * Allocate a cell, and slam the filename into it. Make sure to use * only the last component of the path. */ if (!isApp) { titleCell = [[TextFieldCell allocFromZone:[self zone]] init]; [titleCell setAlignment:NX_CENTERED]; [titleCell setBackgroundTransparent:YES]; if (!strcmp(data, "/")) { gethostname(hostname, 39); [titleCell setStringValue:hostname]; } else if (rindex(data, '/')) [titleCell setStringValue:rindex(data, '/') + 1]; else [titleCell setStringValue:data]; } /* * If there's no frame, make one that's the right size to hold * everything. */ if (!sizeValid) { NXSize titleSize = {0.0, 0.0}; NXRect aRect = {{0, 0}, {0, 0}}; [hilite getSize:&imageSize]; if (!isApp) [titleCell calcCellSize:&titleSize]; if (newFrame) aRect.origin = newFrame->origin; aRect.size.height = imageSize.height + titleSize.height; aRect.size.width = MAX(titleSize.width, imageSize.width); [super initFrame:&aRect]; } else [super initFrame:newFrame]; [self setImageSize]; [self getImagePoint:&imagePoint andHilitePoint:&hilitePoint]; return self; } - initFromDragContext:(id <NXDraggingInfo>)context andSize:(NXSize *)aSize onDock:(BOOL)dockFlag; { char *pbData; unsigned int len; NXImage *copiedImage = [context draggedImageCopy]; Pasteboard *pb = [Pasteboard newName:NXDragPboard]; NXRect aRect = {{0, 0}, {0, 0}}; NXRect *rectPtr = NULL; [pb readType:NXFilenamePboardType data:&pbData length:&len]; if (aSize != NULL) { rectPtr = &aRect; aRect.size = *aSize; } [self initFrame:rectPtr image:copiedImage data:pbData andLength:len+1 useSize:aSize != NULL onDock:dockFlag]; [self display]; return self; } - free { free(data); [image free]; if (!isApp) [titleCell free]; return [super free]; } - getAppPid { char appName[100]; char *appFileName = strrchr((char *)data, '/'); strncpy(appName, appFileName+1, strlen(appFileName)-4); appName[strlen(appFileName)-5] = '\0'; appPid = [IconView getLastPidFor:appName]; return self; } - (NXCoord) cellHeight { NXSize cellSize = {0.0, 0.0}; if (!isApp) [titleCell calcCellSize:&cellSize]; return cellSize.height; } - setImage:anImage { id tempImage = image; image = anImage; return tempImage; } - getImagePoint:(NXPoint *)imageLoc andHilitePoint:(NXPoint *)hiliteLoc { NXSize imageSize; id hilite = (onDock) ? dockHilite : ((isApp) ? shelfAppHilite : shelfHilite); NXSize hiliteSize = {48.0, 48.0}; NXCoord cellHeight = 0.0; if (!isApp) cellHeight = [self cellHeight]; /* * Determine where the image and cell go in the new view. */ if (imageLoc) { [image getSize:&imageSize]; imageLoc->x = (bounds.size.width - imageSize.width) / 2; imageLoc->y = cellHeight + (bounds.size.height - imageSize.height - cellHeight) / 2; if (!isApp) imageLoc->y -= 4.0; } if (hiliteLoc && imageLoc) { [hilite getSize:&hiliteSize]; hiliteLoc->x = (bounds.size.width - hiliteSize.width) / 2; hiliteLoc->y = imageLoc->y - (hiliteSize.height - imageSize.height) / 2; } return self; } - (void) setImageSize { float fontSize; NXSize imageSize; NXSize hMax = {416, 416}; NXSize iMax = {400, 400}; BOOL sizeFont = !strcmp(NXGetDefaultValue([NXApp appName], SIZE_FONT), "YES"); id hilite = (onDock) ? dockHilite : ((isApp) ? shelfAppHilite : shelfHilite); [image setScalable:YES]; [hilite setScalable:YES]; imageSize = bounds.size; imageSize = [hilite scaleToFitInside:imageSize max:hMax onDock:onDock isApp:isApp]; imageSize = [image scaleToFitInside:imageSize max:iMax onDock:onDock isApp:isApp]; if (!isApp && sizeFont) { fontSize = [[Font userFontOfSize:0 matrix:NX_FLIPPEDMATRIX] pointSize]; fontSize *= (imageSize.height/48.0); fontSize = 2.0 * ((int)fontSize/2); fontSize = (fontSize < 8.0) ? 8.0 : fontSize; fontSize = (fontSize > 18.0) ? 18.0 : fontSize; [titleCell setFont:[Font userFontOfSize:fontSize matrix:NX_FLIPPEDMATRIX]]; } } - (BOOL)isApp { return isApp; } - sizeTo:(NXCoord) width :(NXCoord) height { [super sizeTo:width :height]; [self setImageSize]; [self getImagePoint:&imagePoint andHilitePoint:&hilitePoint]; return self; } - setDockMgrView:aView { onDock = YES; dockMgrView = aView; return self; } - dockMgrView { return dockMgrView; } - drawSelf:(const NXRect *) rects :(int) rectCount { NXRect cellRect; id hilite = (onDock) ? dockHilite : ((isApp) ? shelfAppHilite : shelfHilite); if (onDock) { [scaledAppTile setSize:&bounds.size]; [scaledAppTile composite:NX_SOVER toPoint:&frame.origin]; if (autoLaunch) { PSsetlinewidth(0.05*NX_HEIGHT(&frame)); if ([self shouldDrawColor]) NXSetColor(NX_COLORRED); else PSsetgray(NX_BLACK); PSmoveto(0.2*NX_WIDTH(&frame), 0.92*NX_HEIGHT(&frame)); PSrlineto(0.6*NX_WIDTH(&frame), 0.0); PSstroke(); PSsetlinewidth(0.0); PSsetgray(NX_BLACK); } if (isApp && !isLaunched) { [scaledDotsTile setSize:&bounds.size]; [scaledDotsTile composite:NX_SOVER toPoint:&frame.origin]; } } if (!isApp) { if (NXBrightnessComponent(NXReadPixel(&bounds.origin)) < NX_DKGRAY + 0.01) [titleCell setTextGray:ghost ? NX_LTGRAY : NX_WHITE]; else [titleCell setTextGray:ghost ? NX_DKGRAY : NX_BLACK]; } if (ghost || (onDock && selected)) { id tempImage = [[NXImage alloc] initSize:&bounds.size]; if (!onDock) { if ([tempImage lockFocus]) { PSsetalpha(0); NXRectFill(&bounds); [image dissolve:0.666 toPoint:&imagePoint]; [tempImage unlockFocus]; } } else { if ([tempImage lockFocus]) { [scaledAppTile composite:NX_SOVER toPoint:&frame.origin]; [image composite:NX_SOVER toPoint:&imagePoint]; PSsetgray(NX_WHITE); PSsetalpha(0.666); PScompositerect(2.0, 2.0, NX_WIDTH(&frame)-4.0, NX_HEIGHT(&frame)-4.0, NX_SOVER); [tempImage unlockFocus]; } } [tempImage composite:NX_SOVER toPoint:&bounds.origin]; [tempImage free]; } else { if (selected) { [hilite composite:NX_SOVER toPoint:&hilitePoint]; } else { NXRect aRect; [hilite getSize:&aRect.size]; aRect.origin = hilitePoint; [self convertRect:&aRect toView:superview]; [superview lockFocus]; [superview drawSelf:&aRect :1]; [superview unlockFocus]; } [image composite:NX_SOVER toPoint:&imagePoint]; } if (preDelete) { PSsetlinewidth(5.0); if ([self shouldDrawColor]) NXSetColor(NX_COLORRED); else PSsetgray(NX_BLACK); PSmoveto(0.0, 0.0); PSlineto(NX_MAXX(&frame), NX_MAXY(&frame)); PSmoveto(NX_MAXX(&frame), 0.0); PSlineto(0.0, NX_MAXY(&frame)); PSstroke(); PSsetgray(NX_BLACK); } if (!isApp) { NXSetRect(&cellRect, 0, 3 + hilitePoint.y - [self cellHeight], bounds.size.width, [self cellHeight]); [titleCell drawInside:&cellRect inView:self]; } return self; } - image { return image; } - getData:(void **)aPtr andLength:(unsigned int *)aLength { *aPtr = data; *aLength = length; return self; } - setGhost:(BOOL) newGhost { ghost = newGhost; return self; } - (BOOL) isGhost { return ghost; } - setPreDelete:(BOOL)flag { preDelete = flag; return self; } - (BOOL)preDelete { return preDelete; } - setAutoLaunch:(BOOL)flag { autoLaunch = flag; return self; } - (BOOL)autoLaunch { return autoLaunch; } - (int) state { return selected; } - setState:(int) flag { if (flag ^ selected) { selected = flag ? YES : NO; [self display]; } return self; } - (BOOL)onDock { return onDock; } - (BOOL)isLaunched { return isLaunched; } - setLaunched:(BOOL)flag { isLaunched = flag; if (!flag) appPid = -1; return self; } - (int)appPid { return appPid; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.