CDHierarchyMarksImpl.mesa (part of ChipNDale)
Copyright © 1986 by Xerox Corporation. All rights reserved.
Christian Jacobi, July 16, 1986 8:09:57 pm PDT
last edited by Christian Jacobi, July 17, 1986 11:29:46 am PDT
DIRECTORY
CD,
CDBasics,
CDCells,
CDCommandOps,
CDHierarchyMarks,
CDInstances,
CDOps,
CDProperties,
CDRects,
CDSequencer,
CDSimpleOps,
CDViewer,
CDViewHighlight,
RuntimeError USING [UNCAUGHT],
TerminalIO,
ViewerClasses USING [Viewer];
CDHierarchyMarksImpl: CEDAR MONITOR
IMPORTS CD, CDInstances, CDBasics, CDCells, CDCommandOps, CDOps, CDProperties, CDRects, CDSequencer, CDSimpleOps, CDViewer, CDViewHighlight, RuntimeError, TerminalIO
EXPORTS CDHierarchyMarks =
BEGIN
SetHierarchyMarkProc: TYPE = CDHierarchyMarks.SetHierarchyMarkProc;
myKey: ATOM ← $CDHierarchyMark;
GetHierarchyMark: PUBLIC PROC [design: CD.Design←NIL, ob: CD.Object←NIL] RETURNS [inst: CD.Instance←NIL] = {
GetFrom: PROC [x: REF] RETURNS [inst: CD.Instance←NIL] = {
WITH CDProperties.GetProp[x, myKey] SELECT FROM
i: CD.Instance => RETURN [i];
ENDCASE => NULL;
};
IF ob#NIL THEN inst ← GetFrom[ob]
ELSE IF design#NIL THEN inst ← GetFrom[design];
};
ReallySetHierarchyMark: PROC [design: CD.Design, ob: CD.Object←NIL, inst: CD.Instance] = {
--inst must be in the coordinate system of ob!
i2: CD.Instance;
inst ← CDInstances.Copy[inst];
IF design=NIL THEN {
IF ob#NIL THEN CDProperties.PutProp[ob, myKey, inst]
}
ELSE {
IF ob=NIL THEN {
--put it to the design and to the real top level dummy cell
CDProperties.PutProp[design, myKey, inst];
CDProperties.PutProp[CDOps.RealTopCell[design], myKey, inst];
}
ELSE {
--put property to both, the mightReplace and the dummyCell, if it should go on either
CDProperties.PutProp[ob, myKey, inst];
--fancy cases when we are pushed in to this cell
FOR list: LIST OF CD.PushRec ← design.actual, list.rest WHILE list#NIL DO
IF list.first.dummyCell.ob=ob THEN {
--we assume inst to be in design coordinates
IF list.first.mightReplace=NIL THEN CDProperties.PutProp[design, myKey, inst]
ELSE {
i2 ← CDInstances.DeComposed[inst, list.first.mightReplace.trans];
CDProperties.PutProp[list.first.mightReplace.ob, myKey, i2];
};
RETURN;
};
IF list.first.mightReplace#NIL AND list.first.mightReplace.ob=ob THEN {
--we assume inst to be in cell coordinates
i2 ← CDInstances.Composed[inst, list.first.mightReplace.trans];
CDProperties.PutProp[list.first.dummyCell.ob, myKey, i2];
RETURN;
};
ENDLOOP;
};
};
};
SetHierarchyMark: PUBLIC PROC [design: CD.Design, ob: CD.Object←NIL, inst: CD.Instance] = {
FOR list: LIST OF SetHierarchyMarkProc ← regList, list.rest WHILE list#NIL DO
list.first[design, ob, inst ! RuntimeError.UNCAUGHT => CONTINUE];
ENDLOOP;
};
regList: LIST OF SetHierarchyMarkProc;
RegisterHierarchyMarker: PUBLIC ENTRY PROC [setHierarchyMark: SetHierarchyMarkProc] = {
IF setHierarchyMark#NIL THEN {
IF regList=NIL THEN regList ← LIST[setHierarchyMark]
ELSE
FOR list: LIST OF SetHierarchyMarkProc ← regList, list.rest DO
IF list.rest=NIL THEN {list.rest ← LIST[setHierarchyMark]; EXIT}
ENDLOOP
};
};
--########################
RemDisplayHierachyMarkComm: PROC [comm: CDSequencer.Command] = {
viewer: ViewerClasses.Viewer ← CDViewer.GetViewer[comm];
IF viewer#NIL THEN CDViewHighlight.ShowInstance[v: viewer, key: myViewKey]
};
PutHierachyMarkComm: PROC [comm: CDSequencer.Command] = {
selected: CD.Instance ← CDOps.TheInstance[comm.design, "place the hierarchy mark\n"];
IF selected#NIL THEN {
SetHierarchyMark[comm.design, CDOps.PushedTopCell[comm.design], selected];
TDisplayHierarchyMarkComm[comm];
};
};
SelectHierachyMarkComm: PROC [comm: CDSequencer.Command] = {
Match: PROC [i1, i2: CD.Instance] RETURNS [BOOL] = INLINE {
RETURN [i1.ob=i2.ob AND i1.trans=i2.trans]
};
inst: CD.Instance; found: INT ← 0;
TerminalIO.PutRope["select hierarchy mark\n"];
IF CDCells.IsPushedIn[comm.design] THEN {
mr: CD.Instance ← comm.design.actual.first.mightReplace;
inst ← GetHierarchyMark[comm.design, mr.ob];
IF inst#NIL THEN inst ← CDInstances.Composed[inst, mr.trans];
}
ELSE inst ← GetHierarchyMark[comm.design, NIL];
IF inst=NIL THEN TerminalIO.PutRope["no hierarchy mark is set\n"]
ELSE {
CDSimpleOps.DeselectAll[comm.design];
FOR il: CD.InstanceList ← CDOps.InstList[comm.design], il.rest WHILE il#NIL DO
IF Match[il.first, inst] THEN {
il.first.selected ← TRUE; found ← found+1;
CDOps.RedrawInstance[comm.design, il.first, FALSE];
};
ENDLOOP;
IF found#1 THEN TerminalIO.PutRope["hierarchy mark not unique\n"]
};
};
TDisplayHierarchyMarkComm: PROC [comm: CDSequencer.Command] = {
--T=>Top
startInst: CD.Instance ← comm.design.actual.first.mightReplace;
IF startInst=NIL THEN startInst ← comm.design.actual.first.dummyCell;
DisplayHierarchyMarks[comm.design, LIST[startInst], comm];
};
ADisplayHierarchyMarkComm: PROC [comm: CDSequencer.Command] = {
--A=>Selected from top level
DisplayHierarchyMarks[comm.design, CDOps.InstList[comm.design], comm];
};
SDisplayHierarchyMarkComm: PROC [comm: CDSequencer.Command] = {
--S=>All from top level
DisplayHierarchyMarks[comm.design, CDInstances.SplitSelected[CDOps.InstList[comm.design]].selected, comm];
};
myViewKey: ATOMNIL; --$CDHierarchyMark;
CreateEmptyCell: PROC [] RETURNS [cell: CD.Object] = {
cell ← CDCells.CreateEmptyCell[];
CDCells.SetSimplificationTreshhold[cell, 0];
};
MakeMarker: PROC [highlightInst: CD.Instance, mark: CD.Rect, lambda: CD.Number𡤂] = {
mOb: CD.Object ← CreateEmptyCell[];
d: CD.Number ← MAX[lambda, MIN[mark.x2-mark.x1, mark.y2-mark.y1]/20];
lineOb: CD.Object;
lineOb ← CDRects.CreateRect[size: [mark.x2-mark.x1+2*d, d], l: CD.shadeLayer];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, trans: [[-d, -d]]];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, trans: [[-d, mark.y2-mark.y1]]];
lineOb ← CDRects.CreateRect[size: [d, mark.y2-mark.y1], l: CD.shadeLayer];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, trans: [[-d, 0]]];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, trans: [[mark.x2-mark.x1, 0]]];
[] ← CDCells.ResizeCell[NIL, mOb];
[] ← CDCells.IncludeOb[cell: highlightInst.ob, ob: mOb, trans: [CDBasics.BaseOfRect[mark]]];
};
foundAndStop: SIGNAL [ig: CD.Instance] = CODE;
--ig in global design coordinates
DontDrawRects: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = {};
DrawChild: PROC [inst: CD.Instance, trans: CD.Transformation, pr: REF CD.DrawInformation] = {
searchInst: CD.Instance ← NARROW[pr.devicePrivate];
IF searchInst.ob=inst.ob AND searchInst.trans=trans THEN {
ig: CD.Instance ← CDInstances.NewInst[inst.ob, trans];
SIGNAL foundAndStop [ig]
};
};
DisplayHierarchyMarks: PROC [design: CD.Design, il: CD.InstanceList, viewerHint: REF] = {
--il in global design coordinate system
highlightInst: CD.Instance ← NIL;
GoDown: PROC [fromInst: CD.Instance] = {
--fromInst in global design coordinate system
foundInst: CD.Instance ← NIL; --will be in design coordinate system
markInst: CD.Instance ← NIL; --will be in fromInst.ob's coordinate system
multiple: BOOLFALSE;
IF CDProperties.GetProp[fromInst.ob, $IconFor]#NIL THEN RETURN;
markInst ← GetHierarchyMark[design, fromInst.ob];
IF markInst#NIL THEN {
pr.devicePrivate ← CDInstances.Composed[markInst, fromInst.trans]; --get design coords
--draw in design coords
fromInst.ob.class.drawMe[inst: fromInst, trans: fromInst.trans, pr: pr !
foundAndStop => {
IF foundInst=NIL THEN {foundInst ← ig; RESUME}
ELSE {multiple ← TRUE; CONTINUE}
}
];
IF foundInst#NIL THEN {
IF multiple THEN TerminalIO.PutRopes["****multiple hierarchymarks in ", CDOps.InstRope[fromInst], "\n"]
ELSE {
IF highlightInst=NIL THEN highlightInst ← CDInstances.NewInst[CreateEmptyCell[]];
MakeMarker[highlightInst, CDInstances.InstRectI[foundInst], design.technology.lambda];
GoDown[foundInst];
};
};
}
};
pr: CD.DrawRef ← CD.CreateDrawRef[inf: [
design: design,
drawChild: DrawChild,
drawRect: DontDrawRects
]];
FOR list: CD.InstanceList ← il, list.rest WHILE list#NIL DO
GoDown[list.first];
IF CDSequencer.Aborted[design] THEN EXIT;
ENDLOOP;
IF highlightInst=NIL THEN TerminalIO.PutRope["no hierarchy marks set\n"]
ELSE {
[] ← CDCells.ResizeCell[NIL, highlightInst.ob];
};
FOR vL: CDViewer.ViewerList ← CDViewer.ViewersOf[viewerHint], vL.rest WHILE vL#NIL DO
CDViewHighlight.ShowInstance[v: vL.first, instOrList: highlightInst, key: myViewKey];
ENDLOOP
};
--########################
[] ← CDProperties.RegisterProperty[myKey, $CDHierarchyMarks];
RegisterHierarchyMarker[ReallySetHierarchyMark];
--########################
CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "place hierarchy mark", proc: PutHierachyMarkComm, key: $CDHierarchyMarksPut];
CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "display hierarchy marks top", proc: TDisplayHierarchyMarkComm, key: $CDHierarchyMarksTDisplay];
CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "display hierarchy marks selected", proc: SDisplayHierarchyMarkComm, key: $CDHierarchyMarksSDisplay];
CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "display hierarchy marks all", proc: ADisplayHierarchyMarkComm, key: $CDHierarchyMarksADisplay];
CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "un-display hierarchy marks", proc: RemDisplayHierachyMarkComm, key: $CDHierarchyMarksUnDisplay];
CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "select hierarchy mark", proc: SelectHierachyMarkComm, key: $CDHierarchyMarksSelect];
--########################
END.