<> <> <> <> DIRECTORY CD, CDInstances, CDBasics, CDCells, CDDirectory, CDOps, CDOrient; CDCellsImpl2: CEDAR PROGRAM IMPORTS CD, CDInstances, CDBasics, CDCells, CDDirectory, CDOps, CDOrient EXPORTS CDCells = BEGIN CoordSystem: TYPE = CDCells.CoordSystem; <<{outerCoordinates, innerCoordinates, clientCoordinates};>> <<>> IncludeOb: PUBLIC PROC [design: CD.Design_NIL, cell: CD.Object_NIL, ob: CD.Object, position: CD.Position_[0, 0], --evaluated before an eventual repositioning orientation: CD.Orientation_0, cellCSystem: CoordSystem_originCoords, obCSystem: CoordSystem_interrestCoords, mode: CDCells.IncludeMode_doit] RETURNS [newInst: CD.Instance, rep: BOOL_FALSE] = <<--design (NIL: allowed, if cell really is not yet part of a design)>> <<--cell (NIL: include into design; assumes the designs origin at [0, 0])>> <<-- (design&cell NIL: simply create an application)>> <<--ob: object to include in cell >> <<--position: ...>> <<--orientation: of ob inside cell >> <<--cellCSystem: tells reference point in cell (for designs: [0, 0] anyway)>> <<--obCSystem: reference point of object>> <<--mode:>> <<-- doit: normal case everything is done>> <<-- dontReposition: speed up hack>> <<-- Caution: makes temporary a wrong coordinate system! cell is >> <<-- not legal until repositioning is called to clean up.>> <<-- Has no effect if cell is NIL.>> <<-- Does not cause redrawing of the design.>> <<-- dontPropagate: speed up hack.>> <<-- does neither reposition nor propagate the changed event; cell gets>> <<-- an illegal state until repositioning and change-propagation occurs. >> <<-- dontInclude: hack to create instances; cell is not changed at all.>> <<--newInst: the new created application>> <<--rep: Reposition was done or should be done, depending of mode>> BEGIN cp: CD.CellPtr; obInterestRect: CD.Rect = CD.InterestRect[ob]; IF ob=NIL THEN ERROR CD.Error[callingError, "Include NIL ob"]; <<--prepare cell and position relative to cell>> IF cell=NIL THEN { IF design=NIL THEN cp _ NIL ELSE cp _ design^.actual.first.specific; } ELSE { cp _ NARROW[cell.specificRef]; SELECT cellCSystem FROM originCoords => position _ CDBasics.AddPoints[position, CD.ClientOrigin[cell]]; interrestCoords => position _ CDBasics.AddPoints[position, CDBasics.BaseOfRect[CD.InterestRect[cell]]]; ENDCASE --cdCoords-- => NULL; }; <<--handle position: >> <<-- realPos _ (clientPos+cellOrigin) - (position of object origin at fake [0,0] pos)>> newInst _ NEW[CD.InstanceRep _ [ ob: ob, location: CDBasics.SubPoints[ position, --in cell coordinate system CDBasics.BaseOfRect[ --correction for object coordinate system CDOrient.MapRect[ itemInCell: (SELECT obCSystem FROM interrestCoords => obInterestRect, originCoords => CDBasics.RectAt[CD.ClientOrigin[ob], [0, 0]], cdCoords => CDBasics.RectAt[[0, 0], ob.size], ENDCASE => ERROR ), cellSize: ob.size, cellInstOrient: orientation, cellInstPos: [0, 0] ] ] ], orientation: orientation, selected: FALSE ]]; <<--include, handle propagation and reposition >> IF cp#NIL AND mode#dontInclude THEN { cp.contents _ CONS[newInst, cp.contents]; --does not yet change insideRect !! IF cell#NIL THEN { rep _ ~CDBasics.Inside[CDInstances.InstRectO[newInst], CDBasics.RectAt[[0, 0], cell.size]] OR (cp.useDIr AND ~CDBasics.Inside[ CDOrient.MapRect[ itemInCell: obInterestRect, cellSize: ob.size, cellInstOrient: orientation, cellInstPos: newInst.location], CD.InterestRect[cell] ] ); IF rep AND mode=doit THEN [] _ CDCells.RepositionCell[cell, design]; IF mode#dontPropagate THEN CDDirectory.PropagateChange[cell, design]; }; --cell#NIL IF design#NIL AND mode=doit THEN { IF cell=NIL THEN CDOps.RedrawInstance[design, newInst, FALSE] ELSE CDOps.DelayedRedraw[design] }; }; END; RemoveInstance: PUBLIC PROC [design: CD.Design_NIL, cell: CD.Object_NIL, inst: CD.Instance, mode: CDCells.IncludeMode_doit] RETURNS [removed: BOOL_FALSE, rep: BOOL_FALSE] = BEGIN cp: CD.CellPtr; IF inst=NIL THEN ERROR CD.Error[callingError, "Remove NIL inst"]; <<--prepare cell >> IF cell=NIL THEN { IF design=NIL THEN ERROR CD.Error[callingError, "Remove from NIL cell"]; cp _ design^.actual.first.specific; } ELSE { cp _ NARROW[cell.specificRef]; }; <<--remove, handle propagation and reposition >> IF cp#NIL AND mode#dontInclude THEN { IF cp.contents#NIL THEN { IF cp.contents.first=inst THEN { removed _ TRUE; cp.contents _ cp.contents.rest } ELSE FOR list: CD.InstanceList _ cp.contents, list.rest WHILE list.rest#NIL DO IF list.rest.first=inst THEN { removed _ TRUE; list.rest _ list.rest.rest; EXIT } ENDLOOP; }; IF cell#NIL THEN { r: CD.Rect = CDInstances.InstRectO[inst]; rep _ r.x1<=0 OR r.y1<=0 OR r.x2>=cell.size.x OR r.y2>=cell.size.y; IF ~rep AND cp.useDIr THEN { rep _ r.x1<=cp.ir.x1 OR r.y1<=cp.ir.y1 OR r.x2>=cp.ir.x2 OR r.y2>=cp.ir.y2; }; IF rep AND mode=doit THEN [] _ CDCells.RepositionCell[cell, design]; IF mode#dontPropagate THEN CDDirectory.PropagateChange[cell, design]; }; --cell#NIL IF design#NIL AND mode=doit THEN { IF cell=NIL THEN CDOps.RedrawInstance[design, inst] ELSE CDOps.DelayedRedraw[design] }; }; END; END.