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: 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𡤍oit] 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;