<> <> <> <> DIRECTORY CheckMarks, TilerMenu USING [Register], TokenIO USING [ReadInt, WriteInt], TerminalIO USING [WriteRope], CDSequencer USING [Command, ImplementCommand], CD, CDInline USING [AddPoints], CDOps USING [AddAnObject], Rope USING [ROPE]; CheckMarksImpl: CEDAR PROGRAM IMPORTS TilerMenu, CD, TerminalIO, TokenIO, CDOps, CDInline, CDSequencer EXPORTS CheckMarks = BEGIN OPEN CheckMarks; markRadius: INT = 2; versionNumber: INT ~ 1; -- version number of our file format atom: PUBLIC ATOM _ $CheckMark; myLevel: CD.Level; objsProcs: REF CD.ObjectProcs; <<-- Utilities>> <<>> <<-- find the origin of a mark application relative to the containing cell's origin>> Find: PUBLIC PROC [aptr: CD.ApplicationPtr] RETURNS [CD.Position] = BEGIN RETURN[CDInline.AddPoints[aptr.location, [markRadius, markRadius]]]; END; <<>> <<>> <<-- routines for interactive editing of marks>> <<>> <<-- add a mark to a Design or Cell at absolute coordinates>> Place: PUBLIC PROC [into: CD.Design, markPos: CD.Position] = BEGIN obj: CD.ObPtr _ NEW[CD.ObjectDefinition]; obj.p _ objsProcs; obj.size _ [markRadius * 2, markRadius * 2]; obj.specificRef _ NIL; obj.level _ myLevel; CDOps.AddAnObject[design: into, ob: obj, location: markPos]; END; DrawCheckMark: CD.DrawProc = BEGIN <<-- PROC [aptr: ApplicationPtr, pos: DesignPosition, orient: Orientation, pr: REF DrawInformation];>> <<-- draw the mark>> <> pr.drawRect[ [pos.x, pos.y, pos.x + markRadius, pos.y + markRadius], aptr.ob.level, pr]; pr.drawRect[ [pos.x + markRadius, pos.y + markRadius, pos.x + 2 * markRadius, pos.y + 2 * markRadius], aptr.ob.level, pr]; END; AddCheckMark: PROC [comm: CDSequencer.Command] = BEGIN Place[comm.design, comm.pos]; END; WriteMark: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN TokenIO.WriteInt[versionNumber]; END; ReadMark: CD.InternalReadProc -- PROC [] RETURNS [ObPtr] -- = BEGIN version: INT; obj: CD.ObPtr _ NEW[CD.ObjectDefinition]; obj.p _ objsProcs; obj.size _ [markRadius * 2, markRadius * 2]; obj.specificRef _ NIL; obj.level _ myLevel; version _ TokenIO.ReadInt[]; SELECT version FROM 1 => NULL; ENDCASE => TerminalIO.WriteRope["File contained an unknown version of Alignment Marks\n"]; RETURN[obj]; END; DescribeMark: CD.DescribeProc -- PROC [me: ObPtr] RETURNS [Rope.ROPE] -- = BEGIN RETURN["tiler check mark"]; END; <<>> <<-- Top-level command routines>> <<>> Init: PROC[] = BEGIN error: BOOL _ FALSE; tmp: REF CD.ObjectProcs _ NIL; tmp _ CD.RegisterObjectType[atom ! CD.Error => error _ TRUE]; IF tmp = NIL THEN error _ TRUE; IF ~error THEN { myLevel _ CD.NewLevel[NIL, $CheckMarkLevel]; objsProcs _ tmp; } ELSE { error _ FALSE; objsProcs _ CD.FetchObjectProcs[atom! CD.Error => {error _ TRUE; CONTINUE}]; myLevel _ CD.FetchLevel[NIL, $CheckMarkLevel ! CD.Error => {error _ TRUE; CONTINUE}]; IF error THEN objsProcs _ NIL; }; IF objsProcs = NIL THEN { TerminalIO.WriteRope["Error: Can't register check-mark object procs.\n"]; RETURN; }; objsProcs.drawMe _ DrawCheckMark; objsProcs.internalWrite _ WriteMark; objsProcs.internalRead _ ReadMark; objsProcs.describe _ DescribeMark; objsProcs.hasChildren _ FALSE; objsProcs.wireTyped _ FALSE; CDSequencer.ImplementCommand[$AddCheckMark, AddCheckMark]; TilerMenu.Register["Add Check Mark", $AddCheckMark]; END; <<-- Main body>> <<>> Init[]; END.