-- File: Scratchpad2dUserImpl.mesa
-- Last edited by Bier on December 18, 1982 1:41 am
-- Author: Eric Bier on March 22, 1983 1:37 pm
-- Contents: Functions called by the buttons on a Scratchpad2d viewer.
DIRECTORY
Containers,
CoordSys,
Graphics,
Menus,
PadGraphics,
Scratchpad2dUser,
SV2d,
SVPolygon2d,
SweepGeometry,
SVDraw,
SVLines2d,
SVVector2d,
ViewerClasses,
ViewerOps;
Scratchpad2dUserImpl: CEDAR PROGRAM
IMPORTS Graphics, PadGraphics, SVDraw, SVLines2d, SVPolygon2d, SVVector2d, ViewerOps
EXPORTS Scratchpad2dUser =
BEGIN
CoordSystem: TYPE = REF CoordSysObj;
CoordSysObj: TYPE = CoordSys.CoordSysObj;
MouseButton: TYPE = Menus.MouseButton;
Path: TYPE = REF PathObj;
PathObj: TYPE = SV2d.PathObj;
Point2d: TYPE = SV2d.Point2d;
Polygon: TYPE = REF PolygonObj;
PolygonObj: TYPE = SV2d.PolygonObj;
TrigLineSeg: TYPE = SV2d.TrigLineSeg;
Vector2d: TYPE = SVVector2d.Vector2d;
Viewer: TYPE = ViewerClasses.Viewer;
ScratchViewerData: TYPE = REF ScratchViewerDataObj;
ScratchViewerDataObj: TYPE = Scratchpad2dUser.ScratchViewerDataObj;
TextSectionData: TYPE = REF TextSectionDataObj;
TextSectionDataObj: TYPE = Scratchpad2dUser.TextSectionDataObj;
ScratchpadData: TYPE = REF ScratchpadDataObj;
ScratchpadDataObj: TYPE = Scratchpad2dUser.ScratchpadDataObj;
ScratchpadMode: TYPE = {off, pointAt, draw};
squareSide: REAL = 6;
Painter: PUBLIC PROC [proc: PROC [Graphics.Context], scratchViewerData: ScratchViewerData ← NIL] = TRUSTED {
scratchpadData: ScratchpadData ← NARROW[scratchViewerData.scratchpad.data];
scratchpadData.proc ← proc;
ViewerOps.PaintViewer[viewer: scratchViewerData.scratchpad,
hint: client,
whatChanged: scratchViewerData,
clearClient: FALSE];
}; -- end of Painter
PaintRevo: PUBLIC PROC [scratchViewerData: ScratchViewerData] = TRUSTED {
DoPaintRevo: PROC [dc: Graphics.Context] = TRUSTED {
-- begin at y axis to show user how the final effect will look
IF scratchpadData.path.len = 0 THEN RETURN;
-- paint right side
PadGraphics.MoveTo[dc, [0, scratchpadData.path[0][2]], scratchpadData.origin];
PadGraphics.DrawSquare[dc, squareSide, [0, scratchpadData.path[0][2]], scratchpadData.origin];
FOR i: NAT IN[0..scratchpadData.path.len) DO
PadGraphics.DrawTo[dc, scratchpadData.path[i], scratchpadData.origin];
PadGraphics.DrawSquare[dc, squareSide, scratchpadData.path[i], scratchpadData.origin];
ENDLOOP;
-- end at y axis to show user how the final sweep will look
PadGraphics.DrawTo[dc, [0, scratchpadData.path[scratchpadData.path.len-1][2]],
scratchpadData.origin];
PadGraphics.DrawSquare[dc, squareSide, [0, scratchpadData.path[scratchpadData.path.len-1][2]],
scratchpadData.origin];
-- now paint left side
PadGraphics.MirrorMoveTo[dc, [0, scratchpadData.path[0][2]], scratchpadData.origin];
FOR i: NAT IN[0..scratchpadData.path.len) DO
PadGraphics.MirrorDrawTo[dc, scratchpadData.path[i], scratchpadData.origin];
PadGraphics.MirrorDrawSquare[dc, squareSide, scratchpadData.path[i], scratchpadData.origin];
ENDLOOP;
-- end at y axis to show user how the final sweep will look
PadGraphics.MirrorDrawTo[dc,
[0, scratchpadData.path[scratchpadData.path.len-1][2]],
scratchpadData.origin];
}; -- end of DoPaintRevo
scratchpadData: ScratchpadData ← NARROW[scratchViewerData.scratchpad.data];
Painter[DoPaintRevo, scratchpadData.scratchViewerData];
}; -- end of PaintPoly
PaintLin: PUBLIC PROC [scratchViewerData: ScratchViewerData] = TRUSTED {
DoPaintLin: PROC [dc: Graphics.Context] = TRUSTED {
-- paint right side
IF scratchpadData.path.len = 0 THEN RETURN;
PadGraphics.MoveTo[dc, scratchpadData.path[0], scratchpadData.origin];
PadGraphics.DrawSquare[dc, squareSide, scratchpadData.path[0], scratchpadData.origin];
FOR i: NAT IN[1..scratchpadData.path.len) DO
PadGraphics.DrawTo[dc, scratchpadData.path[i], scratchpadData.origin];
PadGraphics.DrawSquare[dc, squareSide, scratchpadData.path[i], scratchpadData.origin];
ENDLOOP;
PadGraphics.DrawTo[dc, scratchpadData.path[0], scratchpadData.origin];
}; -- end of DoPaintLin
scratchpadData: ScratchpadData ← NARROW[scratchViewerData.scratchpad.data];
Painter[DoPaintLin, scratchpadData.scratchViewerData];
}; -- end of PaintLin
Erase: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
scratchViewerData: ScratchViewerData ← NARROW[clientData];
scratchpadData: ScratchpadData ← NARROW[scratchViewerData.scratchpad.data];
DoErase: PROC [dc: Graphics.Context] = TRUSTED {
Graphics.SetColor[dc, Graphics.white];
Graphics.DrawBox[dc,Graphics.GetBounds[dc]];
};
Painter[DoErase, scratchViewerData];
};
Normals: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
-- go through each segment of the current picture. Find its outward pointing normal and draw it.
scratchViewerData: ScratchViewerData ← NARROW[clientData];
scratchpadData: ScratchpadData ← NARROW[scratchViewerData.scratchpad.data];
path: Path ← scratchpadData.path;
iPlusOne: NAT;
p1, p2: Point2d;
seg: TrigLineSeg;
normal: Vector2d;
midpoint: Point2d;
DoDrawNormals: PROC [dc: Graphics.Context] = TRUSTED {
mark: Graphics.Mark ← Graphics.Save[dc];
Graphics.SetColor[dc, Graphics.black];
FOR i: NAT IN [0..path.len) DO
iPlusOne ← IF i = path.len -1 THEN 0 ELSE i + 1;
p1 ← path[i];
p2 ← path[iPlusOne];
seg ← SVLines2d.CreateTrigLineSeg[p1, p2];
normal ← SVVector2d.LeftNormalOfTrigLineSeg[seg];
midpoint[1] ← (p1[1]+p2[1])/2;
midpoint[2] ← (p1[2] + p2[2])/2;
PadGraphics.Draw2dVector[dc: dc, vec: normal, at: midpoint, origin: scratchpadData.origin];
ENDLOOP;
Graphics.SetColor[dc, Graphics.black];
Graphics.Restore[dc,mark];
};
Painter[DoDrawNormals, scratchViewerData];
};
PlaceOrigin: PUBLIC PROC [viewer: Viewer] = TRUSTED {
-- viewer is the scratchpad window
-- find the center of the scratchpad window in scratchpad window coordinates
originX, originY: INTEGER;
scratchpadData: ScratchpadData ← NARROW[viewer.data];
originX ← viewer.cw; -- convert window width to real
originY ← viewer.ch; -- convert window height to real
originX ← originX/2; -- find the midpoint in window coords
originY ← originY/2;
scratchpadData.origin ← [originX, originY];
};
CrossHairs: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
DoCrossHairs: PROC [dc: Graphics.Context] = TRUSTED {
PadGraphics.CrossHairs[dc, scratchpadData.origin];
};
scratchViewerData: ScratchViewerData ← NARROW[clientData];
scratchpadData: ScratchpadData ← NARROW[scratchViewerData.scratchpad.data];
Painter[DoCrossHairs, scratchViewerData];
};
DrawScene: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
scratchViewerData: ScratchViewerData ← NARROW[clientData];
scratchpadData: ScratchpadData ← NARROW[scratchViewerData.scratchpad.data];
Erase[parent, clientData, mouseButton, shift, control];
CrossHairs[parent, clientData, mouseButton, shift, control];
SELECT scratchpadData.mode FROM
drawLin => PaintLin[scratchViewerData];
drawRevo =>PaintRevo[scratchViewerData];
ENDCASE;
};
DrawLin: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
scratchViewerData: ScratchViewerData ← NARROW[clientData];
Erase[parent, clientData, mouseButton, shift, control];
CrossHairs[parent, clientData, mouseButton, shift, control];
PaintLin[scratchViewerData];
};
DrawRevo: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
scratchViewerData: ScratchViewerData ← NARROW[clientData];
Erase[parent, clientData, mouseButton, shift, control];
CrossHairs[parent, clientData, mouseButton, shift, control];
PaintRevo[scratchViewerData];
};
NewLin: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
currentState: ScratchViewerData ← NARROW[clientData];
scratchpadData: ScratchpadData ←
NARROW[currentState.scratchpad.data];
scratchpadData.mode ← drawLin;
SVPolygon2d.ClearPath[scratchpadData.path];
DrawScene[parent, clientData, mouseButton, shift, control];
}; -- end of NewLine
NewRevo: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
currentState: ScratchViewerData ← NARROW[clientData];
scratchpadData: ScratchpadData ←
NARROW[currentState.scratchpad.data];
scratchpadData.mode ← drawRevo;
SVPolygon2d.ClearPath[scratchpadData.path];
DrawScene[parent, clientData, mouseButton, shift, control];
}; -- end of NewRevo
TestPoints: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
currentState: ScratchViewerData ← NARROW[clientData];
scratchpadData: ScratchpadData ←
NARROW[currentState.scratchpad.data];
scratchpadData.mode ← pointAt;
}; -- end of TestPoints
Circle: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
scratchViewerData: ScratchViewerData ← NARROW[clientData];
scratchpadData: ScratchpadData ← NARROW[scratchViewerData.scratchpad.data];
DoDrawCircle: PROC [dc: Graphics.Context] = TRUSTED {
SVDraw.Circle[dc, scratchpadData.origin[1], scratchpadData.origin[2], 100];
};
Painter[DoDrawCircle, scratchViewerData];
}; -- end of Circle
EditMode: TYPE = Scratchpad2dUser.EditMode; -- {lin, revo};
Edit: PUBLIC PROC [path: Path, mode: EditMode, scratchViewerData: ScratchViewerData] = TRUSTED {
scratchpad: ViewerClasses.Viewer ← scratchViewerData.scratchpad;
scratchpadData: ScratchpadData ← NARROW[scratchpad.data];
scratchpadData.path ← path;
SELECT mode FROM
lin => {scratchpadData.mode ← drawLin;
DrawLin [scratchpad, scratchpadData.scratchViewerData, red, FALSE, FALSE];
};
revo => {scratchpadData.mode ← drawRevo;
DrawRevo [scratchpad, scratchpadData.scratchViewerData, red, FALSE, FALSE];
};
ENDCASE => ERROR;
}; -- end of Edit
END.