<<>> <> <> <> 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