<> <> <> DIRECTORY RealFns USING [Cos, Sin], QuickViewer USING [DrawInViewer, BuildViewer], Imager USING [Context, Color, Font, DoSaveAll, SetColor, black, white, MaskVector, PathProc, MaskFill, MaskRectangle, SetFont, SetXY, ShowRope, Rectangle, SetStrokeWidth, SetStrokeEnd, SetStrokeJoint], ImagerColor USING [ColorFromRGB], ImagerFont USING [Find, Scale], ImagerBackdoor USING [GetBounds], Vector2 USING [VEC], Rope USING [ROPE, Cat], MessageWindow USING [Append]; QuickViewerExampleImpl: CEDAR PROGRAM IMPORTS RealFns, QuickViewer, Imager, ImagerBackdoor, ImagerColor, ImagerFont, Rope, MessageWindow ~ BEGIN drawMode: ATOM; -- type of object to draw ShapeRec: TYPE ~ RECORD[ color: Imager.Color, drawMode: ATOM, place: Vector2.VEC ]; DisplayList: TYPE ~ RECORD[ SEQUENCE length: NAT OF ShapeRec ]; displayList: REF DisplayList _ NEW[ DisplayList[32] ]; -- display list of shapes displayListPtr: NAT _ 0; size: REAL _ 20.; -- size of objects (radius or side length) currentColor: Imager.Color _ Imager.black; currentFont: Imager.Font _ NIL; displayContext: Imager.Context _ NIL; Sqr: PROCEDURE [number: REAL] RETURNS [REAL] ~ { RETURN[number * number]; }; Init: PROCEDURE [] ~ { displayContext _ QuickViewer.BuildViewer[ LIST[$Boxes, $Circles, $Octagons, $Xs, $Black, $White, $Red, $Green, $Blue, $Puce, $Spiral], ReDraw, ShutDown, MenuHit, "QuickViewerExample" ]; }; <> MenuHit: PROCEDURE[bttn: ATOM, x, y: REAL, ctrl, shift: BOOL] ~ { keys: Rope.ROPE; SELECT TRUE FROM ctrl AND shift => keys _ "ctrl-shift"; ctrl => keys _ "ctrl"; shift => keys _ "shift"; ENDCASE => keys _ NIL; SELECT bttn FROM $Boxes, $Circles, $Xs, $Octagons => drawMode _ bttn; $Black => currentColor _ ImagerColor.ColorFromRGB[ [ R: 0.0, G: 0.0, B: 0.0 ] ]; $White => currentColor _ ImagerColor.ColorFromRGB[ [ R: 1.0, G: 1.0, B: 1.0 ] ]; $Red => currentColor _ ImagerColor.ColorFromRGB[ [ R: 1.0, G: 0.0, B: 0.0 ] ]; $Green => currentColor _ ImagerColor.ColorFromRGB[ [ R: 0.0, G: 1.0, B: 0.0 ] ]; $Blue => currentColor _ ImagerColor.ColorFromRGB[ [ R: 0.0, G: 0.0, B: 1.0 ] ]; $Puce => currentColor _ ImagerColor.ColorFromRGB[ [ R: 0.5, G: 0.2, B: 0.4 ] ]; $Spiral => DrawSpiral[]; $LeftButton, $LeftHeld => { displayList[displayListPtr] _ [currentColor, drawMode, [x, y] ]; SELECT drawMode FROM $Xs => DrawX[displayList[displayListPtr].place, size]; $Boxes => DrawBox[displayList[displayListPtr].place, size]; $Circles => DrawCircle[displayList[displayListPtr].place, size]; $Octagons => DrawOct[displayList[displayListPtr].place, size]; ENDCASE; displayListPtr _ displayListPtr + 1; IF displayListPtr = displayList.length THEN { -- get longer display list newList: REF DisplayList _ NEW[ DisplayList[displayList.length + 32] ]; FOR i: NAT IN [0..displayListPtr) DO newList[i] _ displayList[i]; ENDLOOP; displayList _ newList; }; }; $MiddleButton => ShowRope[ x, y, Rope.Cat["MiddleButton ", keys] ]; $RightButton => ShowRope[ x, y, Rope.Cat["RightButton ", keys] ]; $MiddleHeld => ShowRope[ x, y, Rope.Cat["MiddleHeld ", keys] ]; $RightHeld => ShowRope[ x, y, Rope.Cat["RightHeld ", keys] ]; ENDCASE; }; <> ReDraw: PROCEDURE [context: Imager.Context] ~ { savedColor: Imager.Color _ currentColor; proc: PROC ~ { -- erase viewport first Imager.SetColor[context, Imager.white]; -- set color to white Imager.MaskRectangle[context, ImagerBackdoor.GetBounds[context]]; -- fill screen }; Imager.DoSaveAll[context, proc]; FOR i: NAT IN [0..displayListPtr) DO currentColor _ displayList[i].color; SELECT displayList[i].drawMode FROM $Xs => DrawX[displayList[i].place, size]; $Boxes => DrawBox[displayList[i].place, size]; $Circles => DrawCircle[displayList[i].place, size]; $Octagons => DrawOct[displayList[i].place, size]; ENDCASE; ENDLOOP; currentColor _ savedColor; }; <> ShutDown: PROCEDURE [] ~ { MessageWindow.Append["QuickViewerExample Exited",TRUE]; -- say goodbye }; <> DrawSpiral: PROC [] ~ { screen: Imager.Rectangle _ ImagerBackdoor.GetBounds[displayContext]; oldPt: Vector2.VEC _ [screen.w/2.0, screen.h/2.0]; Imager.SetStrokeWidth[displayContext, 10.0]; Imager.SetStrokeEnd[displayContext, round]; Imager.SetStrokeJoint[displayContext, mitered]; Imager.SetColor[displayContext, currentColor]; FOR i: NAT IN [0..3000] DO newPt: Vector2.VEC _ [ i/10.0 * RealFns.Sin[i/40.0] + screen.w/2.0 , i/10.0 * RealFns.Cos[i/40.0] + screen.h/2.0 ]; Imager.MaskVector[displayContext, oldPt, newPt]; oldPt _ newPt; ENDLOOP; }; <> DrawX: PROC [controlPoint: Vector2.VEC, leg: REAL] ~ { DoDrawX: PROC [context: Imager.Context] ~ { Imager.SetColor[context, currentColor]; Imager.MaskVector[ context, [controlPoint.x - leg, controlPoint.y - leg], [controlPoint.x + leg, controlPoint.y + leg] ]; Imager.MaskVector[ context, [controlPoint.x - leg, controlPoint.y + leg], [controlPoint.x + leg, controlPoint.y - leg] ]; }; QuickViewer.DrawInViewer[DoDrawX]; -- ask the viewer procs to call you back }; DrawBox: PROC [controlPoint: Vector2.VEC, side: REAL] ~ { DoDrawBox: PROC [context: Imager.Context] ~ { Path: Imager.PathProc ~ { moveTo[[controlPoint.x - side, controlPoint.y - side]]; lineTo[[controlPoint.x + side, controlPoint.y - side]]; lineTo[[controlPoint.x + side, controlPoint.y + side]]; lineTo[[controlPoint.x - side, controlPoint.y + side]]; lineTo[[controlPoint.x - side, controlPoint.y - side]]; }; Imager.SetColor[context, currentColor]; Imager.MaskFill[context, Path]; }; QuickViewer.DrawInViewer[DoDrawBox]; -- ask the viewer procs to call you back }; DrawCircle: PROC [controlPoint: Vector2.VEC, radius: REAL] ~ { DoDrawCircle: PROC [context: Imager.Context] ~ { Path: Imager.PathProc ~ { x, y, theta: REAL _ 0.; moveTo[[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; lineTo[[x, y]]; theta _ theta + 3.1416 / 12.; ENDLOOP; }; Imager.SetColor[context, currentColor]; Imager.MaskFill[context, Path]; }; QuickViewer.DrawInViewer[DoDrawCircle]; -- ask the viewer procs to call you back }; DrawOct: PROC [controlPoint: Vector2.VEC, radius: REAL] ~ { -- draw an octagon DoDrawOct: PROC [context: Imager.Context] ~ { Path: Imager.PathProc ~ { x, y, theta: REAL _ 0.; moveTo[[controlPoint.x + radius , controlPoint.y - radius/3.]]; lineTo[[controlPoint.x + radius , controlPoint.y + radius/3.]]; lineTo[[controlPoint.x + radius/3., controlPoint.y + radius]]; lineTo[[controlPoint.x - radius/3., controlPoint.y + radius]]; lineTo[[controlPoint.x - radius, controlPoint.y + radius/3.]]; lineTo[[controlPoint.x - radius, controlPoint.y - radius/3.]]; lineTo[[controlPoint.x - radius/3., controlPoint.y - radius]]; lineTo[[controlPoint.x + radius/3., controlPoint.y - radius]]; lineTo[[controlPoint.x + radius, controlPoint.y - radius/3.]]; }; Imager.SetColor[context, currentColor]; Imager.MaskFill[context, Path]; }; QuickViewer.DrawInViewer[DoDrawOct]; -- ask the viewer procs to call you back }; ShowRope: PROC[x, y: REAL, rope: Rope.ROPE] ~ { DoShowRope: PROC[context: Imager.Context] ~ { IF currentFont = NIL THEN { currentFont _ ImagerFont.Find["Xerox/Pressfonts/TimesRoman-MRR"]; currentFont _ ImagerFont.Scale[currentFont, 12.0]; }; Imager.SetColor[context, currentColor]; Imager.SetFont[context, currentFont]; Imager.SetXY[context, [x, y]]; Imager.ShowRope[context, rope]; }; QuickViewer.DrawInViewer[DoShowRope]; -- ask the viewer procs to call you back }; Init[]; END.