<> <> <> <> DIRECTORY CD, CDAbuts, CDBasics, CDCallSpecific, CDCells, CDDirectory, CDMenus, CDOps, CDProperties, CDSequencer, CDX, Rope, TerminalIO; CDAbutsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCallSpecific, CDCells, CDDirectory, CDMenus, CDOps, CDProperties, CDSequencer, CDX, Rope, TerminalIO EXPORTS CDAbuts SHARES CDDirectory = BEGIN OPEN CDAbuts; <> IsAbutX: PUBLIC IsAbutProc = { yes _ (ob#NIL) AND (ob.specificRef#NIL) AND ISTYPE [ob.specificRef, LIST OF CD.ObPtr] AND (ob.p=pForAbutX) AND (ob.p.objectType=$AbutX); }; -- completely redundant IsAbutY: PUBLIC IsAbutProc = { yes _ (ob#NIL) AND (ob.specificRef#NIL) AND ISTYPE [ob.specificRef, LIST OF CD.ObPtr] AND (ob.p=pForAbutY) AND (ob.p.objectType=$AbutY); }; -- completely redundant IsAbut: PUBLIC IsAbutProc = { yes _ (ob#NIL) AND (ob.specificRef#NIL) AND ISTYPE [ob.specificRef, LIST OF CD.ObPtr] AND (ob.p=pForAbutX OR ob.p=pForAbutY) AND (ob.p.objectType=$AbutX OR ob.p.objectType=$AbutY); }; -- completely redundant <<>> <> <> GetAbutSubObjects: PUBLIC PROC [abut: CD.ObPtr] RETURNS [subObjects: LIST OF CD.ObPtr] = { subObjects _ NARROW [abut.specificRef]; }; <<>> <> CreateNewAbutX: PUBLIC CreateAbutProc = { newAbut _ NEW [CD.ObjectDefinition _ [p: pForAbutX, specificRef: subObjects]]; newAbut.size _ Expand[newAbut, NIL, NIL].size; }; CreateNewAbutY: PUBLIC CreateAbutProc = { newAbut _ NEW [CD.ObjectDefinition _ [p: pForAbutY, specificRef: subObjects]]; newAbut.size _ Expand[newAbut, NIL, NIL].size; }; <> <> Expand: CDDirectory.AnotherProc -- [me: CD.ObPtr, from: CD.Design, to: CD.Design] RETURNS [CD.ObPtr] -- = { pos: CD.Position _ [0, 0]; equivalentCell: CD.ObPtr; IF to=NIL THEN { ref: REF _ CDProperties.GetPropFromObject[me, $AbutCache]; IF ref#NIL THEN RETURN[NARROW[ref]]; }; equivalentCell _ CDCells.CreateEmptyCell[]; FOR list: LIST OF CD.ObPtr _ GetAbutSubObjects[me], list.rest WHILE list#NIL DO [] _ CDX.IncludeOb[design: NIL, cell: equivalentCell, ob: list.first, position: pos, cellCSystem: originCoords, obCSystem: interrestCoords, mode: dontPropagate]; SELECT me.p FROM pForAbutX => pos.x _ pos.x + CDBasics.SizeOfRect[CD.InterestRect[list.first]].x; pForAbutY => pos.y _ pos.y + CDBasics.SizeOfRect[CD.InterestRect[list.first]].y; ENDCASE => ERROR; ENDLOOP; [] _ CDCells.RepositionCell[equivalentCell, NIL]; IF to#NIL THEN [] _ CDDirectory.Include[to, equivalentCell, Rope.Cat[CDDirectory.Name[equivalentCell], "-AbutEquivalent"]] ELSE CDProperties.PutPropOnObject[me, $AbutCache, equivalentCell]; RETURN [equivalentCell]; }; <> EnumerateAbutChildObjects: CDDirectory.EnumerateChildObjectsProc -- [me: CD.ObPtr, p: CDDirectory.EnumerateObjectsProc, x: REF ANY] -- = { ref: REF _ CDProperties.GetPropFromObject[me, $AbutCache]; IF ref#NIL THEN p[NARROW[ref], x]; FOR w: LIST OF CD.ObPtr _ GetAbutSubObjects[me], w.rest WHILE w#NIL DO p[w.first, x] ENDLOOP; }; ReplaceAbutDirectChilds: CDDirectory.ReplaceDChildsProc -- [me: CD.ObPtr, design: CD.Design, replace: CDDirectory.ReplaceList] RETURNS [changed: BOOL _ FALSE] -- = BEGIN oldSize: CD.Position _ me.size; subObjects: LIST OF CD.ObPtr _ GetAbutSubObjects[me]; FOR w: LIST OF CD.ObPtr _ subObjects, w.rest WHILE w#NIL DO FOR l: CDDirectory.ReplaceList _ replace, l.rest WHILE l#NIL DO IF l.first.old=w.first THEN {changed _ TRUE; EXIT}; ENDLOOP; IF changed THEN EXIT; ENDLOOP; IF ~changed THEN RETURN; CDProperties.PutPropOnObject[me, $AbutCache, NIL]; me.size _ CDDirectory.Expand[me, NIL, NIL].size; changed _ oldSize = me.size; CDDirectory.RepositionObject[design, me, oldSize]; END; AnotherAbut: CDDirectory.AnotherProc -- [me: CD.ObPtr, from: CD.Design, to: CD.Design] RETURNS [CD.ObPtr] -- = BEGIN newAbut: CD.ObPtr _ IF IsAbutX[me] THEN CreateNewAbutX[GetAbutSubObjects[me]] ELSE CreateNewAbutY[GetAbutSubObjects[me]]; IF to#NIL THEN [] _ CDDirectory.Include[to, newAbut, CDDirectory.Name[me]]; RETURN [newAbut] END; <> <<>> DrawAbutSelection: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = { aptr _ NEW [CD.Application _ [ ob: CDDirectory.Expand[aptr.ob, NIL, NIL], location: aptr.location, selected: aptr.selected]]; aptr.ob.p.showMeSelected[aptr, pos, orient, pr]; }; InterestRect: CD.RectProc -- [ob: CD.ObPtr] RETURNS [CD.DesignRect] -- = { rect: CD.Rect _ CD.InterestRect[CDDirectory.Expand[ob, NIL, NIL]]; RETURN [rect]; }; <> TransformToCellS: PROC [comm: CDSequencer.Command] = BEGIN n: NAT; TerminalIO.WriteRope["transform to cell\n"]; n _ CDCallSpecific.CallForSelected[comm.design, $TransformToCell]; TerminalIO.WriteInt[n]; TerminalIO.WriteRope[" objects transformed\n"]; END; <<>> TransformToCell: CDCallSpecific.CallProc -- PROC [design: CD.Design, aptr: CD.ApplicationPtr, x: REF] RETURNS [done: BOOL_TRUE, removeMe: BOOL_FALSE, include: CD.ApplicationList_NIL, repaintMe: BOOL_FALSE, repaintInclude: BOOL_FALSE] -- = BEGIN cob: CD.ObPtr _ NIL; IF IsAbut[aptr.ob] THEN cob _ CDDirectory.Expand[aptr.ob, design, design]; done _ cob#NIL; IF done THEN { removeMe _ TRUE; repaintMe _ TRUE; include _ LIST[NEW[CD.Application _ [ ob: cob, location: aptr.location, orientation: aptr.orientation, selected: aptr.selected, properties: CDProperties.CopyProps[aptr.properties] ]]]; repaintInclude _ TRUE; } END; <<>> <> ExpandAndPushS: PROC [comm: CDSequencer.Command] = BEGIN first: CD.ApplicationPtr; multiple: BOOL; [first, multiple] _ CDOps.SelectedApplication[comm.design]; TerminalIO.WriteRope["ExpandAndPush into object "]; IF multiple THEN {TerminalIO.WriteRope["Multiple selected object\n"]; RETURN}; IF first=NIL THEN {TerminalIO.WriteRope["No selected object\n"]; RETURN}; SELECT TRUE FROM CDCells.IsCell[first.ob] => IF CDCells.PushInCellSelected[comm.design] THEN { TerminalIO.WriteRope[comm.design.actual.first.specific.name]; TerminalIO.WriteLn[] } ELSE TerminalIO.WriteRope["not done\n"]; IsAbut[first.ob] => { TerminalIO.WriteRope[CDDirectory.Name[first.ob]]; TerminalIO.WriteRope[" expanded into "]; first.ob _ CDDirectory.Expand[first.ob, comm.design, comm.design]; IF CDCells.PushInCellSelected[comm.design] THEN { TerminalIO.WriteRope[comm.design.actual.first.specific.name]; TerminalIO.WriteLn[] } ELSE TerminalIO.WriteRope["not done\n"]; }; ENDCASE => TerminalIO.WriteRope[" not done\n"]; END; <<>> <> pForAbutX: REF CD.ObjectProcs = CD.RegisterObjectType[$AbutX]; dpx: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[pForAbutX]; <<>> pForAbutY: REF CD.ObjectProcs = CD.RegisterObjectType[$AbutY]; dpy: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[pForAbutY]; <> <> dpx.enumerateChildObjects _ EnumerateAbutChildObjects; dpx.replaceDirectChilds _ ReplaceAbutDirectChilds; dpx.another _ AnotherAbut; dpx.expand _ Expand; <<>> <> pForAbutX.showMeSelected _ DrawAbutSelection; pForAbutX.interestRect _ InterestRect; <> <> dpy.enumerateChildObjects _ EnumerateAbutChildObjects; dpy.replaceDirectChilds _ ReplaceAbutDirectChilds; dpy.another _ AnotherAbut; dpy.expand _ Expand; <> pForAbutY.showMeSelected _ DrawAbutSelection; pForAbutY.interestRect _ InterestRect; <> [] _ CDProperties.RegisterProperty[$AbutCache, $Abuts]; CDProperties.FetchProcs[$AbutCache].makeCopy _ CDProperties.DontCopy; <<>> <> CDCallSpecific.Register[$TransformToCell, pForAbutX, TransformToCell]; CDCallSpecific.Register[$TransformToCell, pForAbutY, TransformToCell]; CDSequencer.ImplementCommand[$TransformToCellS, TransformToCellS,, doQueue]; CDMenus.CreateEntry[$SpecialMenu, "Abuts -> Cell", $TransformToCellS]; <<>> <> CDSequencer.ImplementCommand[$ExpandAndPushS, ExpandAndPushS,, doQueue]; <<>> END.