CDFeedbackImpl.Mesa
Last Edited by: Spreitzer, December 13, 1984 6:17:18 pm PST
Last Edited by: Jacobi, May 22, 1985 5:29:08 pm PDT
DIRECTORY
CD, CDBasics, CDDirectory, CDFeedback, CDOps, CDProperties, CDRects, CDViewer, CDCells, ImagerTransformation, Real, Rope;
CDFeedbackImpl: CEDAR PROGRAM IMPORTS CDBasics, CDDirectory, CDOps, CDProperties, CDRects, CDViewer, CDCells, ImagerTransformation, Real EXPORTS CDFeedback =
{OPEN CDFeedback;
Showing: TYPE = REF ShowingRep;
ShowingRep: PUBLIC TYPE = RECORD [
design: CD.Design,
insts: InstanceList ← NIL];
InstanceList: TYPE = LIST OF Instance;
Instance: TYPE = RECORD [
in: CD.Object,
appl: CD.Instance];
feedbackKey: PUBLIC ATOM ← $Feedback;
EmptyShow: PUBLIC SIGNAL = CODE;
NoneVisible: PUBLIC SIGNAL = CODE;
Show:
PUBLIC PROC [
design: CD.Design,
rect: CD.Rect,
Will be clipped to bounding box of containing cells.
message: Rope.ROPENIL,
Goes on the application as value of $SignalName property.
flag: ATOM ← $feedback,
Goes on the application as value of feedbackKey property.
in: CellType,
EnumerateSomeInstances: PROC [
cellType: CellType,
to: PROC [transform: Transform, parent: CellType] RETURNS [stop: BOOL]
]
EnumerateSomeInstances may enumerate as many or as few (even none, if you're willing to live with the consequences) of the instances of cellType as it wishes.
]
RETURNS [showing: Showing] =
{
AddRect: PROC [r: CD.Rect, obj: CD.Object] = {
ir: CD.Rect ← IF obj # NIL THEN CDBasics.Intersection[r, CDBasics.RectAt[pos: [0,0], size: obj.size]] ELSE r;
ro: CD.Object ← CDRects.CreateRect[size: CDBasics.SizeOfRect[ir], l: CD.highLightError];
appl: CD.Instance ← CDCells.IncludeOb[design: design, cell: obj, ob: ro,
position: CDBasics.BaseOfRect[ir],
cellCSystem: cdCoords,
obCSystem: interrestCoords].newInst;
CDProperties.PutPropOnInstance[appl, $SignalName, message];
CDProperties.PutPropOnInstance[appl, feedbackKey, flag];
showing.insts ← CONS[[obj, appl], showing.insts];
madeMarks ← TRUE;
};
someVisibleBounds: CD.Rect;
madeMarks, foundVisible: BOOLFALSE;
FindTop: PROC [r: CD.Rect, ct: CellType] = {
IF ct = top THEN {
IF foundVisible THEN ERROR ELSE someVisibleBounds ← r;
foundVisible ← TRUE}
ELSE {
TryInstance: PROC [transform: Transform, parent: CellType] RETURNS [stop: BOOL] = {
FindTop[TransformRect[r, transform], parent];
stop ← foundVisible
};
EnumerateSomeInstances[ct, TryInstance];
};
};
Mark: PROC [r: CD.Rect, ct: CellType] = {
IF ct = top THEN {
AddRect[r, NIL];
IF NOT foundVisible THEN FindTop[r, top];
}
ELSE {
MarkInInstance: PROC [transform: Transform, parent: CellType] RETURNS [stop: BOOL] = {
Mark[TransformRect[r, transform], parent];
stop ← FALSE;
};
shownHere: BOOL -- in names a ChipNDale object that is a cell in design--;
found: BOOL;
obj: CD.Object;
[found, obj] ← CDDirectory.Fetch[design, ct];
shownHere ← found AND ISTYPE[obj.specificRef, CD.CellPtr];
IF shownHere THEN {
AddRect[r, obj];
IF NOT foundVisible THEN FindTop[r, ct]
}
ELSE {
EnumerateSomeInstances[ct, MarkInInstance];
}
};
};
showing ← NEW [ShowingRep ← [design]];
Mark[rect, in];
IF foundVisible THEN {--scroll to show someVisibleBounds
vl: CDViewer.ViewerList ← CDViewer.ViewersOf[design];
FOR vl ← vl, vl.rest WHILE vl # NIL DO
IF CDViewer.DesignOf[vl.first].design = design THEN CDViewer.ShowAndScale[viewer: vl.first, rect: someVisibleBounds];
ENDLOOP;
}
ELSE IF madeMarks THEN NoneVisible[]
ELSE EmptyShow[];
};
UnShow: PUBLIC PROC [showing: Showing] = {
FOR il: InstanceList ← showing.insts, il.rest WHILE il # NIL DO
[] ← CDCells.RemoveInstance[design: showing.design, cell: il.first.in, inst: il.first.appl]
ENDLOOP;
CDOps.Redraw[showing.design];
};
TransformRect: PROC [r: CD.Rect, t: Transform] RETURNS [s: CD.Rect] = {
tr: ImagerTransformation.Rectangle ← ImagerTransformation.TransformRectangle[
t, [x: r.x1, y: r.y1, w: r.x2 - r.x1, h: r.y2 - r.y1]];
s ← CD.Rect[
x1: Real.Round[tr.x],
y1: Real.Round[tr.y],
x2: Real.Round[tr.x + tr.w],
y2: Real.Round[tr.y + tr.h]
];
};
Start: PROC = {
[] ← CDProperties.RegisterProperty[feedbackKey];
};
Start[];
}.