<> <> <> <> <> DIRECTORY CheckMarks, TokenIO USING [ReadInt, WriteInt], TerminalIO USING [WriteRope], CDSequencer USING [Command, ImplementCommand], CD, CDBasics USING [AddPoints], CDApplications USING [NewApplicationI], CDMenus USING [CreateEntry], CDOps USING [IncludeApplication], Rope USING [ROPE]; CheckMarksImpl: CEDAR PROGRAM IMPORTS CDMenus, CD, TerminalIO, TokenIO, CDOps, CDApplications, CDBasics, CDSequencer EXPORTS CheckMarks = BEGIN OPEN CheckMarks; markRadius: INT = 2; versionNumber: INT ~ 1; -- version number of our file format objAtom: 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>> AptrToCheck: PUBLIC PROC [aptr: CD.ApplicationPtr] RETURNS [REF CD.Position] = BEGIN IF aptr.ob.p.objectType # objAtom THEN RETURN[NIL]; RETURN[NEW[CD.Position _ CDBasics.AddPoints[aptr.location, [markRadius, markRadius]]] ]; END; <<>> <<-- make a mark>> MakeCheckAptr: PUBLIC PROC [markPos: CD.Position] RETURNS [CD.ApplicationPtr] = BEGIN obj: CD.ObPtr _ NEW[CD.ObjectDefinition]; obj.p _ objsProcs; obj.size _ [markRadius * 2, markRadius * 2]; obj.specificRef _ NIL; obj.level _ myLevel; RETURN[CDApplications.NewApplicationI[obj, markPos]]; END; <<-- add a mark to a Design at absolute coordinates>> Place: PUBLIC PROC [into: CD.Design, markPos: CD.Position] = BEGIN CDOps.IncludeApplication[into, MakeCheckAptr[markPos]]; END; <<-- Find all check marks in a cell.>> FindList: PUBLIC PROC [ob: CD.ObPtr] RETURNS [LIST OF CD.Position] = BEGIN list: CD.ApplicationList; checks: LIST OF CD.Position _ NIL; SELECT ob.p.objectType FROM $Cell => list _ NARROW[ob.specificRef, CD.CellPtr].contents; ENDCASE => RETURN[NIL]; FOR a: CD.ApplicationList _ list, a.rest WHILE a # NIL DO IF a.first.ob.p.objectType = objAtom THEN { checks _ CONS[AptrToCheck[a.first]^, checks]; }; ENDLOOP; RETURN[checks]; END; <<>> <<>> <<-- routines for interactive editing of marks>> <<>> 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[objAtom ! 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[objAtom! 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.inDirectory _ FALSE; objsProcs.wireTyped _ FALSE; CDSequencer.ImplementCommand[$AddCheckMark, AddCheckMark]; CDMenus.CreateEntry[menu: $ModuleMenu, entry: "Add Check Mark", key: $AddCheckMark]; END; <<-- Main body>> <<>> Init[]; END.