This is ImageCompositor.m in view mode; [Download] [Up]
/* * ImageCompositor -- Randy Nelson * An general class that composites an image at the current mouse location * * You may freely copy, distribute and reuse the code in this example. * NeXT disclaims any warranty of any kind, expressed or implied, as to * its fitness for any particular use. */ #import "ImageCompositor.h" #import <appkit/Application.h> #import <appkit/Window.h> #import <appkit/PrintInfo.h> #import <appkit/NXImage.h> #import <appkit/NXColorPanel.h> #import <appkit/NXColorWell.h> #import <appkit/Button.h> #import <appkit/Slider.h> #import <dpsclient/psops.h> #import <dpsclient/wraps.h> #import <appkit/publicWraps.h> #define SQUARE 1 #define CIRCLE 2 #define BRUSHHEIGHT 48.0 #define BRUSHWIDTH 48.0 #define BRUSHNAME "theBrush" @implementation ImageCompositor - initFrame:(const NXRect *)frameRect { [super initFrame:frameRect]; /* off-screen buffer */ screenImage = [[NXImage alloc] initSize:&bounds.size]; /* undo buffer */ undoImage = [[NXImage alloc] initSize:&bounds.size]; /* brush */ currentBrushSize.height = BRUSHHEIGHT; currentBrushSize.width = BRUSHWIDTH; brushImage = [[NXImage alloc] initSize:¤tBrushSize]; /* we do alot of focus pocus */ [self allocateGState]; return self; } - selfInit:sender { NXRect aRect; /* set up for horizontal printing */ [[[[[NXApp printInfo] setOrientation:NX_LANDSCAPE andAdjust:YES] setHorizCentered:YES] setVertCentered:YES] setMarginLeft:0.0 right:0.0 top:0.0 bottom:0.0]; /* set up initial brush state */ [brushImage setName:BRUSHNAME]; [brushSize setMinValue:1.0]; [brushSize setMaxValue:100.0]; [brushSize setFloatValue:25.0]; [brushColor setColor:NX_COLORBLACK]; [self drawBrushImage:self]; /* set up window resizing limits */ [window getFrame:&aRect]; windowMax.width = aRect.size.width; windowMax.height = aRect.size.height; windowMin.width = windowMax.width/3; windowMin.height = windowMax.height/3; /* show the windows */ [self erase:sender]; [window makeKeyAndOrderFront:self]; [[brushDisplay window] orderFront:self]; [self colorPanel:self]; return self; } - drawSelf:(const NXRect *)r :(int)c { /* load the appropriate portion of the off-screen buffer * into the visible portion of the view */ [screenImage composite:NX_COPY fromRect:r toPoint:&(r->origin)]; return self; } - mouseDownAction:(NXPoint *)currentLocation { NXPoint zero = {0.0, 0.0}; /* load the old off-screen buffer into the undo buffer */ if ([undoImage lockFocus]) { [screenImage composite:NX_COPY toPoint:&zero]; [undoImage unlockFocus]; } /* center on the brush */ currentLocation->x -= currentBrushCenter.x; currentLocation->y -= currentBrushCenter.y; /* draw the current brush into the view */ [self lockFocus]; [brushImage composite:NX_SOVER toPoint:currentLocation]; [self unlockFocus]; [window flushWindow]; /* draw the current brush into the off-screen buffer */ if ([screenImage lockFocus]) { [brushImage composite:NX_SOVER toPoint:currentLocation]; [screenImage unlockFocus]; } return self; } - mouseDraggedAction:(NXPoint *)currentLocation { /* center on the brush */ currentLocation->x -= currentBrushCenter.x; currentLocation->y -= currentBrushCenter.y; /* draw the current brush into the view */ [self lockFocus]; [brushImage composite:NX_SOVER toPoint:currentLocation]; [self unlockFocus]; [window flushWindow]; /* draw the current brush into the off-screen buffer */ if ([screenImage lockFocus]) { [brushImage composite:NX_SOVER toPoint:currentLocation]; [screenImage unlockFocus]; } return self; } - mouseUpAction:(NXPoint *)currentLocation { return self; } - drawBrushImage:sender { /* read all the brush parameters from interface */ currentBrushColor = [brushColor color]; currentBrushShape = [brushShape selectedTag]; currentBrushSize.height = currentBrushSize.width = [brushSize floatValue]; currentBrushCenter.x = (currentBrushSize.width/2); currentBrushCenter.y = (currentBrushSize.height/2); /* draw the current brush */ [brushImage setSize:¤tBrushSize]; if ([brushImage lockFocus]) { PScompositerect(0.0, 0.0, currentBrushSize.height, currentBrushSize.width, NX_CLEAR); NXSetColor(currentBrushColor); switch (currentBrushShape) { case SQUARE:{ PSrectfill(0.0, 0.0, currentBrushSize.height, currentBrushSize.width); break; } case CIRCLE:{ PSarc(currentBrushCenter.x, currentBrushCenter.y, currentBrushCenter.x, 0.0, 360.0); break; } default:{ break; } } PSfill(); [brushImage unlockFocus]; } [brushDisplay setIcon:BRUSHNAME]; return self; } - undo:sender { NXPoint zero = {0.0, 0.0}; /* load the undo buffer into the off-screen buffer and display */ if ([screenImage lockFocus]) { [undoImage composite:NX_COPY toPoint:&zero]; [screenImage unlockFocus]; } [self display]; return self; } - erase:sender { /* leave the undo buffer alone */ if ([screenImage lockFocus]) { NXEraseRect(&bounds); [screenImage unlockFocus]; } [self display]; return self; } - (BOOL)acceptsFirstMouse { return YES; } -appDidInit:sender { [self selfInit:self]; return self; } - windowWillResize:sender toSize:(NXSize *)newFrame { if(newFrame->width > windowMax.width) { newFrame->width = windowMax.width; } else if(newFrame->width < windowMin.width){ newFrame->width = windowMin.width; } if(newFrame->height > windowMax.height){ newFrame->height = windowMax.height; } else if(newFrame->height < windowMin.height){ newFrame->height = windowMin.height; } return self; } - infoPanel:sender { if (infoPanel == nil) { [NXApp loadNibSection:"Info.nib" owner:self]; } [infoPanel orderFront:sender]; return self; } - helpPanel:sender { if(helpPanel == nil){ [NXApp loadNibSection:"Help.nib" owner:self]; } [helpPanel orderFront:sender]; return self; } - colorPanel:sender { [[[[NXColorPanel new] setContinuous:YES] moveTo:494.0 :54.0] orderFront:nil]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.