This is DialView.m in view mode; [Download] [Up]
/* * (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved. * * (b) If this Sample Code is distributed as part of the Display PostScript * System Software Development Kit from Adobe Systems Incorporated, * then this copy is designated as Development Software and its use is * subject to the terms of the License Agreement attached to such Kit. * * (c) If this Sample Code is distributed independently, then the following * terms apply: * * (d) This file may be freely copied and redistributed as long as: * 1) Parts (a), (d), (e) and (f) continue to be included in the file, * 2) If the file has been modified in any way, a notice of such * modification is conspicuously indicated. * * (e) PostScript, Display PostScript, and Adobe are registered trademarks of * Adobe Systems Incorporated. * * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO * CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED * AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED. * ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY * OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO * WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY) * WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY * DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. */ /* * DialView.m * Created by Ken Fromm * * This application draws hash marks on a dial in several ways. The first way * draws using wraps and the rotate operator. The second draws with wraps * but calculates the trig for the beginning and ending points of the line segments. * The third calculates the trig and sends the line segments to the server with * user paths. This is the fastest drawing approach and is recommended * for all but the simplest drawing. The last method stores the user path in the * server instead of calculating the points anew. This is may be useful in a few * cases where the paths are large, imaged frequently and do not change. * In most cases, though, the overhead of managing paths in the server * overrides any savings. * * Version: 2.0 * Author: Ken Fromm * History: * 03-07-91 Added this comment. * 05-10-91 Simplified the application from six methods to * four. (The two taken out were variations of * user path drawing and tended to cloud the * message of the application.) */ #import "DialView.h" #import "DialViewWraps.h" #import <appkit/Button.h> #import <appkit/Control.h> #import <appkit/Matrix.h> #import <appkit/TextField.h> #import <appkit/nextstd.h> #import <math.h> #import <dpsclient/wraps.h> @implementation DialView /* * These definitions are for the names of the user path arrays in the server. Providing * names like this is only to simplify the example. An optimized solution would probably use * user objects and forego names altogether. */ static char *upath1 = "upath1"; static char *upath10 = "upath10"; static char *upath45 = "upath45"; static char *upath90 = "upath90"; /* * Allocate a gstate and set clipping to NO. The gstate is allocated because we do not * want to reset the individual drawing variables when the context is switched back to this * view. The clipping is set to NO because the drawing methods do not need clipping so * its a way to save display time. * * The dimensions of the dial are calculated. The bounds of the DialView is the starting * point. Arrays to hold user path point and operator values are allocated. * * The PSWDefs() call sends some definitions used in the wraps to the interpreter. They * will be available in the interpreter when the wraps call them. */ + newFrame:(NXRect *) frm { self = [super newFrame:frm]; [self allocateGState]; [self setClipping:NO]; viewcenter.x = bounds.size.width/2; viewcenter.y = bounds.size.height/2; if (viewcenter.x > viewcenter.y) maxdim = viewcenter.y - WIDCIRCBRD/2 - CIRCFF ; else maxdim = viewcenter.x - WIDCIRCBRD/2 -CIRCFF; viewcenter.x += bounds.origin.x; viewcenter.y += bounds.origin.y; NX_MALLOC(pts, float, MAX_PTS); NX_MALLOC(ops, char, MAX_OPS); PSWDefs (); [self setupUpaths]; drawFlags.field = 0x80; return self; } /* Free the arrays upon quitting. */ - free { if (pts) NX_FREE(pts); if (ops) NX_FREE(ops); return [super free]; } /* Created by interface. Used to obtain the id's of objects that will be messaged. */ - setMatrixDegreeTypes:anObject { matrixDegreeTypes = anObject; return self; } - setMatrixDisplayTimes:anObject { matrixDisplayTimes = anObject; return self; } /* * Calculate the start and end points and place in user path format. * Send the user path to the server and define it in the server. Execute * the user path for drawing. */ static void setupUpathTrig (pts, ops, x, y, startlen, endlen, deg, upathname, bbox) float pts[]; char ops[]; float x, y, startlen, endlen, deg; char *upathname; float bbox[4]; { int i , j, angle; i = j = 0; for (angle = 0; angle < 360; angle += deg) { pts[i++] = x + (float) cos(angle * RADIANS) * startlen; pts[i++] = y + (float) sin(angle * RADIANS) * startlen; ops[j++] = dps_moveto; pts[i++] = x + (float) cos(angle * RADIANS) * endlen; pts[i++] = y + (float) sin(angle * RADIANS) * endlen; ops[j++] = dps_lineto; } PSWPlaceName(upathname); DPSDoUserPath(pts, i, dps_float, ops, j, bbox, dps_def); } - setupUpaths { float bbox[4]; bbox[0] = bounds.origin.x; bbox[1] = bounds.origin.y; bbox[2] = bounds.origin.x + bounds.size.width; bbox[3] = bounds.origin.y + bounds.size.height; setupUpathTrig(pts, ops, viewcenter.x, viewcenter.y, maxdim * LEN1, maxdim, DEG1, upath1, bbox); setupUpathTrig(pts, ops, viewcenter.x, viewcenter.y, maxdim * LEN10, maxdim, DEG10, upath10, bbox); setupUpathTrig(pts, ops, viewcenter.x, viewcenter.y, maxdim * LEN45, maxdim, DEG45, upath45, bbox); setupUpathTrig(pts, ops, viewcenter.x, viewcenter.y, maxdim * LEN90, maxdim, DEG90, upath90, bbox); return self; } /* * This method changes the title of the menu cell according to the * value of the trace variable. */ -trace:sender { if (trace == NO) [[sender selectedCell] setTitle:"Trace On"]; else [[sender selectedCell] setTitle:"Trace Off"]; trace = !trace; return self; } - eraseTimes:sender { int i; for (i = 0; i < [matrixDisplayTimes cellCount]; i++) [[matrixDisplayTimes cellAt:i :0] setStringValue:""]; return self; } -drawViewOne:sender { drawFlags.field = 0x80 >> [sender selectedRow]; [self display]; return self; } -drawViewAll:sender { drawFlags.field = DRAWALL; [self display]; return self; } /* Use the same line dimensions except rotate the graphics state before each line. */ static void drawWrapsRotate (clr, wid, startlen, endlen, deg) float clr, wid, startlen, endlen, deg; { int angle; PSWSetColorWidth(clr, wid); for (angle = 0; angle < 360; angle += deg) PSWRotate_MakeLine(deg, startlen, 0, endlen, 0); PSstroke(); } - drawWrapsRotate:(int) cell { int ElapsedTime; [[matrixDisplayTimes cellAt:cell :0] setStringValue:""]; PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWFillPath(CLRCIRC); PSWMarkTime (); NXPing (); if (trace) DPSTraceContext(DPSGetCurrentContext(), YES); PSgsave(); PStranslate(viewcenter.x, viewcenter.y); if ([[matrixDegreeTypes cellAt:1 :1] state]) drawWrapsRotate(CLR1, WID1, maxdim * LEN1, maxdim, DEG1); if ([[matrixDegreeTypes cellAt:0 :1] state]) drawWrapsRotate(CLR10, WID10, maxdim * LEN10, maxdim, DEG10); if ([[matrixDegreeTypes cellAt:1 :0] state]) drawWrapsRotate(CLR45, WID45, maxdim * LEN45, maxdim, DEG45); if ([[matrixDegreeTypes cellAt:0 :0] state]) drawWrapsRotate(CLR90, WID90, maxdim * LEN90, maxdim, DEG90); PSgrestore(); if (trace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); PSWSetColorWidth(CLRCIRCBRD, WIDCIRCBRD); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSstroke(); [[matrixDisplayTimes cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* * Calculate the position of the start and end points and add the line to the * current path. Not bad for this particular object but the calculations could * become ugly for something more complex. */ static void drawWrapsTrig (clr, wid, x, y, startlen, endlen, deg) float clr, wid, x, y, startlen, endlen, deg; { int angle; PSWSetColorWidth(clr, wid); for (angle = 0; angle < 360; angle += deg) PSWMakeLine(x + (float) cos(angle * RADIANS) * startlen, y + (float) sin(angle * RADIANS) * startlen, x + (float) cos(angle * RADIANS) * endlen, y + (float) sin(angle * RADIANS) * endlen); PSstroke(); } - drawWrapsTrig:(int) cell { int ElapsedTime; [[matrixDisplayTimes cellAt:cell :0] setStringValue:""]; PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWFillPath(CLRCIRC); PSWMarkTime (); NXPing (); if (trace) DPSTraceContext(DPSGetCurrentContext(), YES); if ([[matrixDegreeTypes cellAt:1 :1] state]) drawWrapsTrig(CLR1, WID1, viewcenter.x, viewcenter.y, maxdim * LEN1, maxdim, DEG1); if ([[matrixDegreeTypes cellAt:0 :1] state]) drawWrapsTrig(CLR10, WID10, viewcenter.x, viewcenter.y, maxdim * LEN10, maxdim, DEG10); if ([[matrixDegreeTypes cellAt:1 :0] state]) drawWrapsTrig(CLR45, WID45, viewcenter.x, viewcenter.y, maxdim * LEN45, maxdim, DEG45); if ([[matrixDegreeTypes cellAt:0 :0] state]) drawWrapsTrig(CLR90, WID90, viewcenter.x, viewcenter.y, maxdim * LEN90, maxdim, DEG90); if (trace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); PSWSetColorWidth(CLRCIRCBRD, WIDCIRCBRD); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSstroke(); [[matrixDisplayTimes cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* * Calculate the start and end points and place in user path format. * Send the entire user path at once using the DPSDoUserPath() call. */ static void drawUpathsTrig (pts, ops, clr, wid, x, y, startlen, endlen, deg, bbox) float pts[]; char ops[]; float clr, wid, x, y, startlen, endlen, deg; float bbox[4]; { int i , j, angle; i = j = 0; for (angle = 0; angle < 360; angle += deg) { pts[i++] = x + (float) cos(angle * RADIANS) * startlen; pts[i++] = y + (float) sin(angle * RADIANS) * startlen; ops[j++] = dps_moveto; pts[i++] = x + (float) cos(angle * RADIANS) * endlen; pts[i++] = y + (float) sin(angle * RADIANS) * endlen; ops[j++] = dps_lineto; } PSWSetColorWidth(clr, wid); DPSDoUserPath(pts, i, dps_float, ops, j, bbox, dps_ustroke); } - drawUpathsTrig:(int) cell; { int ElapsedTime; float bbox[4]; [[matrixDisplayTimes cellAt:cell :0] setStringValue:""]; PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWFillPath(CLRCIRC); PSWMarkTime (); NXPing (); bbox[0] = bounds.origin.x; bbox[1] = bounds.origin.y; bbox[2] = bounds.origin.x + bounds.size.width; bbox[3] = bounds.origin.y + bounds.size.height; if (trace) DPSTraceContext(DPSGetCurrentContext(), YES); if ([[matrixDegreeTypes cellAt:1 :1] state]) drawUpathsTrig(pts, ops, CLR1, WID1, viewcenter.x, viewcenter.y, maxdim * LEN1, maxdim, DEG1, bbox); if ([[matrixDegreeTypes cellAt:0 :1] state]) drawUpathsTrig(pts, ops, CLR10, WID10, viewcenter.x, viewcenter.y, maxdim * LEN10, maxdim, DEG10, bbox); if ([[matrixDegreeTypes cellAt:1 :0] state]) drawUpathsTrig(pts, ops, CLR45, WID45, viewcenter.x, viewcenter.y, maxdim * LEN45, maxdim, DEG45, bbox); if ([[matrixDegreeTypes cellAt:0 :0] state]) drawUpathsTrig(pts, ops, CLR90, WID90, viewcenter.x, viewcenter.y, maxdim * LEN90, maxdim, DEG90, bbox); if (trace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); PSWSetColorWidth(CLRCIRCBRD, WIDCIRCBRD); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSstroke(); [[matrixDisplayTimes cellAt:cell :0] setIntValue:ElapsedTime]; return self; } - drawUpathsServer:(int) cell { int ElapsedTime; [[matrixDisplayTimes cellAt:cell :0] setStringValue:""]; PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWFillPath(CLRCIRC); PSWMarkTime (); NXPing (); if (trace) DPSTraceContext(DPSGetCurrentContext(), YES); if ([[matrixDegreeTypes cellAt:1 :1] state]) { PSWSetColorWidth(CLR1, WID1); PSWDrawUserPath(upath1); } if ([[matrixDegreeTypes cellAt:0 :1] state]) { PSWSetColorWidth(CLR10, WID10); PSWDrawUserPath(upath10); } if ([[matrixDegreeTypes cellAt:1 :0] state]) { PSWSetColorWidth(CLR45, WID45); PSWDrawUserPath(upath45); } if ([[matrixDegreeTypes cellAt:0 :0] state]) { PSWSetColorWidth(CLR90, WID90); PSWDrawUserPath(upath90); } if (trace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); PSWSetColorWidth(CLRCIRCBRD, WIDCIRCBRD); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSstroke(); [[matrixDisplayTimes cellAt:cell :0] setIntValue:ElapsedTime]; return self; } - drawSelf:(NXRect *)r :(int) count { PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); if (drawFlags.flags.wrapsrotate) [self drawWrapsRotate:0]; if (drawFlags.flags.wrapstrig) [self drawWrapsTrig:1]; if (drawFlags.flags.upathstrig) [self drawUpathsTrig:2]; if (drawFlags.flags.upathsserver) [self drawUpathsServer:3]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.