<> <> <> <> 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: BOOLEAN _ TRUE] 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: ROPE _ NIL; port: RoseTypes.EffectivePort _ cc.realCellStuff.effectivePorts[sl.effectivePortIndex]; how: ROPE _ SELECT 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: BOOLEAN _ TRUE] = 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.