<> <> <> DIRECTORY RealFns USING [Cos, Sin], QuickViewer USING [DrawInViewer, BuildViewer], Graphics USING [Context, SetCP, DrawTo, SetColor, white, black, Mark, Save, DrawBox, GetBounds, Restore], MessageWindow USING [Append]; Main: CEDAR PROGRAM IMPORTS RealFns, QuickViewer, Graphics, MessageWindow = BEGIN Point2d: TYPE = RECORD [ x, y: REAL]; Color: TYPE = { black, white }; drawMode: ATOM; -- type of object to draw pointList: LIST OF Point2d _ NIL; -- display list of points size: REAL _ 20.; -- size of objects (radius or side length) Sqr: PROCEDURE [number: REAL] RETURNS [REAL]= INLINE { RETURN[number * number]; }; DrawX: PROC [controlPoint: Point2d, leg: REAL, color: Color] = { DoDrawX: PROC [dc: Graphics.Context] = { IF color = white THEN Graphics.SetColor[dc, Graphics.white] -- set color to white ELSE Graphics.SetColor[dc, Graphics.black]; -- set color to black Graphics.SetCP[dc, controlPoint.x - leg, controlPoint.y - leg]; Graphics.DrawTo[dc, controlPoint.x + leg, controlPoint.y + leg]; Graphics.SetCP[dc, controlPoint.x - leg, controlPoint.y + leg]; Graphics.DrawTo[dc, controlPoint.x + leg, controlPoint.y - leg]; }; QuickViewer.DrawInViewer[DoDrawX]; -- ask the viewer procs to call you back }; DrawBox: PROC [controlPoint: Point2d, side: REAL, color: Color] = { DoDrawBox: PROC [dc: Graphics.Context] = { IF color = white THEN Graphics.SetColor[dc, Graphics.white] -- set color to white ELSE Graphics.SetColor[dc, Graphics.black]; -- set color to black Graphics.SetCP[dc, controlPoint.x - side, controlPoint.y - side]; Graphics.DrawTo[dc, controlPoint.x + side, controlPoint.y - side]; Graphics.DrawTo[dc, controlPoint.x + side, controlPoint.y + side]; Graphics.DrawTo[dc, controlPoint.x - side, controlPoint.y + side]; Graphics.DrawTo[dc, controlPoint.x - side, controlPoint.y - side]; }; QuickViewer.DrawInViewer[DoDrawBox]; -- ask the viewer procs to call you back }; DrawCircle: PROC [controlPoint: Point2d, radius: REAL, color: Color] = { DoDrawCircle: PROC [dc: Graphics.Context] = { x, y, theta: REAL _ 0.; IF color = white THEN Graphics.SetColor[dc, Graphics.white] -- set color to white ELSE Graphics.SetColor[dc, Graphics.black]; -- set color to black Graphics.SetCP[dc, controlPoint.x + radius, controlPoint.y]; UNTIL theta > 2*3.1416 DO x _ radius * RealFns.Cos[theta] + controlPoint.x; y _ radius * RealFns.Sin[theta] + controlPoint.y; Graphics.DrawTo[dc, x, y]; theta _ theta + 3.1416 / 12.; ENDLOOP; }; QuickViewer.DrawInViewer[DoDrawCircle]; -- ask the viewer procs to call you back }; DrawOct: PROC [controlPoint: Point2d, radius: REAL, color: Color] = { -- draw an octagon DoDrawOct: PROC [dc: Graphics.Context] = { x, y, theta: REAL _ 0.; IF color = white THEN Graphics.SetColor[dc, Graphics.white] -- set color to white ELSE Graphics.SetColor[dc, Graphics.black]; -- set color to black Graphics.SetCP [dc, controlPoint.x + radius , controlPoint.y - radius/3.]; Graphics.DrawTo[dc, controlPoint.x + radius , controlPoint.y + radius/3.]; Graphics.DrawTo[dc, controlPoint.x + radius/3., controlPoint.y + radius]; Graphics.DrawTo[dc, controlPoint.x - radius/3., controlPoint.y + radius]; Graphics.DrawTo[dc, controlPoint.x - radius, controlPoint.y + radius/3.]; Graphics.DrawTo[dc, controlPoint.x - radius, controlPoint.y - radius/3.]; Graphics.DrawTo[dc, controlPoint.x - radius/3., controlPoint.y - radius]; Graphics.DrawTo[dc, controlPoint.x + radius/3., controlPoint.y - radius]; Graphics.DrawTo[dc, controlPoint.x + radius, controlPoint.y - radius/3.]; }; QuickViewer.DrawInViewer[DoDrawOct]; -- ask the viewer procs to call you back }; MenuHit: PROCEDURE[command: ATOM, x, y: REAL] = { SELECT command FROM $Boxes, $Circles, $Exes, $Octagons => drawMode _ command; $LeftButton, $LeftHeld => { pointList _ CONS[ [x, y], pointList]; SELECT drawMode FROM $Exes => DrawX[pointList.first, size, black]; $Boxes => DrawBox[pointList.first, size, black]; $Circles => DrawCircle[pointList.first, size, black]; $Octagons => DrawOct[pointList.first, size, black]; ENDCASE; }; $MiddleButton => DrawX[[x, y], size, black]; $RightButton => DrawCircle[[x, y], size, black]; $MiddleHeld => DrawX[[x, y], size, white]; $RightHeld => DrawCircle[[x, y], size, white]; ENDCASE; }; ReDraw: PROCEDURE [dc: Graphics.Context] = { listPtr: LIST OF Point2d; -- erase viewport first mark: Graphics.Mark _ Graphics.Save[dc]; -- mark stack Graphics.SetColor[dc, Graphics.white]; -- set color to white Graphics.DrawBox[dc,Graphics.GetBounds[dc]]; -- erase by drawing box Graphics.Restore[dc,mark]; -- restore stack listPtr _ pointList; WHILE listPtr # NIL DO SELECT drawMode FROM $Exes => DrawX[listPtr.first, size, black]; $Boxes => DrawBox[listPtr.first, size, black]; $Circles => DrawCircle[listPtr.first, size, black]; $Octagons => DrawOct[listPtr.first, size, black]; ENDCASE; listPtr _ listPtr.rest; ENDLOOP; }; ShutDown: PROCEDURE [] = { MessageWindow.Append["EasyGraphics Exited",TRUE]; -- say goodbye }; Init: PROCEDURE [] = { QuickViewer.BuildViewer[LIST[$Boxes, $Circles, $Octagons, $Exes], ReDraw, ShutDown, MenuHit, "EasyGraphics"]; }; Init[]; END.