This is ImageView.m in view mode; [Download] [Up]
#import <appkit/appkit.h> // #import <dpsclient/psops.h> // #import <dpsclient/wraps.h> #import "ImageView.h" #import "PhotoWinProcs.h" #import "Controller.h" // for nextPasteCounter... @implementation ImageView - initForImage:(id)img :(const NXRect *)rect; { NXSize sz; self = [super initFrame:rect]; theImage = img; sz.width = [theImage pixelsWide]; sz.height = [theImage pixelsHigh]; [self sizeTo:sz.width :sz.height]; selectRect.size.width = 0; selectRect.size.height = 0; return self; } - (BOOL)acceptsFirstResponder { return YES; } - (BOOL)acceptsFirstMouse { return YES; } - (id) image { return theImage; } - drawSelf:(const NXRect *)rects :(int)rectCount { [theImage draw]; return self; } #define DRAG_MASK (NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK) - mouseDown:(NXEvent *)event { NXPoint p, start, last, maxBound; NXSize imSize, imPixelSize; static const NXPoint hot = {7., 7.}; int oldMask; BOOL doAlternateDrag = NO; NXCoord faceTiffSize = 64.0, altDragSize = 0; static id crossCursor = nil; [theImage getSize:&imSize]; imPixelSize.width = [theImage pixelsWide]; imPixelSize.height = [theImage pixelsHigh]; if (NX_ALTERNATEMASK & event->flags) { doAlternateDrag = YES; altDragSize = faceTiffSize; maxBound.x = imSize.width; maxBound.y = imSize.height - altDragSize; [self convertPoint:&maxBound fromView:nil]; } oldMask = [window addToEventMask:NX_MOUSEDRAGGEDMASK|NX_MOUSEUPMASK]; if( !crossCursor ) { crossCursor = [[NXCursor alloc] initFromImage: [[NXImage alloc] initFromSection:"cross.tiff"]]; [crossCursor setHotSpot:&hot]; } [crossCursor push]; p = start = event->location; [self convertPoint:&start fromView:nil]; last = start; [self lockFocus]; PSsetlinewidth(0.0); PSsetinstance(YES); event = [NXApp getNextEvent:DRAG_MASK]; while( event->type != NX_MOUSEUP ) { p = event->location; [self convertPoint:&p fromView:nil]; PSnewinstance(); if( p.x != last.x || p.y != last.y ) { PSsetinstance(YES); PSsetgray(1.0); if ( doAlternateDrag ) { start = p; if ( start.x < altDragSize ) start.x = altDragSize; if ( start.y < 0 ) start.y = 0; if ( start.x > maxBound.x ) start.x = maxBound.x; if ( start.y > maxBound.y ) start.y = maxBound.y; PSrectstroke(start.x, start.y, - (altDragSize + 1), (altDragSize + 1) ); } else { PSrectstroke(start.x, start.y, (p.x - start.x), (p.y - start.y)); } PSsetinstance(NO); last = p; NXPing(); } p = event->location; event = [NXApp getNextEvent:DRAG_MASK]; } [self convertPoint:&p fromView:nil]; selectRect.origin.x = start.x; selectRect.origin.y = start.y; if ( doAlternateDrag ) { selectRect.size.width = -altDragSize; selectRect.size.height = altDragSize; } else { selectRect.size.width = p.x - start.x; selectRect.size.height = p.y - start.y; } [self unlockFocus]; [window flushWindow]; [window setEventMask:oldMask]; [crossCursor pop]; return self; } - copy:sender { NXStream *st; NXBitmapImageRep *bm; int i = 0; const char *types[2]; id pb = [Pasteboard new]; // note that "owner:" in the following can not be "self", or the // id of anything else which might be freed inbetween "Copy" // operations. types[i++] = NXTIFFPboardType; [pb declareTypes:types num:i owner:NXApp]; [self lockFocus]; bm = [[NXBitmapImageRep alloc] initData:NULL fromRect:&selectRect]; [self unlockFocus]; st = NXOpenMemory(NULL, 0, NX_WRITEONLY); [bm writeTIFF:st]; [pb writeType:NXTIFFPboardType fromStream:st]; NXCloseMemory(st, NX_FREEBUFFER); [bm free]; return self; } - paste:sender { NXStream *st; char tmpName[40]; int pasteCount; id pb; pb = [Pasteboard new]; (void)[pb types]; st = [pb readTypeToStream:NXTIFFPboardType]; pasteCount = [[NXApp delegate] nextPasteCounter]; sprintf(tmpName, "%d_PasteImage", pasteCount); [[window delegate] displayImage: [[NXBitmapImageRep alloc] initFromStream:st] withName:tmpName atResolution:0]; NXCloseMemory(st, NX_FREEBUFFER); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.