This is DrawView.m in view mode; [Download] [Up]
/* Generated by Interface Builder */
#import "DrawView.h"
#define PRINTER_PIXEL_FACTOR 67.0 // dpi of screen when printed
#define LINE_WIDTH_FACTOR 1.08 // fudge factor to avoid aliasing
@implementation DrawView
+ newFrame: (NXRect *)rect
{
self = [super newFrame:rect];
[self initialValues];
return self;
}
- (PROC) initialValues
{
xmax = 2.0;
xmin = -2.0;
ymax = 2.0;
ymin = -2.0;
xc = 0.0;
yc = 1.0;
iterates = 12;
large = 10.0;
running = NO;
pixelSize = 6;
colors = 7;
}
- (BOOL) continue // Ignores all mousedown events until Stop is pressed
{
NXEvent *peekedEvent;
peekedEvent = [NXApp peekAndGetNextEvent:NX_MOUSEDOWNMASK];
if (peekedEvent IS NULL)
return YES;
else if (NXPointInRect(&(peekedEvent->location), &stopRect))
{
[stopButton highlight:YES];
running = NO;
[stopButton highlight:NO];
return NO;
}
else
return YES;
}
- drawSelf: (NXRect *)rect : (int) count
{
NXRect frameRect;
int p, q, // pixel coords
pmax, qmax, // pixels in screen
pstart; // start of line to draw
float x, y, // actual coords
dx, dy, // distance between pixels
oldCol, newCol, // colours of adjacent pixels
printerDot, // distance between printer dots
lineWidth, // width 1 on printer is PRINTER_PIXEL_FACTOR
qHeight; // vertical position of line to be drawn
NXEraseRect(&bounds);
if ((NXDrawingStatus IS NX_DRAWING) AND running)
{
[self getParams];
[self getFrame:&frameRect];
pmax = (int) frameRect.size.width;
qmax = (int) frameRect.size.height;
dx = (xmax - xmin)/pmax;
dy = (ymax - ymin)/qmax;
PSsetlinewidth(1.0);
for (q = 0, y = ymin; (q <= qmax) AND [self continue]; q++, y += dy)
{
for (p = 0, pstart = 0, x = xmin, oldCol = NX_WHITE;
p <= pmax; p++, x += dx)
{
newCol = [self pixelCol:x :y];
if (newCol IS_NOT oldCol)
{
if (oldCol IS_NOT NX_WHITE)
[self drawline:oldCol :pstart :(p-1) :q];
pstart = p;
oldCol = newCol;
}
}
if (oldCol IS_NOT NX_WHITE)
[self drawline:oldCol :pstart :p :q];
[window flushWindow];
}
}
else if (NXDrawingStatus IS NX_PRINTING)
{
[self getParams];
[self getFrame:&frameRect];
printerDot = PRINTER_PIXEL_FACTOR/
atoi(NXGetDefaultValue("System", "PrinterResolution"));
lineWidth = printerDot*pixelSize;
pmax = (int) ((frameRect.size.width)/lineWidth);
qmax = (int) ((frameRect.size.height)/lineWidth);
dx = (xmax - xmin)/pmax;
dy = (ymax - ymin)/qmax;
if (pixelSize > 1)
PSsetlinewidth(lineWidth*LINE_WIDTH_FACTOR);
else
PSsetlinewidth(0);
for (q = 0, y = ymin; (q <= qmax); q++, y += dy)
{
qHeight = (q + 0.5)*lineWidth;
for (p = 0, pstart = 0, x = xmin, oldCol = NX_WHITE; p <= pmax;
p++, x += dx)
{
newCol = [self pixelCol:x :y];
if (newCol IS_NOT oldCol)
{
if (oldCol IS_NOT NX_WHITE)
[self drawline :oldCol :(pstart*lineWidth)
:(p*lineWidth - printerDot) :qHeight];
pstart = p;
oldCol = newCol;
}
}
if (oldCol IS_NOT NX_WHITE)
[self drawline:oldCol :(pstart*lineWidth) :(p*lineWidth) :qHeight];
[window flushWindow];
}
}
return self;
}
- (PROC) drawline:(float) col :(float) p1 :(float) p2 :(float) q
{
PSnewpath();
PSmoveto(p1, q);
PSlineto(p2, q);
PSsetgray(col);
PSstroke();
}
- (float) pixelCol:(float) x :(float) y
{
int power;
float xx, yy;
xx = x*x;
yy = y*y;
power = 0;
while (((xx + yy) < large) AND (power < iterates))
{
++power;
y = 2*x*y + yc;
x = xx - yy + xc; // f(z) = z*z + c
xx = x*x;
yy = y*y;
}
if (power >= iterates)
return NX_BLACK;
else
return (1.0 + (power MOD (colors - 1)))/(colors - 1);
}
- setParamsForm:anObject
{
paramsForm = anObject;
[paramsForm setFloatValue:xc at:0];
[paramsForm setFloatValue:yc at:1];
[paramsForm setFloatValue:xmin at:2];
[paramsForm setFloatValue:ymin at:3];
[paramsForm setFloatValue:xmax at:4];
[paramsForm setFloatValue:ymax at:5];
[paramsForm setIntValue:iterates at:6];
[paramsForm setFloatValue:large at:7];
[paramsForm setIntValue:colors at:8];
return self;
}
- setPopUpButton:anObject
{
id aPopUp;
popUpButton = anObject;
aPopUp = [PopUpList new];
[aPopUp addItem:"1 dot"];
[aPopUp addItem:"2x2 dots"];
[aPopUp addItem:"3x3 dots"];
[aPopUp addItem:"4x4 dots"];
[aPopUp addItem:"5x5 dots"];
[aPopUp addItem:"6x6 dots"];
[[aPopUp itemList] selectCellAt:pixelSize - 1:0];
NXAttachPopUpList(popUpButton, aPopUp);
[aPopUp setTarget:self];
[aPopUp setAction:@selector(pixelSize:)];
return self;
}
- setStopButton:anObject
{
stopButton = anObject;
[stopButton getFrame:&stopRect];
return self;
}
- getParams
{
xc = [paramsForm floatValueAt:0];
yc = [paramsForm floatValueAt:1];
xmin = [paramsForm floatValueAt:2];
ymin = [paramsForm floatValueAt:3];
xmax = [paramsForm floatValueAt:4];
ymax = [paramsForm floatValueAt:5];
iterates = [paramsForm intValueAt:6];
large = [paramsForm floatValueAt:7];
colors = [paramsForm intValueAt:8];
if (colors < 2)
colors = 2;
return self;
}
- start:sender
{
running = YES;
[self display];
return self;
}
- pixelSize:sender
{
pixelSize = 1 + [sender selectedRow];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.