DIRECTORY CD, CDInstances, CDCells, CDDirectory, CDMenus, CDEvents, CDBasics, CDInterestRects, CDIO, CDIOExtras, CDMarks, CDOps, CDOrient, CDProperties, CDRects, Process USING [Yield], Rope, TokenIO, TerminalIO; CDCellsImpl: CEDAR PROGRAM IMPORTS CD, CDInstances, CDIO, CDIOExtras, CDDirectory, CDEvents, CDBasics, CDMarks, CDMenus, CDOps, CDOrient, CDProperties, CDRects, Process, Rope, TokenIO, TerminalIO, CDInterestRects EXPORTS CDCells SHARES CD, CDRects, CDDirectory = BEGIN -- -- -- -- -- -- -- -- -- -- -- -- cellClass: PUBLIC REF CD.ObjectClass = CD.RegisterObjectClass[$Cell]; beforeReplace: CDEvents.EventRegistration = CDEvents.RegisterEventType[$BeforeCellReplacement]; afterReplace: CDEvents.EventRegistration = CDEvents.RegisterEventType[$AfterCellReplacement]; pushEvent: CDEvents.EventRegistration = CDEvents.RegisterEventType[$AfterPush]; popEvent: CDEvents.EventRegistration = CDEvents.RegisterEventType[$AfterPop]; createEvent: CDEvents.EventRegistration = CDEvents.RegisterEventType[$InteractiveCreatedCell]; fullPopMenu: REF = CDMenus.CreateMenu["Pop from cell"]; partialPopMenu: REF = CDMenus.CreateMenu["Pop from cell"]; emptyPopMenu: REF = CDMenus.CreateMenu["Pop from cell: empty cell"]; lastOutputDesign: CD.Design _ NIL; Init: PROC [] = BEGIN dp: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[cellClass]; dp.enumerateChildObjects _ EnumerateChildObjects; dp.name _ Name; dp.setName _ SetName; dp.another _ Another; dp.replaceDirectChilds _ ReplaceDirectChildForCells; cellClass.drawMe _ DrawMeForCells; cellClass.quickDrawMe _ QuickDrawMeForCells; cellClass.showMeSelected _ DrawCellSelection; cellClass.internalRead _ ReadCell; cellClass.internalWrite _ WriteCell; cellClass.describe _ Describe; cellClass.interestRect _ InterestRectCells; cellClass.oldInsideRect _ OldInsideRect; cellClass.origin _ OriginForCells; CDInterestRects.InstallOldSetInterest[cellClass, OldSetInterest]; CDMenus.CreateEntry[fullPopMenu, "flush", $flush]; CDMenus.CreateEntry[partialPopMenu, "flush", $flush]; CDMenus.CreateEntry[emptyPopMenu, "flush", $flush]; CDMenus.CreateEntry[fullPopMenu, "new cell", $new]; CDMenus.CreateEntry[partialPopMenu, "new cell", $new]; CDMenus.CreateEntry[fullPopMenu, "replace", $replace]; [] _ CDProperties.RegisterProperty[$InsideRect]; CDProperties.InstallProcs[prop: $InsideRect, new: CDProperties.PropertyProcsRec[ makeCopy: CDProperties.DontCopy, internalWrite: NIL, internalRead: InternalReadProperty, exclusive: TRUE ] ]; CDEvents.RegisterEventProc[$WriteTechnologyPrivate, RememberDesignOnWriting]; END; InternalReadProperty: PROC [prop: ATOM] RETURNS [val: REF] = BEGIN val _ NEW[CD.Rect _ CDIOExtras.ReadRect[]] END; InterestRectCells: PROC [ob: CD.Object] RETURNS [CD.Rect] = BEGIN RETURN [NARROW[ob.specificRef, CD.CellPtr].ir] END; OriginForCells: PROC [ob: CD.Object] RETURNS [CD.Position] = BEGIN RETURN [NARROW[ob.specificRef, CD.CellPtr].origin] END; OldInsideRect: PROC [ob: CD.Object] RETURNS [CD.Rect] = BEGIN RETURN [NARROW[ob.specificRef, CD.CellPtr].dIr] END; OldSetInterest: PROC [ob: CD.Object, r: CD.Rect] = BEGIN cptr: CD.CellPtr = NARROW[ob.specificRef]; cptr.ir _ r; cptr.useDIr _ FALSE; END; SetName: PROC [me: CD.Object, r: Rope.ROPE] = BEGIN NARROW[me.specificRef, CD.CellPtr].name _ r END; Name: PROC [me: CD.Object] RETURNS [Rope.ROPE] = BEGIN RETURN [NARROW[me.specificRef, CD.CellPtr].name] END; EnumerateChildObjects: PROC [me: CD.Object, p: CDDirectory.EnumerateObjectsProc, x: REF] = BEGIN cptr: CD.CellPtr = NARROW[me.specificRef]; FOR list: CD.InstanceList _ cptr.contents, list.rest WHILE list#NIL DO p[list.first.ob, x] ENDLOOP END; Another: PROC [me: CD.Object, from, to: CD.Design] RETURNS [CD.Object] = BEGIN oldCp: CD.CellPtr = NARROW[me.specificRef]; newOb: CD.Object = CreateEmptyCell[]; newCp: CD.CellPtr = NARROW[newOb.specificRef]; newOb.size _ me.size; newCp^ _ oldCp^; newCp.contents _ CDInstances.CopyList[oldCp.contents]; CDProperties.AppendProps[winner: newOb.properties, looser: me.properties, putOnto: newOb]; IF to#NIL THEN [] _ CDDirectory.Include[to, newOb]; RETURN [newOb] END; DrawMeForCells: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN IF ~pr.b4 THEN WITH CDProperties.GetPropFromList[pr.properties^, $border] SELECT FROM ro: REF CD.DrawOutLineProc => IF CDProperties.GetPropFromObject[inst.ob, $border]#NIL THEN ro[ CDOrient.MapRect[ itemInCell: CD.InterestRect[inst.ob], cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos ], pr]; ENDCASE => NULL; FOR w: CD.InstanceList _ NARROW[inst.ob.specificRef, CD.CellPtr].contents, w.rest WHILE w#NIL DO r: CD.Rect _ CDOrient.MapRect[ itemInCell: CDOrient.RectAt[w.first.location, w.first.ob.size, w.first.orientation], cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos ]; IF CDBasics.Intersect[r, pr.interestClip] THEN { IF pr.stopFlag^ THEN EXIT; pr.drawChild[ w.first, CDBasics.BaseOfRect[r], CDOrient.ComposeOrient[w.first.orientation, orient], pr]; } ENDLOOP; Process.Yield[]; END; QuickDrawMeForCells: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN cptr: CD.CellPtr = NARROW[inst.ob.specificRef]; r: REAL; IF (r _ pr.scaleHint*inst.ob.size.y)0 THEN { pr.drawOutLine[CDOrient.RectAt[pos, inst.ob.size, orient], pr]; IF r>9 THEN pr.drawComment[CDOrient.RectAt[pos, inst.ob.size, orient], cptr.name, pr]; } ELSE { mapClip: CD.Rect _ CDOrient.DeMapRect[ --clipping boundary in cell coordinates itemInWorld: pr.interestClip, cellSize: inst.ob.size, cellInstPos: pos, cellInstOrient: orient ].itemInCell; IF ~pr.b4 THEN WITH CDProperties.GetPropFromList[pr.properties^, $border] SELECT FROM ro: REF CD.DrawOutLineProc => IF CDProperties.GetPropFromObject[inst.ob, $border]#NIL THEN ro[ CDOrient.MapRect[ itemInCell: CD.InterestRect[inst.ob], cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos ], pr]; ENDCASE => NULL; FOR w: CD.InstanceList _ cptr.contents, w.rest WHILE w#NIL DO IF CDBasics.Intersect[mapClip, CDOrient.RectAt[w.first.location, w.first.ob.size, w.first.orientation]] THEN { r: CD.Rect _ CDOrient.MapRect[ itemInCell: CDOrient.RectAt[w.first.location, w.first.ob.size, w.first.orientation], cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos ]; IF w.first.ob.class=CDRects.bareRectClass THEN pr.drawRect[r, w.first.ob.layer, pr] ELSE { IF pr.stopFlag^ THEN EXIT; w.first.ob.class.quickDrawMe[ w.first, CDBasics.BaseOfRect[r], CDOrient.ComposeOrient[w.first.orientation, orient], pr]; } } ENDLOOP; Process.Yield[]; IF pr.checkPriority THEN pr.priorityChecker[pr]; } END; DrawCellSelection: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN IF (pr.scaleHint*inst.ob.size.y)0 THEN pr.drawRect[CDOrient.RectAt[pos, inst.ob.size, orient], CD.highLightShade, pr] ELSE { pr.drawOutLine[ CDOrient.MapRect[ itemInCell: CD.InterestRect[inst.ob], cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos ], pr ] } END; RemoveSelectedFromWorld: PROC [design: CD.Design] RETURNS [CD.InstanceList] = BEGIN remove, keep: CD.InstanceList; [others: keep, selected: remove] _ CDInstances.SplitSelected[CDOps.InstList[design]]; CDOps.SetInstList[design, keep]; RETURN [remove] END; CreateEmptyCell: PUBLIC PROC [] RETURNS [ob: CD.Object] = BEGIN ob _ NEW[CD.ObjectRep_[ class: cellClass, size: [0, 0], specificRef: NEW[CD.CellRep_[simplifyOn: 50]] ]]; END; CreateCellObject: PROC [use: CD.InstanceList, orient: CD.Orientation_CDOrient.original] RETURNS [CD.Object] = BEGIN ob: CD.Object = CreateEmptyCell[]; cp: CD.CellPtr = NARROW[ob.specificRef]; gOutR: CD.Rect = CDInstances.BoundingRectO[use]; -- coordsys of use, non oriented ob.size _ CDOrient.OrientedSize[CDBasics.SizeOfRect[gOutR], orient]; cp.contents _ CDInstances.DeComposedCopy[use, CDBasics.BaseOfRect[gOutR], ob.size, orient]; cp.ir _ cp.dIr _ CDInstances.BoundingRectI[cp.contents]; RETURN [ob] END; IncludeAndNameCell: PROC [design: CD.Design, cell: CD.Object, interactive: BOOL_TRUE, allowAbort: BOOL_FALSE] RETURNS [done: BOOL] = BEGIN IF ~interactive THEN { [] _ CDDirectory.Include[design, cell]; RETURN [done_TRUE]; }; DO fiddle: BOOL _ FALSE; aborted: BOOL _ FALSE; name: Rope.ROPE; name _ TerminalIO.RequestRope["enter object name: " ! TerminalIO.UserAbort => {aborted _ TRUE; fiddle _ TRUE; CONTINUE} ]; IF aborted THEN { TerminalIO.WriteRope[" **name input aborted\n"]; IF allowAbort THEN RETURN [done_FALSE]; }; IF Rope.IsEmpty[name] THEN { fiddle _ TRUE; name _ "-no name"; }; IF Rope.Fetch[name, name.Length[]-1]='@ THEN { fiddle _ TRUE; name _ Rope.Substr[name, 0, name.Length[]-1]; }; IF CDDirectory.Include[design, cell, name, fiddle] THEN { TerminalIO.WriteRopes[CDDirectory.Name[cell], " included\n"]; RETURN [done_TRUE]; }; TerminalIO.WriteRopes[name, " does already exist\nnot accepted, please repeat\n"]; ENDLOOP; END; CreateCellSelected: PUBLIC PROC [design: CD.Design, name: Rope.ROPE_NIL] RETURNS [done: BOOL_FALSE, cellOb: CD.Object_NIL] = BEGIN sel: CD.InstanceList = RemoveSelectedFromWorld[design]; inst: CD.Instance = NEW[CD.InstanceRep]; b: CD.Rect = CDInstances.BoundingRectO[sel]; cptr: CD.CellPtr; inst.ob _ cellOb _ CreateCellObject[use: sel]; cptr _ NARROW[cellOb.specificRef]; cptr.name _ name; inst.location _ CDBasics.BaseOfRect[b]; inst.selected _ TRUE; IF NOT CDBasics.NonEmpty[b] THEN { TerminalIO.WriteRope["no empty cell\n"]; RETURN [done: FALSE, cellOb: NIL] }; IF name=NIL THEN { IF ~IncludeAndNameCell[design: design, cell: cellOb, allowAbort: TRUE, interactive: TRUE].done THEN { CDOps.IncludeInstanceList[design, sel, FALSE]; RETURN [done: FALSE, cellOb: NIL] }; } ELSE [] _ CDDirectory.Include[design, cellOb]; CDOps.IncludeInstance[design, inst, TRUE]; -- redraw removes seletion [] _ CDEvents.ProcessEvent[createEvent, design, cellOb]; RETURN [done: TRUE, cellOb: cellOb] END; IsCellInstance: PROC [inst: CD.Instance] RETURNS [yes: BOOL _ FALSE] = BEGIN SELECT TRUE FROM inst=NIL => TerminalIO.WriteRope[" no object\n"]; inst.ob=NIL OR inst.ob.specificRef=NIL => TerminalIO.WriteRope[" bad object\n"]; ISTYPE[inst.ob.specificRef, CD.CellPtr] => yes _ TRUE; ENDCASE => TerminalIO.WriteRopes[" object is not cell but ", CDOps.Info[inst.ob], "\n"]; END; CheckRecursionForPush: PROC [design: CD.Design, ob: CD.Object] RETURNS [yes: BOOL _ FALSE] = BEGIN FOR l: LIST OF CD.PushRec _ design.actual, l.rest WHILE l#NIL DO IF l.first.mightReplace#NIL AND l.first.mightReplace.ob=ob THEN RETURN [yes _ TRUE] ENDLOOP; END; PushInCellInstance: PUBLIC PROC [design: CD.Design, inst: CD.Instance] RETURNS [done: BOOL _ FALSE] = BEGIN IF IsCellInstance[inst] THEN { cptr: CD.CellPtr = NARROW[inst.ob.specificRef]; dummy: CD.Object = CreateEmptyCell[]; newCptr: CD.CellPtr = NARROW[dummy.specificRef]; dummyCellInst: CD.Instance; dummy.size _ CDBasics.highposition; IF CheckRecursionForPush[design, inst.ob] THEN { TerminalIO.WriteRopes[" recursive push into ", CDOps.Info[inst.ob], " not possible\n"]; RETURN [done _ FALSE]; }; newCptr^ _ cptr^; --copies interest rect .... newCptr.ir _ CDOrient.MapRect[ itemInCell: cptr.ir, cellSize: inst.ob.size, cellInstOrient: inst.orientation, cellInstPos: inst.location ]; newCptr.dIr _ CDOrient.MapRect[ itemInCell: cptr.dIr, cellSize: inst.ob.size, cellInstOrient: inst.orientation, cellInstPos: inst.location ]; newCptr.contents _ CDInstances.ComposedCopy[ il: newCptr.contents, cellPos: inst.location, cellSize: inst.ob.size, cellOrient: inst.orientation ]; dummyCellInst _ NEW[CD.InstanceRep_[ ob: dummy, selected: TRUE, properties: CDProperties.DangerousCopyProps[inst.properties] ]]; CDProperties.CopyProps[inst.ob.properties, dummy]; CDOps.RemoveInstance[design, inst]; design^.actual _ CONS[ CD.PushRec[dummyCell: dummyCellInst, specific: newCptr, mightReplace: inst], design^.actual ]; [] _ CDEvents.ProcessEvent[pushEvent, design]; RETURN [done _ TRUE]; } END; PopFromCell: PUBLIC PROC [design: CD.Design, m: CDCells.Method_interactive, name: Rope.ROPE_NIL] RETURNS [done: BOOL] = BEGIN done _ IPopFromCell[design, m, name]; IF done THEN [] _ CDEvents.ProcessEvent[popEvent, design]; END; IPopFromCell: PROC [design: CD.Design, m: CDCells.Method, name: Rope.ROPE] RETURNS [done: BOOL_FALSE] = BEGIN currentRect, originalRect: CD.Rect; --cd coords currentInst, originalInst: CD.Instance; currentCellOb, originalCellOb: CD.Object; currentCellPtr, originalCellPtr: CD.CellPtr; recursive: BOOL _ FALSE; CheckRecursionForPop: PROC [mark: CDMarks.MarkRange] = BEGIN CDMarks.MarkUnMarkedInclusiveChildren[design, currentCellOb, mark]; recursive _ (originalInst.ob.marked=mark); END; DoFlush: PROC [] = BEGIN b: BOOL _ design^.actual.first.indirectlyChanged; TerminalIO.WriteRope["flush\n"]; design^.actual _ design^.actual.rest; design^.actual.first.indirectlyChanged _ TRUE; IF b THEN design^.actual.first.indirectlyChanged _ TRUE; CDOps.IncludeInstance[design, originalInst, FALSE]; END; HackSetOwner: PROC [ob: CD.Object, design: CD.Design] = TRUSTED { DesignPtr: TYPE = LONG POINTER TO CD.DesignRec; x: REF DesignPtr _ NEW[DesignPtr_LOOPHOLE[design]]; CDProperties.PutPropOnObject[ob, $OwnerDesign, x]; }; DoReplace: PROC [] = BEGIN needsRep: BOOL _ FALSE; [] _ CDEvents.ProcessEvent[beforeReplace, design, originalInst.ob]; TerminalIO.WriteRope["replace\n"]; HackSetOwner[currentCellOb, design]; design^.actual _ design^.actual.rest; design^.actual.first.indirectlyChanged _ TRUE; needsRep _ originalRect#currentRect OR originalCellPtr.ir#currentCellPtr.ir OR currentCellPtr.dIr#originalCellPtr.dIr OR originalCellPtr.useDIr#currentCellPtr.useDIr; originalCellPtr.contents _ currentCellPtr.contents; originalCellPtr.useDIr _ currentCellPtr.useDIr; originalCellPtr.ir _ currentCellPtr.ir; IF needsRep THEN { oldSize: CD.Position _ originalInst.ob.size; newFakeOrigin: CD.Position; --absolute coordinates newInOldCoordinates: CD.Position; --coordinates of old cell originalInst.ob.size _ CDOrient.OrientedSize[CDBasics.SizeOfRect[currentRect], originalInst.orientation]; newFakeOrigin _ CDOrient.MapPoint[ pointInCell: [0, 0], cellSize: originalInst.ob.size, cellInstOrient: originalInst.orientation, cellInstPos: currentInst.location ].pointInWorld; newInOldCoordinates _ CDOrient.DeMapPoint[ pointInWorld: newFakeOrigin, cellSize: oldSize, cellInstOrient: originalInst.orientation, cellInstPos: originalInst.location ].pointInCell; originalCellPtr.origin _ CDBasics.SubPoints[originalCellPtr.origin, newInOldCoordinates]; IF ~originalCellPtr.useDIr THEN originalCellPtr.ir _ CDBasics.MoveRect[originalCellPtr.ir, CDBasics.NegOffset[newInOldCoordinates]]; CDDirectory.RepositionObject[design: design, ob: originalInst.ob, oldSize: oldSize, baseOff: newInOldCoordinates ]; }; originalInst.location _ currentInst.location; CDOps.IncludeInstance[design, originalInst, FALSE]; [] _ CDEvents.ProcessEvent[afterReplace, design, originalInst.ob]; CDDirectory.PropagateChange[originalInst.ob, design]; END; DoNewCell: PROC [interactive: BOOL_FALSE] = BEGIN TerminalIO.WriteRope["new cell\n"]; currentInst.ob _ currentCellOb; design^.actual _ design^.actual.rest; design^.actual.first.indirectlyChanged _ TRUE; design^.actual.first.changed _ TRUE; IF ~IncludeAndNameCell[design, currentCellOb, interactive, FALSE].done THEN ERROR; CDOps.IncludeInstance[design, currentInst, FALSE]; CDDirectory.PropagateChange[currentInst.ob, design]; END; menu: REF _ fullPopMenu; IF design^.actual.rest=NIL THEN { TerminalIO.WriteRope["not in cell\n"]; RETURN [FALSE] }; originalInst _ design^.actual.first.mightReplace; originalCellOb _ originalInst.ob; originalCellPtr _ NARROW[originalCellOb.specificRef]; originalRect _ CDOrient.RectAt[originalInst.location, originalCellOb.size, originalInst.orientation]; TerminalIO.WriteRopes["Pop from cell ", originalCellPtr.name, "\n"]; CDInstances.DeSelectList[CDOps.InstList[design]]; currentRect _ CDInstances.BoundingRectO[CDOps.InstList[design]]; -- design coordinates currentCellOb _ CreateCellObject[CDOps.InstList[design], originalInst.orientation]; currentCellPtr _ NARROW[currentCellOb.specificRef]; currentCellPtr.useDIr _ design^.actual.first.specific.useDIr; IF ~currentCellPtr.useDIr THEN currentCellPtr.ir _ CDOrient.DeMapRect[ itemInWorld: design^.actual.first.specific.ir, cellSize: originalInst.ob.size, cellInstOrient: originalInst.orientation, cellInstPos: originalInst.location ].itemInCell; currentInst _ NEW[CD.InstanceRep _ [ ob: currentCellOb, location: CDBasics.BaseOfRect[currentRect], orientation: originalInst.orientation, selected: TRUE, properties: CDProperties.DangerousCopyProps[originalInst.properties] ]]; CDProperties.CopyProps[originalInst.ob.properties, currentCellOb]; IF m=flush OR (m=interactive AND ~design^.actual.first.changed) THEN { DoFlush[]; RETURN [TRUE] }; IF CDBasics.NonEmpty[currentRect] THEN { IF m=newcell THEN { DoNewCell[interactive: FALSE]; RETURN [TRUE] }; CDMarks.DoWithMark[design, CheckRecursionForPop]; IF recursive THEN { TerminalIO.WriteRope[" Original cell used inside, replace not possible\n"]; IF m=replace THEN RETURN[FALSE]; menu _ partialPopMenu; } ELSE { --ok, normal case IF m=replace THEN { DoReplace[]; RETURN [TRUE] }; } } ELSE { -- empty TerminalIO.WriteRope[" create empty cell not possible\n"]; IF m#interactive THEN {DoFlush[]; RETURN [TRUE]}; menu _ emptyPopMenu; }; SELECT CDMenus.CallMenu[menu] FROM $flush => DoFlush[]; $replace => DoReplace[]; $new => DoNewCell[interactive: TRUE]; ENDCASE => { TerminalIO.WriteRope["skipped\n"]; RETURN [FALSE] }; RETURN [TRUE]; END; -- -- -- -- -- -- -- -- -- -- -- -- ReadCell: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN ob: CD.Object = CreateEmptyCell[]; specific: CD.CellPtr = NARROW[ob.specificRef]; ob.size _ CDIOExtras.ReadPos[]; IF CDIO.VersionKey[]>=8 THEN { --now specific.simplifyOn _ TokenIO.ReadInt[]; specific.useDIr _ (TokenIO.ReadInt[]=0); IF ~specific.useDIr THEN specific.ir _ CDIOExtras.ReadRect[]; specific.origin _ CDIOExtras.ReadPos[]; } ELSE { -- old versions IF CDIO.VersionKey[]<1 THEN { specific.name _ TokenIO.ReadRope[]; } ELSE { specific.simplifyOn _ TokenIO.ReadInt[]; }; }; specific.contents _ CDIO.ReadInstanceList[]; specific.dIr _ CDInstances.BoundingRectI[specific.contents]; IF specific.useDIr THEN specific.ir _ specific.dIr; RETURN [ob]; END; RememberDesignOnWriting: CDEvents.EventProc = BEGIN lastOutputDesign _ design END; WriteCell: CD.InternalWriteProc -- PROC [me: Object] -- = BEGIN specific: CD.CellPtr = NARROW[me.specificRef]; CDIOExtras.WritePos[me.size]; TokenIO.WriteInt[specific.simplifyOn]; IF specific.useDIr AND specific.ir=specific.dIr THEN TokenIO.WriteInt[0] ELSE { TokenIO.WriteInt[1]; CDIOExtras.WriteRect[specific.ir]; }; CDIOExtras.WritePos[specific.origin]; CDIO.WriteInstanceList[specific.contents]; END; Describe: PROC[me: CD.Object] RETURNS [Rope.ROPE] = BEGIN RETURN [Rope.Concat["cell ", NARROW[me.specificRef, CD.CellPtr].name]] END; ReplaceDirectChildForCells: CDDirectory.ReplaceDChildsProc = BEGIN cp: CD.CellPtr = NARROW[me.specificRef]; needReposition: BOOL = ReplaceDirectChildForDummyCells[me, replace]; newIr: CD.Rect = CDInstances.BoundingRectI[cp.contents]; IF needReposition OR cp.dIr#newIr THEN { changed _ RepositionCell[me, design]; } END; ReplaceDirectChildForDummyCells: PUBLIC PROC [cellOb: CD.Object, replace: CDDirectory.ReplaceList] RETURNS [needReposition: BOOL] = BEGIN PointRect: PROC [class: CD.Position] RETURNS [CD.Rect] = INLINE { RETURN [[x1: class.x, y1: class.y, x2: class.x, y2: class.y]] }; cp: CD.CellPtr = NARROW[cellOb.specificRef]; needReposition _ FALSE; FOR replaceList: CDDirectory.ReplaceList _ replace, replaceList.rest WHILE replaceList#NIL DO rep: REF CDDirectory.ReplaceRec = replaceList.first; IF rep.old=cellOb THEN LOOP; FOR instL: CD.InstanceList _ cp.contents, instL.rest WHILE instL#NIL DO IF instL.first.ob=rep.old THEN { IF rep.newSize#rep.oldSize OR rep.off#[0, 0] THEN { realPos: CD.Position = CDOrient.MapPoint[ pointInCell: rep.off, cellSize: rep.oldSize, cellInstOrient: instL.first.orientation, cellInstPos: instL.first.location ]; fakePos: CD.Position = CDOrient.MapPoint[ pointInCell: [0, 0], cellSize: rep.newSize, cellInstOrient: instL.first.orientation, cellInstPos: [0, 0] ]; instL.first.location _ CDBasics.SubPoints[realPos, fakePos]; needReposition _ TRUE; }; instL.first.ob _ rep.new }; ENDLOOP; ENDLOOP; END; IsDummyCell: PROC [cellOb: CD.Object, design: CD.Design] RETURNS [isDummy: BOOL_FALSE] = INLINE BEGIN IF design#NIL THEN { FOR list: LIST OF CD.PushRec _ design.actual, list.rest WHILE list#NIL DO IF list.first.dummyCell.ob=cellOb THEN RETURN [isDummy_TRUE] ENDLOOP; }; END; RepositionCell: PUBLIC PROC [cellOb: CD.Object, design: CD.Design] RETURNS [didReposition: BOOLEAN] = BEGIN IF IsDummyCell[cellOb, design] THEN RETURN [didReposition_FALSE] ELSE { cp: CD.CellPtr = NARROW[cellOb.specificRef]; oldSize: CD.Position _ cellOb.size; oldR: CD.Rect _ CDBasics.RectAt[[0,0], oldSize]; oldDIr: CD.Rect _ cp.dIr; newR: CD.Rect = CDInstances.BoundingRectO[cp.contents]; newSize: CD.Position _ CDBasics.SizeOfRect[newR]; newBase: CD.Position = CDBasics.BaseOfRect[newR]; newDIr: CD.Rect _ CDInstances.BoundingRectI[cp.contents]; didReposition _ oldR#newR OR oldSize#newSize OR (cp.useDIr AND oldDIr#newDIr); IF didReposition THEN { IF cp.contents=NIL THEN { TerminalIO.WriteRopes["** tried to reposition an empty cell ", CDOps.Info[cellOb], "\n"]; RETURN }; IF newBase#[0, 0] THEN { CDInstances.TranslateList[cp.contents, CDBasics.NegOffset[newBase]]; newDIr _ CDBasics.MoveRect[newDIr, CDBasics.NegOffset[newBase]]; cp.origin _ CDBasics.SubPoints[cp.origin, newBase]; }; cellOb.size _ newSize; cp.dIr _ newDIr; cp.ir _ IF cp.useDIr THEN newDIr ELSE CDBasics.MoveRect[cp.ir, CDBasics.NegOffset[newBase]]; CDDirectory.RepositionObject[ design: design, ob: cellOb, oldSize: oldSize, baseOff: newBase ] } } END; SetInterestRect: PUBLIC PROC [cellOb: CD.Object, r: CD.Rect _ [0, 0, -1, -1]] = BEGIN cp: CD.CellPtr = NARROW[cellOb.specificRef]; cp.useDIr _ ~CDBasics.NonEmpty[r]; IF cp.useDIr THEN cp.ir _ cp.dIr ELSE cp.ir _ r END; Init[]; END. dCDCellsImpl.mesa (part of ChipNDale) Copyright c 1983, 1986 by Xerox Corporation. All rights reserved. by Christian Jacobi, June 24, 1983 5:00 pm last edited Christian Jacobi, February 19, 1986 3:28:27 pm PST --old stuff for io format version 4 --draw border --draw inside --draw border --draw inside --speed up rects... -- removes the selected instances from design and returns them -- does not includes the cell into any design or celldirectory -- does not name the cell -- not yet included in design --interactive -- if name is NIL: interactive read for name -- cell is included in directory --undo the command --verbose if inst is not a cell --Returns "pushing into ob would cause recursion" --HACK for CDDirectory XXX --originalInst.ob.properties _ currentCellOb.properties; is a second copy anyway -- PROC [event: REF, design: CD.Design, x: REF] -- PROC[me: CD.Object, design: CD.Design, replace: LIST OF REF ReplaceRec] -- --actually this is an error; but it could be produced by some silly client program, --so we do not abort --defaulting r means to use a reasonable default for the interest rect Κΰ˜codešœ&™&Kšœ Οmœ7™BKšœ-™-Kšœ@™@K˜—šΟk ˜ Kšžœ˜K˜ K˜K˜ K˜K˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜K˜ Kšœ ˜ Kšœ˜Kšœžœ ˜Kšœ˜K˜Kšœ ˜ —K˜šΠbl œžœžœ˜Kšžœžœžœœ˜ΉKšžœ˜Kšžœ˜"—Kšž˜K˜KšΟn#˜#K˜Kšœ ž œžœ˜EK˜˜,K˜3—˜(K˜4—K˜OK˜M˜^K˜—K˜Kšœ žœ'˜7Kšœžœ'˜:Kšœžœ3˜DKšœžœ žœ˜"K˜š œžœ˜Kšž˜KšœžœK˜RKšœ1˜1Kšœ˜Kšœ˜Kšœ˜Kšœ4˜4Kšœ"˜"Kšœ,˜,Kšœ-˜-Kšœ"˜"Kšœ$˜$Kšœ˜Kšœ+˜+Kšœ)˜)Kšœ#˜#KšœA˜AKšœ2˜2Kšœ5˜5Kšœ3˜3Kšœ3˜3Kšœ6˜6Kšœ6˜6Kšœ0˜0šœ-˜-šœ#˜#Kšœ!˜!Kšœžœ˜Kšœ#˜#Kšœ ž˜Kšœ˜—Kšœ˜—KšœM˜MKšžœ˜—K˜š  œžœžœžœžœ˜™>Kšž˜Kšœžœ˜KšœU˜UKšœ ˜ Kšžœ ˜Kšžœ˜—K˜š  œžœžœžœžœ ˜9Kšœ>™>Kšœ™Kšž˜šœžœžœ ˜Kšœ˜Kšœ ˜ Kšœ žœžœ˜-Kšœ˜—Kšžœ˜—K˜š  œžœžœžœ žœžœ ˜mKšœ™Kšž˜Kšœžœ˜"Kšœžœ žœ˜(Kšœžœ'’!˜QKšœD˜DKšœ[˜[Kšœ8˜8Kšžœ˜ Kšžœ˜—K˜š œžœ žœžœžœžœžœžœžœžœ˜„Kšž˜šžœžœ˜Kšœ'˜'Kšžœžœ˜K˜—Kš’ ™ šžœ˜Kšœžœžœ˜Kšœ žœžœ˜Kšœ ž˜šœ5˜5Kšœ$žœ žœžœ˜CKšœ˜—šžœ žœ˜Kšœ0˜0Kšžœ žœžœžœ˜'K˜—šžœžœ˜Kšœ žœ˜Kšœ˜Kšœ˜—šžœ&žœ˜.Kšœ žœ˜Kšœ-˜-Kšœ˜—šžœ1žœ˜:K˜>Kšžœžœ˜K˜—KšœR˜RKšžœ˜—Kšžœ˜—K˜š  œžœžœ žœžœžœ˜IKš žœžœžœ žœžœ˜3Kšœ,™,Kšœ ™ Kšž˜Kšœžœ0˜7Kšœžœ žœžœ˜(Kšœžœ'˜,Kšœžœ ˜Kšœ.˜.Kšœžœ˜"K˜K˜'Kšœžœ˜šžœžœžœ˜"Kšœ)˜)Kšžœžœ žœ˜!Kšœ˜—šžœžœžœ˜šžœ?žœžœžœ˜eKšœ™Kšœ'žœ˜.Kšžœžœ žœ˜!K˜—K˜—Kšžœ*˜.Kšœ$žœ’˜EKšœ8˜8Kšžœžœ˜#Kšžœ˜—K˜š  œžœžœ žœžœžœ˜FKšœ™Kšž˜šžœžœž˜Kšœžœ)˜1Kšœžœžœžœ+˜QKšžœžœžœ˜6KšžœQ˜X—Kšžœ˜K˜—š œžœ žœ žœ žœžœžœ˜\Kš’1™1Kšž˜š žœžœžœžœ!žœžœž˜@Kš žœžœžœžœžœžœ˜SKšžœ˜—Kšžœ˜—K˜š œž œ žœžœ žœžœžœ˜eKšž˜šžœžœ˜Kšœžœ žœ˜/Kšœžœ˜%Kšœ žœ žœ˜0Kšœžœ ˜Kšœ#˜#šžœ(žœ˜0KšœX˜XKšžœ žœ˜Kšœ˜—Kšœ’˜-šœ˜Kšœ˜K˜K˜"K˜K˜—šœ˜Kšœ˜K˜K˜"K˜K˜—˜,K˜K˜K˜K˜K˜—šœžœžœ˜$Kšœ ˜ Kšœ žœ˜Kšœ<˜