<> <> <> <> DIRECTORY CD, CDBasics, CDDirectory, CDIO, CDProperties, CDRepetitions, IO, Rope, TokenIO; CDRepetitionsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDDirectory, CDIO, CDProperties, IO, TokenIO EXPORTS CDRepetitions SHARES CDDirectory = BEGIN RepSpecific: TYPE = CDRepetitions.RepSpecific; pForRepetitions: CD.ObjectClass = CD.RegisterObjectClass[$Repetitions, [ drawMe: DrawMeForRepetitions, quickDrawMe: QuickDrawMeForRepetitions, internalRead: ReadRepetition, internalWrite: WriteRepetition, describe: Describe ]]; Describe: CD.DescribeProc = { rp: RepSpecific = NARROW[ob.specific]; r: Rope.ROPE _ IO.PutFR["repetition [%g]", [integer[rp.count]]]; RETURN [r] }; Adjust: PROC [repOb: CD.Object, rp: RepSpecific] = { or: CD.Rect _ CDBasics.MapRect[rp.ob.bbox, [[0,0], rp.orientation]]; ir: CD.Rect _ CDBasics.MapRect[CD.InterestRect[rp.ob], [[0,0], rp.orientation]]; totalOffset: CD.Position _ [(rp.count-1)*rp.offset.x, (rp.count-1)*rp.offset.y]; repOb.bbox _ CDBasics.Surround[or, CDBasics.MoveRect[or, totalOffset]]; rp.ir _ CDBasics.Surround[ir, CDBasics.MoveRect[ir, totalOffset]]; }; CreateRepetition: PUBLIC PROC [design: CD.Design, ob: CD.Object, count: NAT, offset: CD.Position, orientation: CD.Orientation] RETURNS [CD.Object] = { rp: RepSpecific = NEW[CDRepetitions.RepRec_[ ob: ob, ir: [0, 0, 0, 0], orientation: orientation, offset: offset, count: MAX[1, MIN[count, 512]] ]]; repOb: CD.Object = NEW[CD.ObjectRep_[ class: pForRepetitions, specific: rp ]]; Adjust[repOb, rp]; IF design#NIL THEN CDDirectory.SetOwner[design, repOb]; RETURN [repOb]; }; DrawMeForRepetitions: CD.DrawProc = { rptr: RepSpecific _ NARROW[ob.specific]; t1: CD.Transformation _ CDBasics.ComposeTransform[[[0,0], rptr.orientation], trans]; off: CD.Position _ CDBasics.MapPoint[rptr.offset, [[0,0], trans.orient]]; FOR i: INT IN [0..rptr.count) DO IF pr.stopFlag^ THEN EXIT; pr.drawChild[pr, rptr.ob, t1]; t1.off _ CDBasics.AddPoints[t1.off, off] ENDLOOP; }; QuickDrawMeForRepetitions: CD.DrawProc = { rptr: RepSpecific _ NARROW[ob.specific]; t1: CD.Transformation _ CDBasics.ComposeTransform[[[0,0], rptr.orientation], trans]; off: CD.Position _ CDBasics.MapPoint[rptr.offset, [[0,0], trans.orient]]; FOR i: INT IN [0..rptr.count) DO IF pr.stopFlag^ THEN EXIT; rptr.ob.class.quickDrawMe[pr, rptr.ob, t1]; t1.off _ CDBasics.AddPoints[t1.off, off] ENDLOOP; }; Another: PROC [me: CD.Object, fromOrNil: CD.Design_NIL, into: CD.Design_NIL, friendly: BOOL_FALSE] RETURNS [new: CD.Object_NIL, childAccessible: BOOL_FALSE] = { rp: RepSpecific = NARROW[me.specific]; new _ CreateRepetition[into, rp.ob, rp.count, rp.offset, rp.orientation]; CDProperties.AppendProps[winner: new.properties, looser: me.properties, putOnto: new]; childAccessible _ ~rp.ob.class.composed OR (fromOrNil#NIL AND fromOrNil=into) }; EnumerateChildren: PROC [me: CD.Object, proc: CDDirectory.EachObjectProc, data: REF] RETURNS [quit: BOOL] = { rptr: RepSpecific = NARROW[me.specific]; quit _ proc[rptr.ob, data]; }; ReadRepetition: CD.InternalReadProc = { ob: CD.Object = CDIO.ReadObject[h]; count: NAT = TokenIO.ReadInt[h]; offset: CD.Position = CDIO.ReadPos[h]; orientation: CD.Orientation = CDIO.ReadOrientation[h]; rep: CD.Object _ CreateRepetition[design: CDIO.DesignInReadOperation[h], ob: ob, count: count, offset: offset, orientation: orientation]; <> RETURN [rep]; }; WriteRepetition: CD.InternalWriteProc = { specific: RepSpecific = NARROW[ob.specific]; CDIO.WriteObject[h, specific.ob]; TokenIO.WriteInt[h, specific.count]; CDIO.WritePos[h, specific.offset]; CDIO.WriteOrientation[h, specific.orientation]; }; ReplaceDirectChildren: CDDirectory.ReplaceDChildsProc = { rp: CDRepetitions.RepSpecific = NARROW[me.specific]; bbox: CD.Rect _ me.bbox; ir: CD.Rect _ rp.ir; FOR replaceList: CDDirectory.ReplaceList _ replace, replaceList.rest WHILE replaceList#NIL DO rep: REF CDDirectory.ReplaceRec _ replaceList.first; IF rep.old=rp.ob THEN { trans: CD.Transformation _ CDBasics.ComposeTransform[ itemInCell: rep.trans, cellInWorld: [[0, 0], rp.orientation] ].itemInWorld; IF me.immutable THEN ERROR; rp.ob _ rep.new; rp.orientation _ trans.orient; Adjust[me, rp]; IF trans.off#[0, 0] THEN CDDirectory.ReplaceObject[design: design, old: me, new: me, trans: [trans.off, original]] ELSE IF me.bbox#bbox OR rp.ir#ir THEN CDDirectory.PropagateResize[design, me]; changed _ TRUE; EXIT; }; ENDLOOP; }; InitRepetitions: PROC [] = { rp: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[pForRepetitions, [ enumerateChildObjects: EnumerateChildren, replaceDirectChilds: ReplaceDirectChildren, another: Another ]]; }; InitRepetitions[]; END.