Main.mesa - Rudimentary Graphics exerciser
Authored by Frank Crow
Last Edited by: Crow, August 15, 1983 6:25 pm
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.