DIRECTORY Commander, Controls, Draw2d, G2dBasic, G2dImplicitTool, G2dTool, G2dVector, Rope; G2dImplicitCmdsImpl: CEDAR PROGRAM IMPORTS Controls, Draw2d, G2dImplicitTool, G2dTool, G2dVector ~ BEGIN CommandProc: TYPE ~ Commander.CommandProc; Tool: TYPE ~ G2dImplicitTool.Tool; Pair: TYPE ~ G2dBasic.Pair; ROPE: TYPE ~ Rope.ROPE; SimpleType: TYPE ~ {circle, blob}; SimpleData: TYPE ~ REF SimpleDataRep; SimpleDataRep: TYPE ~ RECORD [ tool: Tool ฌ NIL, radius: Controls.Control ฌ NIL, radiusSquared: REAL ฌ 1.0, blobSep: REAL ฌ 0.25, type: SimpleType ฌ circle ]; SimpleCommand: CommandProc ~ { s: SimpleData ~ NEW[SimpleDataRep]; s.tool ฌ G2dImplicitTool.MakeTool[ name: "Simple", valueProc: Value, clientDraw: Draw, clientData: s, extraControls: LIST[s.radius ฌ Controls.NewControl["Radius",, s, 0, 5, 1, Radius]], extraButtons: LIST[ Controls.ClickButton["Circle", TypeCycle, s], Controls.ClickButton["Blob Sep", BlobSep, s]] ]; }; Value: G2dImplicitTool.ValueProc ~ { s: SimpleData ฌ NARROW[clientData]; SELECT s.type FROM circle => value ฌ point.x*point.x+point.y*point.y-s.radiusSquared; blob => { centers: ARRAY [0..1] OF Pair ฌ [[-s.blobSep, 0.0], [s.blobSep, 0.0]]; FOR n: NAT IN [0..1] DO value ฌ value+1.0/MAX[.001, G2dVector.SquareDistance[centers[n], point]]; ENDLOOP; }; ENDCASE; }; Radius: Controls.ControlProc ~ { s: SimpleData ฌ NARROW[clientData]; s.radiusSquared ฌ s.radius.value*s.radius.value; G2dImplicitTool.Repaint[s.tool, $Client]; }; Draw: Draw2d.DrawProc ~ { s: SimpleData ฌ NARROW[clientData]; SELECT s.type FROM circle => Draw2d.Circle[context, [0, 0], s.radius.value]; ENDCASE; }; BlobSep: Controls.ClickProc ~ { d: SimpleData ~ NARROW[clientData]; d.blobSep ฌ Controls.GetReal[d.tool.typescript, "Blob Separation", d.blobSep]; }; TypeCycle: Controls.ClickProc ~ { Roper: PROC [type: SimpleType] RETURNS [ROPE] ~ { RETURN[SELECT type FROM circle => "Circle", blob => "Blob", ENDCASE => NIL]; }; d: SimpleData ~ NARROW[clientData]; old: SimpleType ~ d.type; d.type ฌ IF old = SimpleType.LAST THEN SimpleType.FIRST ELSE SUCC[old]; Controls.ButtonRelabel[d.tool.outerData, Roper[old], Roper[d.type]]; IF mouseButton = blue THEN G2dImplicitTool.Repaint[d.tool, $Client]; }; G2dTool.Register["ImplicitFunction", SimpleCommand, "ImplicitFunction