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.