RoseDisplayBrowsing.Mesa
Last Edited by: Spreitzer, July 18, 1983 9:23 pm
DIRECTORY
Atom, Buttons, Graphs, GraphBrowsers, HierarchicalDisplays, IO, List, Menus, MessageWindow, OrderedSymbolTableRef, Rope, Rosemary, RoseConditions, RoseDisplayInsides, Trees, VFonts, ViewerClasses, ViewerOps, ViewerTools, ViewRec;
RoseDisplayBrowsing:
PROGRAM
IMPORTS Atom, GraphBrowsers, HD: HierarchicalDisplays, List, OrderedSymbolTableRef, MessageWindow, Rope, Rosemary, RoseDisplayInsides, VF:VFonts, VO: ViewerOps, VR: ViewRec
EXPORTS RoseDisplayInsides =
BEGIN OPEN RoseDisplayInsides;
nodeDisplaysProp: PUBLIC ATOM ← Atom.Gensym[];
cellStateDisplayProp: PUBLIC ATOM ← Atom.Gensym[];
cellStateClass:
PUBLIC
HD.ChildClass ←
NEW [
HD.ChildClassRep ← [
buttonProc: CellStateButtonProc,
NotifyOnRemove: NoticeCellStateRemoval]];
roseType: Graphs.NodeType ←
NEW [Graphs.NodeTypeRep ← [
Expand: RoseExpand,
NameNeighbors: NIL,
GetNamedNeighbor: NIL,
GetIndexedNeighbor: NIL,
GetNeighborCount: RoseNeighborCount,
View: NIL]];
rosemaryBrowser: GraphBrowsers.BrowserClass ←
NEW [GraphBrowsers.BrowserClassRep ← [
cmds: [
GraphBrowsers.basicBrowserClass.cmds[red],
ALL[ALL[[BrowserClick]]],
ALL[ALL[[BrowserClick]]]] ]];
BrowseDisplay:
PROC [display: Display, info: ViewerClasses.ViewerRec ← [], paint:
BOOLEAN ←
TRUE]
RETURNS [v: ViewerClasses.Viewer] =
BEGIN
v ← GraphBrowsers.Browse[node: CellNode[display.rootCell, display, NIL], browserClass: rosemaryBrowser, browserData: display, viewerInit: info, paint: paint].BrowserQuaViewer[];
END;
CellNode:
PROC [cell: Cell, display: Display, parent: CellBrowser]
RETURNS [node: Graphs.Node] =
{node ← NEW [Graphs.NodeRep ← [type: roseType, rep: NEW [CellBrowserRep ← [cell, display, parent]]]]};
StateNode:
PROC [cb: CellBrowser]
RETURNS [node: Graphs.Node] =
{node ← NEW [Graphs.NodeRep ← [type: roseType, rep: NEW [CellStateRep ← [cb]]]]};
InterfaceNode:
PROC [cb: CellBrowser]
RETURNS [node: Graphs.Node] =
{node ← NEW [Graphs.NodeRep ← [type: roseType, rep: NEW [InterfaceNodesRep ← [cb]]]]};
InternalNode:
PROC [cb: CellBrowser]
RETURNS [node: Graphs.Node] =
{node ← NEW [Graphs.NodeRep ← [type: roseType, rep: NEW [InternalNodesRep ← [cb]]]]};
ComponentsNode:
PROC [cb: CellBrowser]
RETURNS [node: Graphs.Node] =
{node ← NEW [Graphs.NodeRep ← [type: roseType, rep: NEW [ComponentsRep ← [cb]]]]};
NodeNode:
PROC [ne: NodeElt]
RETURNS [node: Graphs.Node] =
{node ← NEW [Graphs.NodeRep ← [type: roseType, rep: ne]]};
RoseNeighborCount: Graphs.NeighborCountProc
--PROC [node: Node] RETURNS [neighborCount: INT]-- =
CHECKED
BEGIN
WITH node.rep
SELECT
FROM
cb: CellBrowser => RETURN[4];
in: InterfaceNodes => RETURN[in.cb1.cell.class.ports.length];
in: InternalNodes => RETURN[in.cb2.cell.internalNodes.Size[]];
components: Components => RETURN[components.cb3.cell.components.Size[]];
cs: CellState => RETURN [0];
ne: NodeElt => RETURN [0];
ENDCASE => ERROR;
END;
RoseExpand: Graphs.ExpandProc
--PROC [node: Node, consume: LinkConsumer]-- =
TRUSTED
BEGIN
WITH node.rep
SELECT
FROM
cb: CellBrowser => EnumerateCell[cb, consume];
in: InterfaceNodes => EnumerateInterfaceNodes[in, consume];
in: InternalNodes => EnumerateInternalNodes[in, consume];
components: Components => EnumerateComponents[components, consume];
cs: CellState => NULL;
ne: NodeElt => NULL;
ENDCASE => ERROR;
END;
EnumerateCell:
PROC [cb: CellBrowser, to: Graphs.LinkConsumer, 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 IF cb.cell.realCellStuff.state = NIL THEN FALSE ELSE NOT ISTYPE[cb.cell.realCellStuff.state, Rosemary.Structure]) THEN to.proc[["State", StateNode[cb]], to.data];
END;
EnumerateInterfaceNodes:
PROC [in: InterfaceNodes, to: Graphs.LinkConsumer] =
BEGIN
FOR ni:
CARDINAL
IN [0 .. in.cb1.cell.class.ports.length)
DO
port: Rosemary.Port ← in.cb1.cell.class.ports[ni];
node: Node ← in.cb1.cell.interfaceNodes[ni];
ne: NodeElt ← NEW [NodeEltRep ← [node: node, name: port.name, org: [display: in.cb1.display, cell: in.cb1.cell], interfaceIndex: ni, interfaceNode: TRUE, parent: in.cb1]];
to.proc[[port.name, NodeNode[ne]], to.data];
ENDLOOP;
END;
EnumerateInternalNodes:
PROC [in: InternalNodes, to: Graphs.LinkConsumer] =
BEGIN
FOR node: Node ← in.cb2.cell.firstInternalNode, node.next
WHILE node #
NIL
DO
ne: NodeElt ← NEW [NodeEltRep ← [node: node, name: node.name, org: [display: in.cb2.display, cell: in.cb2.cell], interfaceIndex: notLookedFor, parent: in.cb2]];
to.proc[[node.name, NodeNode[ne]], to.data];
ENDLOOP;
END;
notFound: CARDINAL = Rosemary.notFound;
notLookedFor: CARDINAL = notFound - 1;
EnumerateComponents:
PROC [components: Components, to: Graphs.LinkConsumer] =
BEGIN
FOR cell: Cell ← components.cb3.cell.leftChild, cell.rightSibling
WHILE cell #
NIL
DO
cb: CellBrowser ← NEW [CellBrowserRep ← [cell: cell, display: components.cb3.display, parent: components.cb3]];
to.proc[[cell.name, CellNode[cell: cell, display: components.cb3.display, parent: components.cb3]], 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[yellow .. blue] OF ARRAY BOOLEAN OF Graphs.LinkConsumerProc ← ALL[ALL[NIL]];
BrowserClick: GraphBrowsers.BrowserCmdProc
--PROC [pane: Pane, index: CARDINAL- -origin 0- -, cmdData, browserData: REF ANY, button: Menus.MouseButton, ctl, shift, paint: BOOLEAN]-- =
CHECKED
BEGIN
whatToDo[button][shift][[pane.GetChildName[index], pane.GetChildNode[index]], NIL];
END;
DisplayAllButState: Graphs.LinkConsumerProc =
TRUSTED
BEGIN
WITH link.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]];
components: Components => EnumerateComponents[components, [DisplayAllButState]];
ENDCASE => ERROR;
END;
UnDisplayAll: Graphs.LinkConsumerProc =
TRUSTED
BEGIN
WITH link.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]];
components: Components => EnumerateComponents[components, [UnDisplayAll]];
ENDCASE => ERROR;
END;
DisplayAllState: Graphs.LinkConsumerProc =
TRUSTED
BEGIN
WITH link.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;
components: Components => EnumerateComponents[components, [DisplayAllState]];
ENDCASE => ERROR;
END;
UnDisplayAllState: Graphs.LinkConsumerProc =
TRUSTED
BEGIN
WITH link.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;
components: Components => EnumerateComponents[components, [UnDisplayAllState]];
ENDCASE => ERROR;
END;
DisplayCellState:
PROC [cs: CellState] =
BEGIN
dl: HD.Leaf ← NARROW[List.Assoc[key: cellStateDisplayProp, aList: cs.cb0.cell.other]];
IF dl =
NIL
THEN
BEGIN
CreateValue:
HD.ValueCreater
--PROC [leaf: Leaf] RETURNS [value: Viewer]-- =
CHECKED
BEGIN
value ←
VR.ViewRef[
agg: cs.cb0.cell.realCellStuff.state,
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: [feedBackHeight: 0],
parent: cs.cb0.display.rv,
paint: FALSE].RVQuaViewer[];
END;
dp: HD.Parent ← EnsureDisplay[cs.cb0];
name: ROPE ← cs.cb0.cell.name.Cat["'s state:"];
dl ← HD.AddLeaf[parent: dp, before: NextCellChild[cs.cb0.display, cs.cb0.cell.leftChild], name: name, class: cellStateClass, instanceData: cs, CreateValue: CreateValue, paint: FALSE];
cs.cb0.cell.other ← List.PutAssoc[key: cellStateDisplayProp, val: dl, aList: cs.cb0.cell.other];
END;
END;
UnDisplayCellState:
PROC [cs: CellState] =
BEGIN
dl: HD.Leaf ← NARROW[List.Assoc[key: cellStateDisplayProp, aList: cs.cb0.cell.other]];
IF dl # NIL THEN HD.Remove[dl];
END;
NoticeCellStateRemoval:
HD.ChildNotifyProc
-- PROC [child: Child]-- =
CHECKED
BEGIN
cs: CellState ← NARROW[child.instanceData];
cs.cb0.cell.other ← List.PutAssoc[key: cellStateDisplayProp, val: NIL, aList: cs.cb0.cell.other];
END;
CellStateButtonProc: Buttons.ButtonProc =
CHECKED
BEGIN
MessageWindow.Append[message: "Don't do that", clearFirst: TRUE];
END;
UnDisplayNode:
PROC [ne: NodeElt, noisy:
BOOLEAN] =
BEGIN
displays: NodeDisplayList ← NARROW[List.Assoc[key: nodeDisplaysProp, aList: 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 ← Rosemary.GetIndex[ne.org.cell.class.ports, ne.name]};
DisplayNode:
PROC [ne: NodeElt, noisy:
BOOLEAN] =
BEGIN
displays: NodeDisplayList ← NARROW[List.Assoc[key: nodeDisplaysProp, aList: 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 ne.node.visible.cell #
NIL
THEN
BEGIN
CreateValue:
HD.ValueCreater =
TRUSTED
BEGIN
value ←
VO.CreateViewer[flavor: $Text, paint:
FALSE,
info: [parent: leaf.container,
data:
IF ne.org.display.ctlPanel.mode = Value
THEN ne.node.type.toRope[
where: ne.node.visible.SocketToWP[],
typeData: ne.node.type.typeData]
ELSE ne.node.type.unParseTest[
testProc: ne.testProc,
testData: ne.testData,
typeData: ne.node.type.typeData,
subject: NIL],
wx: leaf.nameButton.wx + leaf.nameButton.ww + 2,
ww: ne.node.type.maxWidth[ne.node.type.typeData, 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 THEN name ← name.Concat[":"];
EnsureInterfaceIndex[ne];
IF ne.interfaceIndex # notFound
THEN
BEGIN
name ← name.Concat[SELECT (IF ne.org.cell.class.ports[ne.interfaceIndex].input THEN 1 ELSE 0) + (IF ne.org.cell.class.ports[ne.interfaceIndex].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, paint: FALSE];
displays ← CONS[[ne.org, dc], displays];
ne.node.other ← List.PutAssoc[key: nodeDisplaysProp, val: displays, aList: ne.node.other];
Rosemary.AddNodeWatcher[node: ne.node, watcher: [NotifyNodeView, dc], priority: 1];
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[List.Assoc[key: nodeDisplaysProp, aList: 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 ← ne.node.next;
IF ne.interfaceNode
THEN
BEGIN
FOR c:
CARDINAL
IN (ne.interfaceIndex .. ne.org.cell.interfaceNodes.length)
DO
IF Displayed[ne.org.cell.interfaceNodes[c]] THEN RETURN;
ENDLOOP;
node ← ne.org.cell.firstInternalNode;
END;
FOR node ← node, node.next
WHILE node #
NIL
DO
IF Displayed[node] THEN RETURN ENDLOOP;
child ← NARROW[List.Assoc[key: cellStateDisplayProp, aList: ne.org.cell.other]];
IF child # NIL THEN RETURN;
child ← NextCellChild[ne.org.display, ne.org.cell.leftChild];
END;
UnDisplayCell:
PROC [cb: CellBrowser] =
BEGIN
dpAsAny: REF ANY ← List.Assoc[aList: cb.cell.other, key: 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 ← List.Assoc[aList: cell.other, key: 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 ← List.Assoc[aList: cb.cell.other, key: cb.display];
IF dpAsAny =
NIL
THEN
BEGIN
pdp: HD.Parent ← IF cb.parent = NIL THEN cb.display.rootDisplay ELSE EnsureDisplay[cb.parent];
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, paint: FALSE]).asParent;
cb.cell.other ← List.PutAssoc[key: cb.display, val: dp, aList: cb.cell.other];
IF cb.cell.type = Real
THEN
BEGIN
Rosemary.AddCellEventWatcher[cb.cell, $Schedule, [NotifyCellView, dc]];
NotifyCellView[cb.cell, dc];
END;
END
ELSE dp ← NARROW[dpAsAny];
END;
Setup:
PROC =
BEGIN
whatToDo[yellow][FALSE] ← DisplayAllButState;
whatToDo[yellow][TRUE] ← UnDisplayAll;
whatToDo[blue][FALSE] ← DisplayAllState;
whatToDo[blue][TRUE] ← UnDisplayAllState;
END;
Setup[];
END.