<> <> <> <> <> <<>> <> DIRECTORY RealFns USING [Cos, Sin], QuickViewer USING [BuildViewer, DrawInViewer, QuickView], 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) stopMe: BOOLEAN _ FALSE; currentColor: Imager.Color _ Imager.black; currentFont: Imager.Font _ NIL; displayViewer: REF QuickViewer.QuickView _ NIL; Sqr: PROCEDURE [number: REAL] RETURNS [REAL] ~ { RETURN[number * number]; }; Init: PROCEDURE [] ~ { displayViewer _ QuickViewer.BuildViewer[ "QuickViewerExample", LIST["Boxes", "Circles", "Octagons", "Xs", "Black", "White", "Red", "Green", "Blue", "Puce", "Spiral", "STOP!"], ReDraw, MenuHit, ShutDown ]; }; <> MenuHit: PROCEDURE[bttn, choice: ATOM, x, y: REAL] ~ { keys: Rope.ROPE; SELECT choice FROM $ControlShift => keys _ "ctrl-shift"; $Control => 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[]; $STOP => { stopMe _ TRUE; ShowRope[ 100.0, 100.0, "STOP!" ]; }; $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 [imagerCtx: Imager.Context, toDo: REF ANY] ~ { <> savedColor: Imager.Color _ currentColor; proc: PROC ~ { -- erase viewport first Imager.SetColor[imagerCtx, Imager.white]; -- set color to white Imager.MaskRectangle[imagerCtx, ImagerBackdoor.GetBounds[imagerCtx]]; -- fill screen }; Imager.DoSaveAll[imagerCtx, 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 [] ~ { oldPt, newPt: Vector2.VEC; screen: Imager.Rectangle; DoVector: PROC [context: Imager.Context] ~ { Imager.SetStrokeWidth[context, 8.0]; Imager.SetStrokeEnd[context, round]; Imager.SetStrokeJoint[context, mitered]; Imager.SetColor[context, currentColor]; Imager.MaskVector[context, oldPt, newPt]; }; DoSetUp: PROC [context: Imager.Context] ~ { screen _ ImagerBackdoor.GetBounds[context]; }; QuickViewer.DrawInViewer[displayViewer, DoSetUp]; oldPt _ [screen.w/2.0, screen.h/2.0]; FOR i: NAT IN [0..1000] DO newPt _ [ i/10.0 * RealFns.Sin[i/40.0] + screen.w/2.0 , i/10.0 * RealFns.Cos[i/40.0] + screen.h/2.0 ]; IF stopMe THEN { stopMe _ FALSE; EXIT; }; QuickViewer.DrawInViewer[displayViewer, DoVector]; 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[displayViewer, DoDrawX]; -- get 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[displayViewer, DoDrawBox]; }; 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[displayViewer, DoDrawCircle]; -- get viewer 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[displayViewer, DoDrawOct]; }; 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[displayViewer, DoShowRope]; }; Init[]; END.