<> <> <> 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, <> message: Rope.ROPE _ NIL, <> flag: ATOM _ $feedback, <> in: CellType, EnumerateSomeInstances: PROC [ cellType: CellType, to: PROC [transform: Transform, parent: CellType] RETURNS [stop: BOOL] ] <> ] 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: BOOL _ FALSE; 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[]; }.