ShowSweepImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Greene, October 3, 1986 6:38:53 pm PDT
DIRECTORY
Commander USING [CommandProc, Register],
Containers USING [Container, Create],
Imager USING [Context, Color, ScaleT, MaskStrokeTrajectory, SetColor, black, SetStrokeWidth, SetStrokeEnd, SetStrokeJoint],
ImagerColor USING [ColorFromRGB],
ImagerPath USING[LineTo, MoveTo],
Menus USING[CreateMenu, AppendMenuEntry, CreateEntry, Menu, ClickProc],
Process USING [Pause, SecondsToTicks],
Random USING [ChooseInt],
Real USING [Float, Round],
Rope USING [ROPE],
Sweep,
TIPUser USING [TIPScreenCoords, InstantiateNewTIPTable],
Vector2 USING [VEC],
ViewerClasses USING [ViewerClass, ViewerClassRec, Viewer, PaintProc, NotifyProc],
ViewerOps USING [CreateViewer, RegisterViewerClass, PaintViewer];
ShowSweepImpl: CEDAR MONITOR
LOCKS my USING my: State
IMPORTS Containers, Commander, Imager, ImagerPath, ImagerColor, Menus, Process, Random, Real, Sweep, TIPUser, ViewerOps =
BEGIN
darkBlue: Imager.Color = ImagerColor.ColorFromRGB[[0.0, 0.0, 1.0]];
lightRed: Imager.Color = ImagerColor.ColorFromRGB[[1.0, 0.0, 0.0]];
TestSize: INT ← 6;
Scale: INT ← 1; --Dots per inch
Time: CARDINAL ← 0;
State: TYPE = REF StateRec;
StateRec: TYPE = MONITORED RECORD [
outer: Containers.Container ← NIL,
menu: Menus.Menu,
inner: ViewerClasses.Viewer,
mouse: TIPUser.TIPScreenCoords,
stop: BOOLEAN ← FALSE,
input: Sweep.Graph ← Sweep.NewGraph[],
output: Sweep.Graph];
Change: TYPE = REF ChangeRec;
ChangeRec: TYPE = RECORD[doc: Rope.ROPE];
allFlag: Change = NIL;
lastLine: Change = NEW[ChangeRec ← ["Paint Last Line"]];
ShowSweep: Commander.CommandProc = {
my: State ← NEW[StateRec];
my.menu ← Menus.CreateMenu[];
my.menu.AppendMenuEntry[Menus.CreateEntry["Clear", ClearProc, my]];
my.menu.AppendMenuEntry[Menus.CreateEntry["ReDraw", ReDrawProc, my]];
my.menu.AppendMenuEntry[Menus.CreateEntry["Intersect", IntersectProc, my]];
my.menu.AppendMenuEntry[Menus.CreateEntry["Straighten", StraightenProc, my]];
my.menu.AppendMenuEntry[Menus.CreateEntry["Verify", VerifyProc, my]];
my.menu.AppendMenuEntry[Menus.CreateEntry["RandomTest", RandomTestProc, my]];
my.menu.AppendMenuEntry[Menus.CreateEntry["Stop", StopProc, my]];
my.outer ← Containers.Create[[
name: "Sweep",
menu: my.menu,
scrollable: FALSE]];
my.inner ← ViewerOps.CreateViewer[
flavor: $ShowSweep,
info: [wx: 10, wy: 10, wh: 400, ww: 600, parent: my.outer, data: my]];
ViewerOps.PaintViewer[viewer: my.inner, hint: all];
};
ClearProc: Menus.ClickProc = {
my: State ← NARROW[clientData];
ClearLocked[my];
ViewerOps.PaintViewer[viewer: my.inner, hint: all];
};
ClearLocked: ENTRY PROC[my: State] ~ {
ENABLE UNWIND => NULL;
Sweep.DestroyGraph[my.input]; my.input ← Sweep.NewGraph[];
Sweep.DestroyGraph[my.output]; my.output ← NIL;
};
ReDrawProc: Menus.ClickProc = {
my: State ← NARROW[clientData];
ViewerOps.PaintViewer[viewer: my.inner, hint: all, whatChanged: allFlag];
};
IntersectProc: Menus.ClickProc = {
my: State ← NARROW[clientData];
IntersectLocked[my];
ViewerOps.PaintViewer[viewer: my.inner, hint: all, whatChanged: allFlag];
};
IntersectLocked: ENTRY PROC[my: State] ~ {
ENABLE UNWIND => NULL;
[my.output] ← Sweep.Intersect[Sweep.CopyGraph[my.input]];
};
VerifyProc: Menus.ClickProc = {
my: State ← NARROW[clientData];
VerifyLocked[my];
};
VerifyLocked: ENTRY PROC[my: State] ~ {
ENABLE UNWIND => NULL;
Sweep.Verify[my.output];
};
RandomTestProc: Menus.ClickProc = {
my: State ← NARROW[clientData];
my.stop ← FALSE;
DO
IF my.stop THEN EXIT;
ClearLocked[my];
RandomLinesLocked[my];
ViewerOps.PaintViewer[viewer: my.inner, hint: all, whatChanged: allFlag];
IF my.stop THEN EXIT;
IntersectLocked[my];
ViewerOps.PaintViewer[viewer: my.inner, hint: all, whatChanged: allFlag];
Process.Pause[Process.SecondsToTicks[Time]];
IF my.stop THEN EXIT;
VerifyLocked[my];
StraightenLocked[my];
ViewerOps.PaintViewer[viewer: my.inner, hint: all, whatChanged: allFlag];
Process.Pause[Process.SecondsToTicks[Time]];
IF my.stop THEN EXIT;
VerifyLocked[my];
ENDLOOP;
};
StopProc: Menus.ClickProc = {
my: State ← NARROW[clientData];
my.stop ← TRUE;
};
RandomLinesLocked: ENTRY PROC[my: State] ~ {
ENABLE UNWIND => NULL;
FOR i:
INT
IN [1..TestSize]
DO
my.input ← Sweep.NewPoint[my.input, Random.ChooseInt[min: 1, max: 14*Scale], Random.ChooseInt[min: 1, max: 9*Scale]];
my.input ← Sweep.LineTo[my.input, Random.ChooseInt[min: 1, max: 14*Scale], Random.ChooseInt[min: 1, max: 9*Scale]];
ENDLOOP;
};
StraightenProc: Menus.ClickProc = {
my: State ← NARROW[clientData];
StraightenLocked[my];
ViewerOps.PaintViewer[viewer: my.inner, hint: all, whatChanged: allFlag];
};
StraightenLocked: ENTRY PROC[my: State] ~ {
ENABLE UNWIND => NULL;
[my.output] ← Sweep.StraightenLines[my.output];
};
ShowSweepPaint: ViewerClasses.PaintProc = {
my:State ← NARROW[self.data];
context.ScaleT[40.0/Scale];
context.SetStrokeEnd[round];
context.SetStrokeJoint[round];
PaintLocked[my, context, whatChanged];
};
PaintLocked: ENTRY PROC [my: State, context: Imager.Context, whatChanged: REF ANY] ~ {
OPEN Imager, ImagerPath;
ENABLE UNWIND => NULL;
PaintLines: PROC [in: Sweep.Graph, pointSize, lineSize: REAL] = {
PerLine:
PROC [l: Sweep.Line]
RETURNS [
BOOL] ~ {
IndividualLine[l, pointSize, lineSize]; RETURN[FALSE];
};
IF in = NIL THEN RETURN;
[] ← Sweep.EnumerateLines[in, PerLine];
};
IndividualLine:
PROC [l: Sweep.Line, pointSize, lineSize:
REAL] ~ {
context.SetStrokeWidth[pointSize];
context.MaskStrokeTrajectory[MoveTo[Vfi[l.above.x, l.above.y]].LineTo[Vfi[l.above.x, l.above.y]]];
context.MaskStrokeTrajectory[MoveTo[Vfi[l.below.x, l.below.y]].LineTo[Vfi[l.below.x, l.below.y]]];
context.SetStrokeWidth[lineSize];
context.MaskStrokeTrajectory[MoveTo[Vfi[l.below.x, l.below.y]].LineTo[Vfi[l.above.x, l.above.y]]];
};
IF whatChanged = allFlag
THEN {
context.SetColor[lightRed];
PaintLines[my.input, .2*Scale, .1*Scale];
context.SetColor[darkBlue];
PaintLines[my.output, .11*Scale, .04*Scale];
context.SetStrokeWidth[.05*Scale];
context.SetColor[black];
FOR i:
INT
IN [1..15]
DO
FOR j:
INT
IN [1..10]
DO
context.MaskStrokeTrajectory[MoveTo[Vfi[i*Scale,j*Scale]].LineTo[Vfi[i*Scale,j*Scale]]];
ENDLOOP;
ENDLOOP;
}
ELSE
{IF whatChanged # lastLine THEN ERROR;
context.SetColor[lightRed];
IndividualLine[Sweep.LastLine[my.input], .2*Scale, .1*Scale];
};
};
Vfi:
PROC [i, j:
INT]
RETURNS [Vector2.
VEC] ~ {
RETURN[[Real.Float[i], Real.Float[j]]];
};
PaintRequest: TYPE = {none, all, lastLine};
LineComing: ViewerClasses.NotifyProc ~ {
my: State ←NARROW[self.data];
paint: PaintRequest ← LineComingLocked[my, input];
IF paint = all THEN ViewerOps.PaintViewer[viewer: my.inner, hint: all, whatChanged: allFlag]
ELSE IF paint = lastLine THEN ViewerOps.PaintViewer[viewer: my.inner, hint: all, clearClient: FALSE, whatChanged: lastLine];
};
LineComingLocked: ENTRY PROC[my: State, input: LIST OF REF ANY] RETURNS [paint: PaintRequest ← none] ~ {
ENABLE UNWIND => NULL;
FOR list:
LIST
OF
REF
ANY ← input, list.rest
UNTIL list =
NIL
DO
WITH list.first
SELECT
FROM
a:
ATOM =>
SELECT a
FROM
$Head => {my.input ← Sweep.NewPoint[my.input, IS[my.mouse.mouseX], IS[my.mouse.mouseY]]};
$Delete => {
Not implemented
};
$Tail => {
my.input ← Sweep.LineTo[my.input, IS[my.mouse.mouseX], IS[my.mouse.mouseY]];
paint ← IF paint = none THEN lastLine ELSE all;
};
ENDCASE => NULL;
z: TIPUser.TIPScreenCoords => my.mouse ← z;
ENDCASE => ERROR;
ENDLOOP;
};
IS:
PROC [i:
INT]
RETURNS [o:
INT] ~
INLINE {
RETURN[Real.Round[i*Scale/40.0]];
};
displayerClass: ViewerClasses.ViewerClass ← NEW[ViewerClasses.ViewerClassRec ←
[paint: ShowSweepPaint, notify: LineComing, tipTable: TIPUser.InstantiateNewTIPTable["ShowSweep.tip"]]];
ViewerOps.RegisterViewerClass[$ShowSweep, displayerClass];
Commander.Register[key: "ShowSweep", proc: ShowSweep, doc: "To Debug Sweep"];
END.