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.