CDHierarchyMarksImpl.mesa (part of ChipNDale)
Copyright © 1986, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, July 16, 1986 8:09:57 pm PDT
Last edited by Christian Jacobi, January 29, 1987 6:04:10 pm PST
DIRECTORY
CD,
CDBasics,
CDCells,
CDCommandOps,
CDHierarchyMarks,
CDInstances,
CDOps,
CDProperties,
CDRects,
CDSequencer,
CDViewer,
CDViewHighlight,
RuntimeError USING [UNCAUGHT],
TerminalIO,
ViewerClasses USING [Viewer];
CDHierarchyMarksImpl:
CEDAR
MONITOR
IMPORTS CD, CDInstances, CDBasics, CDCells, CDCommandOps, CDOps, CDProperties, CDRects, CDSequencer, 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 {
CDOps.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: ATOM ← NIL; --$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: CD.DrawRectProc = {};
DontDrawContext: CD.DrawContextProc = {};
DrawChild: CD.DrawProc = {
searchInst: CD.Instance ← NARROW[pr.devicePrivate];
IF searchInst.ob=ob
AND searchInst.trans=trans
THEN {
ig: CD.Instance ← CDInstances.NewInst[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: BOOL ← FALSE;
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[ob: fromInst.ob, 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,
drawContext: DontDrawContext
]];
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.