Commands
UserData: TYPE ~ RECORD [o: Controls.OuterData, p: ProgramData];
ProgramData: TYPE ~ REF ProgramDataRec;
ProgramDataRec:
TYPE ~
RECORD [
out: STREAM ← NIL, -- for any text output
outer: Viewer ← NIL, -- the outer (parent, top level) viewer
color: Color ← Imager.black, -- Imager color
alpha: Control ← NIL, -- interpolation alpha
scaler: Control ← NIL, -- contour scaler
hue: Control ← NIL, -- fill hue
fun: Control ← NIL, -- have some
contour: Control ← NIL, -- the contour control
contour0: Control ← NIL, -- first interpolant
contour1: Control ← NIL, -- second interpolant
save: Contour ← NIL, -- permit undo
scale: Contour ← NIL, -- avoid scale accumulation
scaling: BOOL ← FALSE,
normals: BOOL ← FALSE, -- show contour normals?
info: BOOL ← FALSE -- report contour information?
];
General Testing Program
ContoursTest: Commander.CommandProc ~ {
p: ProgramData ← NEW[ProgramDataRec ← [out: cmd.out]];
p.contour ← Controls.NewControl[
name: "Contour and Normals", type: contour, data: p, w: 180, flavor: $Normals];
p.scaler ← Controls.NewControl["Scale", vSlider, p, 0.0, 5.0, 1.0, Scale, , , , , , , 138];
p.hue ← Controls.NewControl["Hue", vSlider, p, 0.0, 1.0, 0.5, Hue, , , , , , , 138];
p.fun ← Controls.NewControl["Fun", vSlider, p, 0.0, 5.0, 1.0, Fun, , , , , , , 138];
p.outer ← Controls.OuterViewer[
name: "Contours Test",
column: right,
controls: LIST[p.contour, p.scaler, p.hue, p.fun],
buttons:
LIST[
["Info-Off", ToggleInfo, 0],
["Normals-Off", ToggleNormals, 0],
["Read", Read, 0],
["Write", Write, 0],
["UnDo", UnDo, 1],
["Clear", Clear, 1],
["Center", Center, 1],
["Thin", Thin, 1],
["Smooth", Smooth, 1],
["Close", Close, 1],
["Outline", Outline, 1],
["Fill", Fill, 1],
["FillPm", FillPm, 1]],
typeScriptHeight: 18,
data: p
];
};
Scale: Controls.ControlProc ~ {
IF control.mouse.state # up THEN ScaleContour[NARROW[control.data, ProgramData]];
};
Fun: Controls.ControlProc ~ {
p: ProgramData ← NARROW[control.data];
hue: REAL ← p.hue.value+0.02;
IF control.mouse.state = up THEN RETURN;
IF hue > p.hue.max THEN hue ← p.hue.min;
Controls.SetSliderDialValue[p.hue, hue];
Controls.SetSliderDialValue[p.scaler, p.fun.value];
ScaleContour[NARROW[control.data, ProgramData]];
p.color ← ImagerColor.ColorFromRGB[ImagerColor.RGBFromHSL[[p.hue.value, 1.0, 0.5]]];
FillContour[p];
};
ScaleContour:
PROC [p: ProgramData] ~ {
contour: Contour ← Contours.Copy[p.scale];
centroid: Pair ← Contours.Centroid[contour];
contour ← Contours.Offset[contour, Vector2.Neg[centroid]];
contour ← Contours.Scale[contour, p.scaler.value];
contour ← Contours.Offset[contour, centroid];
p.scaling ← TRUE;
Contours.ToControl[p.contour, contour];
};
FillContour:
PROC [p: ProgramData] ~ {
Contours.Fill[InitColorDisplayContext[], Contours.FromControl[p.contour], p.color];
};
Fill: Controls.ClickProc ~ {
FillContour[UserDataFromClientData[clientData].p];
};
FillPm: Controls.ClickProc ~ {
p: ProgramData ← UserDataFromClientData[clientData].p;
Contours.FillPm[ColorTrixBasics.GetColorDisplayPm[], Contours.FromControl[p.contour], 100];
};
Hue: Controls.ControlProc ~ {
p: ProgramData ← NARROW[control.data];
IF control.mouse.state = up THEN RETURN;
p.color ← ImagerColor.ColorFromRGB[ImagerColor.RGBFromHSL[[p.hue.value, 1.0, 0.5]]];
FillContour[p];
};
ToggleInfo: Controls.ClickProc ~ {
u: UserData ← UserDataFromClientData[clientData];
u.p.info ← NOT u.p.info;
Controls.ButtonToggle[u.o, u.p.info, "Info-On", "Info-Off"];
CheckPrintInfo[u.p];
};
CheckPrintInfo:
PROC [p: ProgramData] ~ {
IF p.info
THEN {
rope:
ROPE ←
IO.PutFR[
"%g pairs in %g contour\n",
IO.int[Controls.NPointsInContour[p.contour]],
IO.rope[IF Controls.IsContourClosed[p.contour] THEN "closed" ELSE "open"]];
Controls.TypeScriptWrite[NARROW[p.outer.data], rope];
};
};
ToggleNormals: Controls.ClickProc ~ {
u: UserData ← UserDataFromClientData[clientData];
Controls.ButtonToggle[u.o, u.p.normals ← NOT u.p.normals, "Normals-On", "Normals-Off"];
ViewerOps.PaintViewer[u.p.contour.viewer, client, FALSE, NIL];
};
PaintNormals: ViewerClasses.PaintProc ~ {
control: Control ← NARROW[self.data];
p: ProgramData ← NARROW[control.data];
IF control.mouse.state # up
THEN [] ← ControlsPrivate.PaintContour[self, context, whatChanged, clear]
ELSE {
contour: Contour ← Contours.FromControl[p.contour];
CheckPrintInfo[p];
IF p.normals THEN contour.normals ← Contours.Normals[contour];
Contours.Paint[contour, context, p.normals];
IF
NOT p.scaling
THEN {
p.scale ← contour;
Controls.SetSliderDialValue[p.scaler, 1.0];
};
p.scaling ← FALSE;
};
};
Read: Controls.ClickProc ~ {
u: UserData ← UserDataFromClientData[clientData];
name: ROPE ← Controls.TypeScriptReadFileName[u.o];
IF name #
NIL
THEN {
stream: STREAM ← FS.StreamOpen[name ! FS.Error => GOTO noOpen];
Contours.ToControl[u.p.contour, Contours.Read[stream]];
CheckPrintInfo[u.p];
EXITS
noOpen =>
Controls.TypeScriptWrite[u.o, IO.PutFR["Couldn't open %g\n", IO.rope[name]]];
};
};
Write: Controls.ClickProc ~ {
u: UserData ← UserDataFromClientData[clientData];
name: ROPE ← Controls.TypeScriptReadFileName[u.o];
IF name #
NIL
THEN
Contours.Write[FS.StreamOpen[name, $create], Contours.FromControl[u.p.contour]];
};
UnDo: Controls.ClickProc ~ {
p: ProgramData ← UserDataFromClientData[clientData].p;
Contours.ToControl[p.contour, p.scale ← p.save];
CheckPrintInfo[p];
};
Clear: Controls.ClickProc ~ {
u: UserData ← UserDataFromClientData[clientData];
Controls.Reset[u.p.contour];
};
Center: Controls.ClickProc ~ {
p: ProgramData ← UserDataFromClientData[clientData].p;
contour: Contour ← Contours.FromControl[p.contour];
p.save ← p.scale ← Contours.Copy[contour];
Contours.ToControl[p.contour, Contours.Center[contour]];
};
Thin: Controls.ClickProc ~ {
p: ProgramData ← UserDataFromClientData[clientData].p;
p.scale ← Contours.Thin[p.save ← Contours.FromControl[p.contour]];
Contours.ToControl[p.contour, p.scale];
CheckPrintInfo[p];
};
Smooth: Controls.ClickProc ~ {
p: ProgramData ← UserDataFromClientData[clientData].p;
p.scale ← Contours.Smooth[p.save ← Contours.FromControl[p.contour]];
Contours.ToControl[p.contour, p.scale];
CheckPrintInfo[p];
};
Close: Controls.ClickProc ~ {
Controls.CloseContour[UserDataFromClientData[clientData].p.contour];
};
InitColorDisplayContext:
PROC
RETURNS [Context] ~ {
RETURN[ColorTrixBasics.InitCd[color, , , FALSE]];
};
Outline: Controls.ClickProc ~ {
p: ProgramData ← UserDataFromClientData[clientData].p;
Contours.Outline[InitColorDisplayContext[], Contours.FromControl[p.contour], p.color];
};
Miscellany
UserDataFromClientData:
PROC [clientData:
REF
ANY]
RETURNS [u: UserData] ~ {
u.p ← NARROW[(u.o ← NARROW[clientData]).data];
};
testUsage: ROPE ← "\nDraw a contour.";
interpolateUsage: ROPE ← "\nDraw two contours and interpolate between them.";
ViewerOps.RegisterViewerClass[$Normals,
NEW[ViewerClasses.ViewerClassRec ← [
notify: Controls.NotifyControl,
paint: PaintNormals,
tipTable: TIPUser.InstantiateNewTIPTable["Controls.TIP"]]]];
Commander.Register["///Commands/ContoursTest", ContoursTest, testUsage];
Commander.Register["///Commands/ContoursInterpolate", ContoursInterpolate, interpolateUsage];