CDFeedbackImpl.Mesa
Last Edited by: Spreitzer, December 13, 1984 6:17:18 pm PST
Last Edited by: Jacobi, April 17, 1985 11:51:30 am PST
DIRECTORY
CD, CDBasics, CDDirectory, CDFeedback, CDOps, CDProperties, CDRects, CDViewer, CDX, ImagerTransform, Rope;
CDFeedbackImpl: CEDAR PROGRAM IMPORTS CDBasics, CDDirectory, CDOps, CDProperties, CDRects, CDViewer, CDX, ImagerTransform 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.ObPtr,
appl: CD.ApplicationPtr];
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.ObPtr] = {
ir: CD.Rect ← IF obj # NIL THEN CDBasics.Intersection[r, CDBasics.RectAt[pos: [0,0], size: obj.size]] ELSE r;
ro: CD.ObPtr ← CDRects.CreateRect[size: CDBasics.SizeOfRect[ir], l: CD.highLightError];
appl: CD.ApplicationPtr ← CDX.IncludeOb[design: design, cell: obj, ob: ro,
position: CDBasics.BaseOfRect[ir],
cellCSystem: cdCoords,
obCSystem: interrestCoords].newApp;
CDProperties.PutPropOnApplication[appl, $SignalName, message];
CDProperties.PutPropOnApplication[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.ObPtr;
[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
[] ← CDX.RemoveApp[design: showing.design, cell: il.first.in, app: il.first.appl]
ENDLOOP;
CDOps.Redraw[showing.design];
};
TransformRect: PROC [r: CD.Rect, t: Transform] RETURNS [s: CD.Rect] = {
tr: ImagerTransform.IntRectangle ← ImagerTransform.TransformIntRectangle[[x: r.x1, y: r.y1, w: r.x2 - r.x1, h: r.y2 - r.y1], t];
s ← [x1: tr.x, y1: tr.y, x2: tr.x + tr.w, y2: tr.y + tr.h];
};
Start: PROC = {
[] ← CDProperties.RegisterProperty[feedbackKey];
};
Start[];
}.