This is DialView.m in view mode; [Download] [Up]
/* * (C) 1990 by Adobe Systems Incorporated. All rights reserved. * * This file may be freely copied and redistributed as long as: * 1) This entire notice continues to be included in the file, * 2) If the file has been modified in any way, a notice of such * modification is conspicuously indicated. * * PostScript, Display PostScript, and Adobe are registered trademarks of * Adobe Systems Incorporated. * * ************************************************************************ * 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 NONINFINGEMENT OF THIRD PARTY RIGHTS. * ************************************************************************ */ /* * DialView.m * Created by Ken Fromm * * This application draws an object in several ways. The first way draws * with the help of the matrix operation rotate. The second draws with * rotate and user paths. The third draws with basic wraps performing * the calculations on the client side. The fourth draws with the * calculated user paths placed in a buffer and sent to the server a * single request. The fifth follows the same procedure as the previous * method except that the user path is stored in the server and not * resent each time. */ #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 setupUserPaths]; drawFlags.field = 0x80; return self; } /* Free the gstate upon quitting. */ - free { if (pts) NX_FREE(pts); if (ops) NX_FREE(ops); [self freeGState]; 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 setupTrigUserPath( pts, ops, x, y, startlen, endlen, deg, upathname) float pts[]; char ops[]; float x, y, startlen, endlen, deg; char *upathname; { int i , j, angle; i = 4; j = 1; 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; } PSWDefineUserPath(pts, i, ops, j, upathname ); } - setupUserPaths { pts[0] = bounds.origin.x; pts[1] = bounds.origin.y; pts[2] = bounds.origin.x + bounds.size.width; pts[3] = bounds.origin.y + bounds.size.height; ops[0] = dps_setbbox; setupTrigUserPath(pts, ops, viewcenter.x, viewcenter.y, maxdim * LEN1, maxdim, DEG1, upath1); setupTrigUserPath(pts, ops, viewcenter.x, viewcenter.y, maxdim * LEN10, maxdim, DEG10, upath10); setupTrigUserPath(pts, ops, viewcenter.x, viewcenter.y, maxdim * LEN45, maxdim, DEG45, upath45); setupTrigUserPath(pts, ops, viewcenter.x, viewcenter.y, maxdim * LEN90, maxdim, DEG90, upath90); return self; } - eraseTimes:sender { int i; for (i = 0; i < [matrixDisplayTimes cellCount]; i++) [[matrixDisplayTimes cellAt:i :0] setStringValue:""]; return self; } -drawViewOne:sender { int i, row; row = [sender selectedRow]; drawFlags.field = 0x80 >> row; [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 drawRotateLines (clr, wid, startlen, endlen, deg) float clr, wid, startlen, endlen, deg; { int angle; for (angle = 0; angle < 360; angle += deg) PSWRotate_MakeLine(deg, startlen, 0, endlen, 0); PSWStrokePath(clr, wid); } - drawRotate:(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 (); PSgsave(); PStranslate(viewcenter.x, viewcenter.y); if ([[matrixDegreeTypes cellAt:1 :1] state]) drawRotateLines(CLR1, WID1, maxdim * LEN1, maxdim, DEG1); if ([[matrixDegreeTypes cellAt:0 :1] state]) drawRotateLines(CLR10, WID10, maxdim * LEN10, maxdim, DEG10); if ([[matrixDegreeTypes cellAt:1 :0] state]) drawRotateLines(CLR45, WID45, maxdim * LEN45, maxdim, DEG45); if ([[matrixDegreeTypes cellAt:0 :0] state]) drawRotateLines(CLR90, WID90, maxdim * LEN90, maxdim, DEG90); PSgrestore(); PSWReturnTime (&ElapsedTime); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWStrokePath(CLRCIRCBRD, WIDCIRCBRD); [[matrixDisplayTimes cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* Put the line description in a user path and then rotate and uappend. * Not a good way to do it. (In other words, don't try this at home.) */ static void drawRotateUserPathLines(pts, ops, clr, wid, startlen, endlen, deg) float pts[]; char ops[]; float clr, wid, startlen, endlen, deg; { int angle; pts[0] = pts[4] = startlen; pts[2] = pts[6] = endlen; pts[1] = -wid/2; pts[3] = -pts[1]; pts[5] = pts[7] = 0; PSsetgray(clr); PSsetlinewidth(wid); for (angle = 0; angle < 360; angle += deg) PSWRotate_UAppend(deg, pts, 8, ops, 3); PSstroke(); } - drawRotateUserPaths:(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 (); ops[0] = dps_setbbox; ops[1] = dps_moveto; ops[2] = dps_lineto; PSgsave(); PStranslate(viewcenter.x, viewcenter.y); if ([[matrixDegreeTypes cellAt:1 :1] state]) drawRotateUserPathLines(pts, ops, CLR1, WID1, maxdim * LEN1, maxdim, DEG1); if ([[matrixDegreeTypes cellAt:0 :1] state]) drawRotateUserPathLines(pts, ops, CLR10, WID10, maxdim * LEN10, maxdim, DEG10); if ([[matrixDegreeTypes cellAt:1 :0] state]) drawRotateUserPathLines(pts, ops, CLR45, WID45, maxdim * LEN45, maxdim, DEG45); if ([[matrixDegreeTypes cellAt:0 :0] state]) drawRotateUserPathLines(pts, ops, CLR90, WID90, maxdim * LEN90, maxdim, DEG90); PSgrestore(); PSWReturnTime (&ElapsedTime); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWStrokePath(CLRCIRCBRD, WIDCIRCBRD); [[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 drawTrigLines (clr, wid, x, y, startlen, endlen, deg) float clr, wid, x, y, startlen, endlen, deg; { int angle; 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); PSWStrokePath(clr, wid); } - drawTrig:(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 ([[matrixDegreeTypes cellAt:1 :1] state]) drawTrigLines(CLR1, WID1, viewcenter.x, viewcenter.y, maxdim * LEN1, maxdim, DEG1); if ([[matrixDegreeTypes cellAt:0 :1] state]) drawTrigLines(CLR10, WID10, viewcenter.x, viewcenter.y, maxdim * LEN10, maxdim, DEG10); if ([[matrixDegreeTypes cellAt:1 :0] state]) drawTrigLines(CLR45, WID45, viewcenter.x, viewcenter.y, maxdim * LEN45, maxdim, DEG45); if ([[matrixDegreeTypes cellAt:0 :0] state]) drawTrigLines(CLR90, WID90, viewcenter.x, viewcenter.y, maxdim * LEN90, maxdim, DEG90); PSWReturnTime (&ElapsedTime); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWStrokePath(CLRCIRCBRD, WIDCIRCBRD); [[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. */ static void drawTrigUserPathLines( pts, ops, clr, wid, x, y, startlen, endlen, deg) float pts[]; char ops[]; float clr, wid, x, y, startlen, endlen, deg; { int i , j, angle; i = 4; j = 1; 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; } PSWUStroke(clr, wid, pts, i, ops, j); } - drawTrigUserPaths:(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 (); pts[0] = bounds.origin.x; pts[1] = bounds.origin.y; pts[2] = bounds.origin.x + bounds.size.width; pts[3] = bounds.origin.y + bounds.size.height; ops[0] = dps_setbbox; if ([[matrixDegreeTypes cellAt:1 :1] state]) drawTrigUserPathLines(pts, ops, CLR1, WID1, viewcenter.x, viewcenter.y, maxdim * LEN1, maxdim, DEG1); if ([[matrixDegreeTypes cellAt:0 :1] state]) drawTrigUserPathLines(pts, ops, CLR10, WID10, viewcenter.x, viewcenter.y, maxdim * LEN10, maxdim, DEG10); if ([[matrixDegreeTypes cellAt:1 :0] state]) drawTrigUserPathLines(pts, ops, CLR45, WID45, viewcenter.x, viewcenter.y, maxdim * LEN45, maxdim, DEG45); if ([[matrixDegreeTypes cellAt:0 :0] state]) drawTrigUserPathLines(pts, ops, CLR90, WID90, viewcenter.x, viewcenter.y, maxdim * LEN90, maxdim, DEG90); PSWReturnTime (&ElapsedTime); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWStrokePath(CLRCIRCBRD, WIDCIRCBRD); [[matrixDisplayTimes cellAt:cell:0] setIntValue:ElapsedTime]; return self; } - drawTrigUserPathsServer:(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 ([[matrixDegreeTypes cellAt:1 :1] state]) PSWDrawUserPath(CLR1, WID1, upath1); if ([[matrixDegreeTypes cellAt:0 :1] state]) PSWDrawUserPath(CLR10, WID10, upath10); if ([[matrixDegreeTypes cellAt:1 :0] state]) PSWDrawUserPath(CLR45, WID45, upath45); if ([[matrixDegreeTypes cellAt:0 :0] state]) PSWDrawUserPath(CLR90, WID90, upath90); PSWReturnTime (&ElapsedTime); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWStrokePath(CLRCIRCBRD, WIDCIRCBRD); [[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 drawDPSUserPathLines( 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; } PSsetgray(clr); PSsetlinewidth(wid); DPSDoUserPath(pts, i, dps_float, ops, j, bbox, dps_ustroke); } - drawDPSUserPaths:(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 ([[matrixDegreeTypes cellAt:1 :1] state]) drawDPSUserPathLines(pts, ops, CLR1, WID1, viewcenter.x, viewcenter.y, maxdim * LEN1, maxdim, DEG1, bbox); if ([[matrixDegreeTypes cellAt:0 :1] state]) drawDPSUserPathLines(pts, ops, CLR10, WID10, viewcenter.x, viewcenter.y, maxdim * LEN10, maxdim, DEG10, bbox); if ([[matrixDegreeTypes cellAt:1 :0] state]) drawDPSUserPathLines(pts, ops, CLR45, WID45, viewcenter.x, viewcenter.y, maxdim * LEN45, maxdim, DEG45, bbox); if ([[matrixDegreeTypes cellAt:0 :0] state]) drawDPSUserPathLines(pts, ops, CLR90, WID90, viewcenter.x, viewcenter.y, maxdim * LEN90, maxdim, DEG90, bbox); PSWReturnTime (&ElapsedTime); PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim); PSWStrokePath(CLRCIRCBRD, WIDCIRCBRD); [[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.rotate) [self drawRotate:0]; if (drawFlags.flags.uappend) [self drawRotateUserPaths:1]; if (drawFlags.flags.trig) [self drawTrig:2]; if (drawFlags.flags.userpaths) [self drawTrigUserPaths:3]; if (drawFlags.flags.server) [self drawTrigUserPathsServer:4]; if (drawFlags.flags.dpsuserpath) [self drawDPSUserPaths:5]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.