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,
CDCommandOpsExtras2,
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, CDCommandOpsExtras2, 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] = {
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 {
CDProperties.PutProp[design, myKey, inst];
--put it also to the real top level cell
FOR list:
LIST
OF
CD.PushRec ← design.actual, list.rest
WHILE list#
NIL
DO
IF list.first.mightReplace=
NIL
THEN
CDProperties.PutProp[list.first.dummyCell.ob, myKey, inst]
ENDLOOP;
}
ELSE {
--put property to both, the mightReplace and the dummyCell, if it should go on either
FOR list:
LIST
OF
CD.PushRec ← design.actual, list.rest
WHILE list#
NIL
DO
IF list.first.dummyCell.ob=ob
THEN {
CDProperties.PutProp[ob, myKey, inst];
IF list.first.mightReplace=NIL THEN CDProperties.PutProp[design, myKey, inst]
ELSE {
i2 ← CDInstances.DeComposed[inst, list.first.mightReplace.location, list.first.mightReplace.ob.size, list.first.mightReplace.orientation];
CDProperties.PutProp[list.first.mightReplace.ob, myKey, i2];
};
RETURN;
}
ENDLOOP;
FOR list:
LIST
OF
CD.PushRec ← design.actual, list.rest
WHILE list#
NIL
DO
IF list.first.mightReplace#
NIL
AND list.first.mightReplace.ob=ob
THEN {
CDProperties.PutProp[ob, myKey, inst];
i2 ← CDInstances.Composed[inst, list.first.mightReplace.location, list.first.mightReplace.ob.size, list.first.mightReplace.orientation];
CDProperties.PutProp[list.first.dummyCell.ob, myKey, i2];
RETURN;
}
ENDLOOP;
--an ordinary cell; no pushed in state...
CDProperties.PutProp[ob, myKey, inst]
};
};
};
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 ← CDCommandOps.TheInstance[comm, "place the hierarchy mark"];
IF selected#
NIL
THEN {
IF ~CDCells.IsPushedIn[comm.design] THEN SetHierarchyMark[comm.design, NIL, selected]
ELSE SetHierarchyMark[comm.design, comm.design.actual.first.dummyCell.ob, selected];
TDisplayHierarchyMarkComm[comm];
};
};
SelectHierachyMarkComm:
PROC [comm: CDSequencer.Command] = {
Match:
PROC [i1, i2:
CD.Instance]
RETURNS [
BOOL] =
INLINE {
RETURN [i1.ob=i2.ob AND i1.location=i2.location AND i1.orientation=i2.orientation]
};
inst: CD.Instance;
TerminalIO.WriteRope["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.location, mr.ob.size, mr.orientation];
}
ELSE inst ← GetHierarchyMark[comm.design, NIL];
IF inst=NIL THEN TerminalIO.WriteRope["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;
CDOps.RedrawInstance[comm.design, il.first, FALSE];
};
ENDLOOP;
};
};
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, position: [-d, -d]];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [-d, mark.y2-mark.y1]];
lineOb ← CDRects.CreateRect[size: [d, mark.y2-mark.y1], l: CD.shadeLayer];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [-d, 0]];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [mark.x2-mark.x1, 0]];
[] ← CDCells.RepositionCell[mOb, NIL];
[] ← CDCells.IncludeOb[cell: highlightInst.ob, ob: mOb, position: 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, pos:
CD.Position, orient:
CD.Orientation, pr:
REF
CD.DrawInformation] = {
searchInst: CD.Instance ← NARROW[pr.devicePrivate];
IF searchInst.ob=inst.ob
AND searchInst.location=pos
AND searchInst.orientation=orient
THEN {
ig: CD.Instance ← CDInstances.NewInst[inst.ob, pos, orient];
SIGNAL foundAndStop [ig]
};
};
DisplayHierarchyMarks:
PROC [design:
CD.Design, il:
CD.InstanceList, viewerHint:
REF] = {
highlightInst: CD.Instance ← NIL;
GoDown:
PROC [fromInst:
CD.Instance] = {
--fromInst in global world coordinate system
foundInst, markInst: CD.Instance ← NIL; 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.location, fromInst.ob.size, fromInst.orientation];
fromInst.ob.class.drawMe[inst: fromInst, pos: fromInst.location, orient: fromInst.orientation, pr: pr !
foundAndStop => {
IF foundInst=NIL THEN {foundInst ← ig; RESUME}
ELSE {multiple ← TRUE; CONTINUE}
}
];
IF foundInst#
NIL
THEN {
IF multiple THEN TerminalIO.WriteRopes["****multiple hierarchymarks in ", CDCommandOps.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.WriteRope["no hierarchy marks set\n"]
ELSE {
[] ← CDCells.RepositionCell[highlightInst.ob, NIL];
highlightInst.location ← CDBasics.NegOffset[CD.ClientOrigin[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];
--########################
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Place hierarchy mark", proc: PutHierachyMarkComm, key: $CDHierarchyMarksPut];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Display hierarchy marks top", proc: TDisplayHierarchyMarkComm, key: $CDHierarchyMarksTDisplay];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Display hierarchy marks selected", proc: SDisplayHierarchyMarkComm, key: $CDHierarchyMarksSDisplay];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Display hierarchy marks all", proc: ADisplayHierarchyMarkComm, key: $CDHierarchyMarksADisplay];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Un-display hierarchy marks", proc: RemDisplayHierachyMarkComm, key: $CDHierarchyMarksUnDisplay];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Select hierarchy mark", proc: SelectHierachyMarkComm, key: $CDHierarchyMarksSelect];
--########################
END.