RoseDisplayBrowsing.Mesa
Last Edited by: Spreitzer, September 4, 1985 0:20:46 am PDT
Last Edited by: Barth, April 23, 1984 5:39:57 pm PST
Last Edited by: Gasbarro, August 16, 1984 4:15:14 pm PDT
DIRECTORY Asserting, Atom, Buttons, Graphs, GraphBrowsers, HierarchicalDisplays, IO, Labels, Menus, MessageWindow, RedBlackTree, Rope, RoseConditions, RoseDisplayInsides, RoseEvents, RoseTypes, Trees, VFonts, ViewerClasses, ViewerOps, ViewerTools, ViewRec;
RoseDisplayBrowsing: CEDAR PROGRAM
IMPORTS Asserting, Atom, Graphs, GraphBrowsers, HD: HierarchicalDisplays, Labels, MessageWindow, RedBlackTree, Rope, RoseDisplayInsides, RoseEvents, RoseTypes, VF:VFonts, VO: ViewerOps, VR: ViewRec
EXPORTS RoseDisplayInsides =
BEGIN OPEN RoseDisplayInsides;
nodeDisplaysProp: PUBLIC ATOM ← Atom.MakeAtom["Spreitzer January 6, 1984 9:24 pm"];
cellStateDisplayProp: PUBLIC ATOM ← Atom.MakeAtom["January 6, 1984 9:24 pm Spreitzer"];
typeDataDisplayProp: PUBLIC ATOM ← Atom.MakeAtom["January 19, 1985 1:43:43 pm PST Spreitzer"];
cellStateClass: PUBLIC HD.ChildClass ← NEW [HD.ChildClassRep ← [
buttonProc: CellStateButtonProc,
NotifyOnRemove: NoticeCellStateRemoval]];
typeDataClass: PUBLIC HD.ChildClass ← NEW [HD.ChildClassRep ← [
buttonProc: TypeDataButtonProc,
NotifyOnRemove: NoticeTypeDataRemoval]];
roseType: Graphs.VertexType ← Graphs.NewVertexType[[
Expand: RoseExpand,
GetNeighborCount: RoseNeighborCount]];
rosemaryBrowser: GraphBrowsers.BrowserClass ←
NEW [GraphBrowsers.BrowserClassRep ← [
cmds: [
[
FALSE: GraphBrowsers.basicBrowserClass.cmds[red][FALSE],
TRUE: ALL[[BrowserClick]]
],
ALL[ALL[[BrowserClick]]],
ALL[ALL[[BrowserClick]]]] ]];
BrowseDisplay: PUBLIC PROC [display: Display, info: ViewerClasses.ViewerRec ← [], paint: BOOLEANTRUE] RETURNS [v: Viewer] =
BEGIN
IF info.name = NIL THEN info.name ← display.rootCell.name.Cat[".Browser"];
v ← GraphBrowsers.Browse[vertex: CellNode[display.rootCell, display], browserClass: rosemaryBrowser, browserData: display, viewerInit: info, paint: paint].BrowserQuaViewer[];
END;
CellNode: PROC [cell: Cell, display: Display] RETURNS [node: Graphs.Vertex] =
{node ← NEW [Graphs.VertexRep ← [type: roseType, rep: NEW [CellBrowserRep ← [cell, display]]]]};
StateNode: PROC [cb: CellBrowser] RETURNS [node: Graphs.Vertex] =
{node ← NEW [Graphs.VertexRep ← [type: roseType, rep: NEW [CellStateRep ← [cb]]]]};
InterfaceNode: PROC [cb: CellBrowser] RETURNS [node: Graphs.Vertex] =
{node ← NEW [Graphs.VertexRep ← [type: roseType, rep: NEW [InterfaceNodesRep ← [cb]]]]};
InternalNode: PROC [cb: CellBrowser] RETURNS [node: Graphs.Vertex] =
{node ← NEW [Graphs.VertexRep ← [type: roseType, rep: NEW [InternalNodesRep ← [cb]]]]};
ComponentsNode: PROC [cb: CellBrowser] RETURNS [node: Graphs.Vertex] =
{node ← NEW [Graphs.VertexRep ← [type: roseType, rep: NEW [ComponentsRep ← [cb]]]]};
NodeNode: PROC [ne: NodeElt] RETURNS [node: Graphs.Vertex] =
{node ← NEW [Graphs.VertexRep ← [type: roseType, rep: ne]]};
EffectiveInterfaceNode: PROC [cb: CellBrowser] RETURNS [node: Graphs.Vertex] =
{node ← NEW [Graphs.VertexRep ← [type: roseType, rep: NEW [EffectiveInterfaceRep ← [cb]]]]};
RoseNeighborCount: PROC [node: Graphs.Vertex] RETURNS [neighborCount: INT] --Graphs.NeighborCountProc-- =
BEGIN
neighborCount ← WITH node.rep SELECT FROM
cb: CellBrowser => 5,
in: InterfaceNodes => in.cb1.cell.type.ports.length,
in: InternalNodes => in.cb2.cell.internalNodes.Size[],
ei: EffectiveInterface => ei.cb4.cell.realCellStuff.implNodes.length,
components: Components => components.cb3.cell.components.Size[],
cs: CellState => 0,
ne: NodeElt => CountLinksFromNode[ne.node],
ENDCASE => ERROR;
END;
CountLinksFromNode: SAFE PROC [node: Node] RETURNS [count: INT] =
BEGIN
count ← 0;
SELECT node.significances[inImpl] FROM
TRUE => SELECT node.type.simple FROM
TRUE => FOR str: Strength IN Strength DO
FOR s: RoseTypes.Slot ← node.byStrength[str].first, s.cell.realCellStuff.effectivePorts[s.effectivePortIndex].strengthNext WHILE s # RoseTypes.head DO
count ← count + 1;
ENDLOOP;
ENDLOOP;
FALSE => FOR sl: RoseTypes.SlotList ← node.switchConnections, sl.rest WHILE sl # NIL DO
count ← count + 1;
ENDLOOP;
ENDCASE => ERROR;
FALSE => FOR pl: RoseTypes.PieceList ← node.childPieces, pl.rest WHILE pl # NIL DO count ← count + 1 ENDLOOP;
ENDCASE => ERROR;
END;
RoseExpand: PROC [vertex: Graphs.Vertex, consume: Graphs.EdgeConsumer] --Graphs.ExpandProc-- =
BEGIN
WITH vertex.rep SELECT FROM
cb: CellBrowser => EnumerateCell[cb, consume];
in: InterfaceNodes => EnumerateInterfaceNodes[in, consume];
in: InternalNodes => EnumerateInternalNodes[in, consume];
ei: EffectiveInterface => EnumerateEffectiveInterfaceNodes[ei, consume];
components: Components => EnumerateComponents[components, consume];
cs: CellState => NULL;
ne: NodeElt => EnumerateFromNode[ne, consume];
ENDCASE => ERROR;
END;
EnumerateFromNode: PROC [ne: NodeElt, to: Graphs.EdgeConsumer] =
BEGIN
node: Node ← ne.node;
Do: PROC [sl: RoseTypes.Slot] =
BEGIN
cc: Cell ← sl.cell;
cellName: ROPENIL;
port: RoseTypes.EffectivePort ← cc.realCellStuff.effectivePorts[sl.effectivePortIndex];
how: ROPESELECT TRUE FROM
port.input AND port.output => "=",
port.input => ">",
port.output => "<",
ENDCASE => ERROR;
WHILE cc # ne.node.cellIn DO
IF cellName # NIL THEN cellName ← Rope.Concat[".", cellName];
cellName ← cc.name.Concat[cellName];
cc ← cc.parent;
ENDLOOP;
to.proc[[
label: Rope.Cat[sl.cell.realCellStuff.effectivePorts[sl.effectivePortIndex].name, how, cellName],
otherSide: CellNode[cell: sl.cell, display: ne.org.display]], to.data];
END;
SELECT node.significances[inImpl] FROM
TRUE => SELECT node.type.simple FROM
TRUE => FOR str: Strength IN Strength DO
FOR s: RoseTypes.Slot ← node.byStrength[str].first, s.cell.realCellStuff.effectivePorts[s.effectivePortIndex].strengthNext WHILE s # RoseTypes.head DO
Do[s];
ENDLOOP;
ENDLOOP;
FALSE => FOR sl: RoseTypes.SlotList ← node.switchConnections, sl.rest WHILE sl # NIL DO
Do[sl.first];
ENDLOOP;
ENDCASE => ERROR;
FALSE => FOR pl: RoseTypes.PieceList ← node.childPieces, pl.rest WHILE pl # NIL DO
mod: ROPE ← pl.first.reln.SelectorToRope[];
in: Node ← pl.first.twardImpl;
one: NodeElt ← NEW [NodeEltRep ← [
name: in.name,
node: in,
org: [display: ne.org.display, circ: [cell: in.cellIn, role: internal]],
parent: NEW [CellBrowserRep ← [in.cellIn, ne.org.display]],
format: in.type.procs.GetFormat[in.type, ""]
]];
to.proc[
[label: mod, otherSide: NodeNode[one]],
to.data];
ENDLOOP;
ENDCASE => ERROR;
END;
EnumerateCell: PROC [cb: CellBrowser, to: Graphs.EdgeConsumer, interf, intern: BOOLEANTRUE] =
BEGIN
canInterf: BOOLEAN ← cb.cell.interfaceNodes.length > 0;
canIntern: BOOLEAN ← cb.cell.internalNodes.Size[] > 0;
canBoth: BOOLEAN ← canInterf AND canIntern;
interf ← interf OR NOT canBoth;
intern ← intern OR NOT canBoth;
IF canInterf AND interf THEN to.proc[["Interface Nodes", InterfaceNode[cb]], to.data];
IF canIntern AND intern THEN to.proc[["Internal Nodes", InternalNode[cb]], to.data];
IF cb.cell.components.Size[] > 0 THEN to.proc[["Components", ComponentsNode[cb]], to.data];
IF (IF cb.cell.realCellStuff = NIL THEN FALSE ELSE cb.cell.realCellStuff.state # NIL) THEN to.proc[["State", StateNode[cb]], to.data];
IF cb.cell.substantiality = Real THEN to.proc[["EffectiveInterface", EffectiveInterfaceNode[cb]], to.data];
END;
EnumerateInterfaceNodes: PROC [in: InterfaceNodes, to: Graphs.EdgeConsumer] =
BEGIN
FOR ni: PortIndex IN [0 .. in.cb1.cell.type.ports.length) DO
port: RoseTypes.Port ← in.cb1.cell.type.ports[ni];
node: Node ← in.cb1.cell.interfaceNodes[ni];
ne: NodeElt ← NEW [NodeEltRep ← [
name: port.name,
node: node,
org: [display: in.cb1.display, circ: [cell: in.cb1.cell, role: interface, index: ni]],
parent: in.cb1,
format: node.type.procs.GetFormat[node.type, ""],
interfaceIndex: ni,
interfaceNode: TRUE
]];
IF ne.format = NIL THEN ERROR --type should supply default keyed by empty string--;
to.proc[[PortLinkName[port.name, node.name], NodeNode[ne]], to.data];
ENDLOOP;
END;
EnumerateEffectiveInterfaceNodes: PROC [ei: EffectiveInterface, to: Graphs.EdgeConsumer] =
BEGIN
cell: Cell ← ei.cb4.cell;
FOR epi: RoseTypes.EffectivePortIndex IN [0 .. cell.realCellStuff.effectivePorts.length) DO
port: RoseTypes.EffectivePort ← cell.realCellStuff.effectivePorts[epi];
node: Node ← cell.realCellStuff.implNodes[epi];
ne: NodeElt ← NEW [NodeEltRep ← [
name: port.name,
node: node,
org: [display: ei.cb4.display, circ: [cell: cell, role: effectiveInterface, index: epi]],
parent: ei.cb4,
format: node.type.procs.GetFormat[node.type, ""],
effectiveInterfaceIndex: epi,
effectiveInterfaceNode: TRUE
]];
IF ne.format = NIL THEN ERROR --type should supply default keyed by empty string--;
to.proc[[PortLinkName[port.name, node.name], NodeNode[ne]], to.data];
ENDLOOP;
END;
PortLinkName: PROC [portName, nodeName: ROPE] RETURNS [linkName: ROPE] =
BEGIN
linkName ← IF portName.Equal[nodeName] THEN portName ELSE portName.Cat[": ", nodeName];
END;
EnumerateInternalNodes: PROC [in: InternalNodes, to: Graphs.EdgeConsumer] =
BEGIN
FOR node: Node ← in.cb2.cell.firstInternalNode, node.designNext WHILE node # NIL DO
ne: NodeElt ← NEW [NodeEltRep ← [
node: node,
name: node.name,
org: [display: in.cb2.display, circ: [cell: in.cb2.cell, role: internal]],
parent: in.cb2,
format: node.type.procs.GetFormat[node.type, ""]
]];
IF ne.format = NIL THEN ERROR;
to.proc[[node.name, NodeNode[ne]], to.data];
ENDLOOP;
END;
EnumerateComponents: PROC [components: Components, to: Graphs.EdgeConsumer] =
BEGIN
FOR cell: Cell ← components.cb3.cell.leftChild, cell.rightSibling WHILE cell # NIL DO
to.proc[[cell.name, CellNode[cell: cell, display: components.cb3.display]], to.data];
ENDLOOP;
END;
NDLSearch: PUBLIC PROC [ndl: NodeDisplayList, org: NodeOrigin, remove: BOOLEAN] RETURNS [newdl: NodeDisplayList, nd: NodeDisplay, found: BOOLEAN] =
BEGIN
prev: NodeDisplayList ← NIL;
newdl ← ndl; found ← FALSE;
FOR ndl ← ndl, ndl.rest WHILE ndl # NIL DO
IF ndl.first.org = org THEN
BEGIN
IF found THEN ERROR ELSE found ← TRUE;
nd ← ndl.first;
IF remove THEN
{IF prev = NIL THEN newdl ← ndl.rest ELSE prev.rest ← ndl.rest};
RETURN;
END;
prev ← ndl;
ENDLOOP;
END;
whatToDo: ARRAY Menus.MouseButton[red .. blue] OF ARRAY BOOL--ctl-- OF ARRAY BOOL--shift-- OF Graphs.EdgeConsumerProc ← ALL[ALL[ALL[NIL]]];
BrowserClick: GraphBrowsers.BrowserCmdProc--PROC [pane: Pane, index: CARDINAL- -origin 0- -, cmdData, browserData: REF ANY, button: Menus.MouseButton, ctl, shift, paint: BOOLEAN]-- =
BEGIN
n: Graphs.Vertex ← GraphBrowsers.GetPaneVertex[pane];
d: Display ← GetDisplay[n];
d.mucking ← d.mucking + 1;
{ENABLE UNWIND => d.mucking ← d.mucking - 1;
whatToDo[button][ctl][shift][
[pane.GetChildName[index], pane.GetChildVertex[index]],
NIL];
};
d.mucking ← d.mucking - 1;
END;
GetDisplay: PROC [n: Graphs.Vertex] RETURNS [d: Display] = {
d ← WITH n.rep SELECT FROM
cb: CellBrowser => cb.display,
cs: CellState => cs.cb0.display,
in: InterfaceNodes => in.cb1.display,
in: InternalNodes => in.cb2.display,
ei: EffectiveInterface => ei.cb4.display,
c: Components => c.cb3.display,
ne: NodeElt => ne.org.display,
ENDCASE => ERROR};
LogSwitchery: Graphs.EdgeConsumerProc =
BEGIN
WITH edge.otherSide.rep SELECT FROM
ne: NodeElt => {
RoseEvents.RemoveWatcher[event: $NewNodeQ, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.AddWatcher[event: $NewNodeQ, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.RemoveWatcher[event: $NewNodeUD, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.AddWatcher[event: $NewNodeUD, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.RemoveWatcher[event: $Perturbed, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.AddWatcher[event: $Perturbed, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.RemoveWatcher[event: $Found, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.AddWatcher[event: $Found, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.RemoveWatcher[event: $ChangeEarly, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.AddWatcher[event: $ChangeEarly, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
};
cs: CellState => NULL;
cb: CellBrowser => NULL;
in: InterfaceNodes => NULL;
in: InternalNodes => NULL;
components: Components => NULL;
ENDCASE => ERROR;
END;
DontLogSwitchery: Graphs.EdgeConsumerProc =
BEGIN
WITH edge.otherSide.rep SELECT FROM
ne: NodeElt => {
RoseEvents.RemoveWatcher[event: $NewNodeQ, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.RemoveWatcher[event: $NewNodeUD, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.RemoveWatcher[event: $Perturbed, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.RemoveWatcher[event: $Found, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
RoseEvents.RemoveWatcher[event: $ChangeEarly, watcher: [NotifyActivity, ne.org.display], watched: ne.node];
};
cs: CellState => NULL;
cb: CellBrowser => NULL;
in: InterfaceNodes => NULL;
in: InternalNodes => NULL;
components: Components => NULL;
ENDCASE => ERROR;
END;
DisplayAllButState: Graphs.EdgeConsumerProc =
BEGIN
WITH edge.otherSide.rep SELECT FROM
ne: NodeElt => DisplayNode[ne, FALSE];
cs: CellState => NULL;
cb: CellBrowser => EnumerateCell[cb: cb, to: [DisplayAllButState], interf: FALSE];
in: InterfaceNodes => EnumerateInterfaceNodes[in, [DisplayAllButState]];
in: InternalNodes => EnumerateInternalNodes[in, [DisplayAllButState]];
ei: EffectiveInterface => NULL;
components: Components => EnumerateComponents[components, [DisplayAllButState]];
ENDCASE => ERROR;
END;
UnDisplayAll: Graphs.EdgeConsumerProc =
BEGIN
WITH edge.otherSide.rep SELECT FROM
ne: NodeElt => UnDisplayNode[ne, FALSE];
cs: CellState => UnDisplayCellState[cs];
cb: CellBrowser => UnDisplayCell[cb];
in: InterfaceNodes => EnumerateInterfaceNodes[in, [UnDisplayAll]];
in: InternalNodes => EnumerateInternalNodes[in, [UnDisplayAll]];
ei: EffectiveInterface => EnumerateEffectiveInterfaceNodes[ei, [UnDisplayAll]];
components: Components => EnumerateComponents[components, [UnDisplayAll]];
ENDCASE => ERROR;
END;
DisplayAllState: Graphs.EdgeConsumerProc =
BEGIN
WITH edge.otherSide.rep SELECT FROM
ne: NodeElt => NULL;
cs: CellState => DisplayCellState[cs];
cb: CellBrowser => EnumerateCell[cb: cb, to: [DisplayAllState], interf: FALSE];
in: InterfaceNodes => NULL;
in: InternalNodes => NULL;
ei: EffectiveInterface => NULL;
components: Components => EnumerateComponents[components, [DisplayAllState]];
ENDCASE => ERROR;
END;
UnDisplayAllState: Graphs.EdgeConsumerProc =
BEGIN
WITH edge.otherSide.rep SELECT FROM
ne: NodeElt => NULL;
cs: CellState => UnDisplayCellState[cs];
cb: CellBrowser => EnumerateCell[cb: cb, to: [UnDisplayAllState], interf: FALSE];
in: InterfaceNodes => NULL;
in: InternalNodes => NULL;
ei: EffectiveInterface => NULL;
components: Components => EnumerateComponents[components, [UnDisplayAllState]];
ENDCASE => ERROR;
END;
DisplayCellState: PROC [cs: CellState] =
BEGIN
Do: PROC [class: HD.ChildClass, key: ATOM, name: ROPE, val: REF ANY] = {
dl: HD.Leaf ← NARROW[Asserting.FnVal[fn: key, from: cs.cb0.cell.other]];
IF val = NIL THEN RETURN;
IF dl = NIL THEN
BEGIN
CreateValue: PROC [leaf: HD.Leaf] RETURNS [value: Viewer] --ValueCreater-- =
BEGIN
value ← VR.ViewRef[
agg: val,
viewerInit: [
parent: leaf.container,
wx: 10,
wy: leaf.nameButton.wy + leaf.nameButton.wh + 2,
ww: MAX[100, leaf.container.cw - 10],
wh: VF.FontHeight[] + 5,
iconic: FALSE,
border: TRUE,
scrollable: FALSE],
createOptions: [mayInitiateRelayout: FALSE, feedBackHeight: 0],
parent: cs.cb0.display.rv,
paint: FALSE
!VR.NotAnAggregate => {
value ← Labels.Create[
info: [
name: "!Not an aggregate!",
parent: leaf.container,
wx: 10,
wy: leaf.nameButton.wy + leaf.nameButton.wh + 2]
];
CONTINUE;
}]
.RVQuaViewer[];
END;
dp: HD.Parent ← EnsureDisplay[cs.cb0];
dl ← HD.AddLeaf[parent: dp, before: NextCellChild[cs.cb0.display, cs.cb0.cell.leftChild], name: name, class: class, instanceData: cs, CreateValue: CreateValue];
cs.cb0.cell.other ← Asserting.AssertFn1[fn: key, val: dl, inAdditionTo: cs.cb0.cell.other];
END;
};
Do[cellStateClass, cellStateDisplayProp, "state:", cs.cb0.cell.realCellStuff.state];
Do[typeDataClass, typeDataDisplayProp, "typeData:", cs.cb0.cell.type.typeData];
END;
UnDisplayCellState: PROC [cs: CellState] =
BEGIN
Do: PROC [key: ATOM] = {
dl: HD.Leaf ← NARROW[Asserting.FnVal[fn: key, from: cs.cb0.cell.other]];
IF dl # NIL THEN HD.Remove[dl];
};
Do[cellStateDisplayProp];
Do[typeDataDisplayProp];
END;
NoticeCellStateRemoval: PROC [child: HD.Child] -- ChildNotifyProc-- =
BEGIN
cs: CellState ← NARROW[child.instanceData];
cs.cb0.cell.other ← Asserting.AssertFn1[fn: cellStateDisplayProp, val: NIL, inAdditionTo: cs.cb0.cell.other];
END;
CellStateButtonProc: Buttons.ButtonProc =
BEGIN
MessageWindow.Append[message: "Don't do that", clearFirst: TRUE];
END;
NoticeTypeDataRemoval: PROC [child: HD.Child] -- ChildNotifyProc-- =
BEGIN
cs: CellState ← NARROW[child.instanceData];
cs.cb0.cell.other ← Asserting.AssertFn1[fn: typeDataDisplayProp, val: NIL, inAdditionTo: cs.cb0.cell.other];
END;
TypeDataButtonProc: Buttons.ButtonProc =
BEGIN
MessageWindow.Append[message: "Don't do that", clearFirst: TRUE];
END;
UnDisplayNode: PROC [ne: NodeElt, noisy: BOOLEAN] =
BEGIN
displays: NodeDisplayList ← NARROW[Asserting.FnVal[fn: nodeDisplaysProp, from: ne.node.other]];
nd: NodeDisplay;
found: BOOLEAN;
[displays, nd, found] ← NDLSearch[ndl: displays, org: ne.org, remove: FALSE];
IF NOT found THEN
{IF noisy THEN ne.org.display.rv.DisplayMessage[msg: "not displayed!"]}
ELSE BEGIN
HD.Remove[nd.dc];
IF noisy THEN ne.org.display.rv.DisplayMessage[msg: "ok"];
END;
END;
EnsureInterfaceIndex: PROC [ne: NodeElt] = {
IF ne.interfaceIndex = notLookedFor THEN ne.interfaceIndex ← IF ne.org.circ.cell # NIL THEN RoseTypes.GetIndex[ne.org.circ.cell.type.ports, ne.name] ELSE notFound;
IF ne.effectiveInterfaceIndex = notLookedFor THEN ne.effectiveInterfaceIndex ← IF ne.org.circ.cell # NIL AND ne.org.circ.cell.substantiality = Real THEN RoseTypes.GetIndex[ne.org.circ.cell.realCellStuff.effectivePorts, ne.name] ELSE notFound;
};
DisplayNode: PROC [ne: NodeElt, noisy: BOOLEAN] =
BEGIN
displays: NodeDisplayList ← NARROW[Asserting.FnVal[fn: nodeDisplaysProp, from: ne.node.other]];
nd: NodeDisplay;
found: BOOLEAN;
[, nd, found] ← NDLSearch[ndl: displays, org: ne.org, remove: FALSE];
IF found THEN
{IF noisy THEN ne.org.display.rv.DisplayMessage[msg: "already displayed!"]}
ELSE IF TRUE THEN BEGIN
CreateValue: HD.ValueCreater =
BEGIN
value ← VO.CreateViewer[flavor: $Text, paint: FALSE,
info: [parent: leaf.container,
data: FormatNE[ne],
wx: leaf.nameButton.wx + leaf.nameButton.ww + 2,
ww: ne.format.MaxWidth[ne.node.type, ne.format, VF.defaultFont] + 20,
wh: VF.FontHeight[] + 5,
iconic: FALSE,
border: FALSE,
scrollable: FALSE]];
VO.AddProp[viewer: value, prop: leafProp, val: leaf];
END;
dp: HD.Parent ← EnsureDisplay[ne.parent];
dc: HD.Leaf;
name: ROPE ← ne.name;
IF NOT (ne.interfaceNode OR ne.effectiveInterfaceNode) THEN name ← name.Concat[":"];
EnsureInterfaceIndex[ne];
IF ne.interfaceIndex # notFound THEN
BEGIN
name ← name.Concat[SELECT (IF ne.org.circ.cell.type.ports[ne.interfaceIndex].input THEN 1 ELSE 0) + (IF ne.org.circ.cell.type.ports[ne.interfaceIndex].output THEN 2 ELSE 0) FROM 1 => "<", 2 => ">", 3 => "=", ENDCASE => ERROR];
END
ELSE IF ne.effectiveInterfaceIndex # notFound THEN
BEGIN
name ← name.Concat[SELECT (IF ne.org.circ.cell.realCellStuff.effectivePorts[ne.effectiveInterfaceIndex].input THEN 1 ELSE 0) + (IF ne.org.circ.cell.realCellStuff.effectivePorts[ne.effectiveInterfaceIndex].output THEN 2 ELSE 0) FROM 1 => "<", 2 => ">", 3 => "=", ENDCASE => ERROR];
END;
dc ← HD.AddLeaf[parent: dp, before: NextNodeChild[ne], name: name, class: nodeClass, instanceData: ne, CreateValue: CreateValue];
displays ← CONS[[ne.org, dc], displays];
ne.node.other ← Asserting.AssertFn1[fn: nodeDisplaysProp, val: displays, inAdditionTo: ne.node.other];
RoseEvents.AddWatcher[watched: ne.node, watcher: [NotifyNodeView, dc], event: $ChangeEarly];
IF noisy THEN ne.org.display.rv.DisplayMessage[msg: "ok"];
END
ELSE ne.org.display.rv.DisplayMessage[ne.name.Cat[" can't be displayed"]];
END;
NextNodeChild: PROC [ne: NodeElt] RETURNS [child: HD.Child] =
BEGIN
Displayed: PROC [node: Node] RETURNS [BOOLEAN] =
BEGIN
displays: NodeDisplayList ← NARROW[Asserting.FnVal[fn: nodeDisplaysProp, from: node.other]];
nd: NodeDisplay;
found: BOOLEAN;
[, nd, found] ← NDLSearch[ndl: displays, org: ne.org, remove: FALSE];
IF found THEN child ← nd.dc;
RETURN [found];
END;
node: Node ← IF ne.node.significances[fromDesign] THEN ne.node.designNext ELSE NIL;
IF ne.interfaceNode THEN
BEGIN
FOR c: PortIndex IN (ne.interfaceIndex .. ne.org.circ.cell.interfaceNodes.length) DO
IF Displayed[ne.org.circ.cell.interfaceNodes[c]] THEN RETURN;
ENDLOOP;
node ← ne.org.circ.cell.firstInternalNode;
END
ELSE IF ne.effectiveInterfaceNode THEN
BEGIN
FOR c: RoseTypes.EffectivePortIndex IN (ne.effectiveInterfaceIndex .. ne.org.circ.cell.realCellStuff.implNodes.length) DO
IF Displayed[ne.org.circ.cell.realCellStuff.implNodes[c]] THEN RETURN;
ENDLOOP;
node ← ne.org.circ.cell.firstInternalNode;
END;
FOR node ← node, node.designNext WHILE node # NIL DO
IF Displayed[node] THEN RETURN ENDLOOP;
child ← NARROW[Asserting.FnVal[fn: cellStateDisplayProp, from: ne.org.circ.cell.other]];
IF child # NIL THEN RETURN;
child ← NextCellChild[ne.org.display, ne.org.circ.cell.leftChild];
END;
UnDisplayCell: PROC [cb: CellBrowser] =
BEGIN
dpAsAny: REF ANY ← Asserting.FnVal[from: cb.cell.other, fn: cb.display];
IF dpAsAny # NIL THEN
BEGIN
dp: HD.Parent ← NARROW[dpAsAny];
IF dp.asChild # NIL THEN
BEGIN
HD.Remove[dp.asChild];
END;
END;
END;
NextCellChild: PROC [display: Display, start: Cell] RETURNS [child: HD.Child] =
BEGIN
FOR cell: Cell ← start, cell.rightSibling WHILE cell # NIL DO
nextDPAsAny: REF ANY ← Asserting.FnVal[from: cell.other, fn: display];
IF nextDPAsAny # NIL THEN
{child ← NARROW[nextDPAsAny, HD.Parent].asChild; EXIT};
ENDLOOP;
END;
EnsureDisplay: PROC [cb: CellBrowser] RETURNS [dp: HD.Parent] =
BEGIN
dpAsAny: REF ANY ← Asserting.FnVal[from: cb.cell.other, fn: cb.display];
IF dpAsAny = NIL THEN
BEGIN
pdp: HD.Parent ← IF cb.cell.parent = NIL THEN cb.display.rootDisplay ELSE EnsureDisplay[NEW [CellBrowserRep ← [cb.cell.parent, cb.display]]];
dc: HD.Child;
dp ← (dc ← HD.AddInternalNode[parent: pdp, before: NextCellChild[cb.display, cb.cell.rightSibling], name: cb.cell.name.Cat[": "], class: cellClass, instanceData: cb]).asParent;
cb.cell.other ← Asserting.AssertFn1[fn: cb.display, val: dp, inAdditionTo: cb.cell.other];
IF cb.cell.substantiality = Real THEN
BEGIN
RoseEvents.AddWatcher[$Schedule, [NotifyCellView, dc], cb.cell];
NotifyCellView[$Schedule, cb.cell, dc, NIL];
END;
END
ELSE dp ← NARROW[dpAsAny];
END;
Setup: PROC =
BEGIN
whatToDo[red] ← ALL[ALL[HighlightNode]];
whatToDo[yellow][FALSE][FALSE] ← DisplayAllButState;
whatToDo[yellow][FALSE][TRUE] ← UnDisplayAll;
whatToDo[blue][FALSE][FALSE] ← DisplayAllState;
whatToDo[blue][FALSE][TRUE] ← UnDisplayAllState;
whatToDo[yellow][TRUE][FALSE] ← DisplayAllButState;
whatToDo[yellow][TRUE][TRUE] ← UnDisplayAll;
whatToDo[blue][TRUE][FALSE] ← LogSwitchery;
whatToDo[blue][TRUE][TRUE] ← DontLogSwitchery;
END;
Setup[];
END.