CDCellsImpl2.mesa (part of ChipNDale)
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
by Ch. Jacobi, September 10, 1984 9:20:09 am PDT
last edited by Ch. Jacobi, March 14, 1986 10:42:44 am PST
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𡤀,
cellCSystem: CoordSystem←originCoords,
obCSystem: CoordSystem←interrestCoords,
mode: CDCells.IncludeMode𡤍oit]
RETURNS [newInst: CD.Instance, rep: BOOLFALSE] =
--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𡤍oit] RETURNS [removed: BOOLFALSE, rep: BOOLFALSE] =
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.