GraphTable.mesa, Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by:
Sweetsun Chen, November 18, 1985 8:45:06 pm PST
DIRECTORY
Containers USING [ChildXBound, ChildYBound],
Convert USING [RopeFromInt],
Graph USING [Entity, EntityGroup, EntityGroupList, EntityList, GraphHandle, GraphProc, NestedEntities, NestedEntitiesList, ROPE, Text, Texts, Viewer],
GraphPrivate USING [CallWithLock, GraphPlaceProc, RemoveEntity, RemoveText, ShowEntity, ShowText, UserEditAllowed],
GraphUtil USING [BlinkMsg, ControllerViewerExits, HandleNotNil],
InputFocus USING [SetInputFocus],
Rope USING [Concat, IsEmpty, Length],
TiogaOps USING [Break, FirstChild, GetProp, GetRope, InsertRope, LastChild, Lock, Nest, Next, Ref, SelectPoint, SetLooks, SetSelection, SubtractLooks, Unlock, UnNest, ViewerDoc],
TiogaButtons USING [CreateButton, CreateButtonFromNode, CreateViewer, TiogaButton, TiogaButtonList, TiogaButtonProc],
ViewerTools USING [SetContents];
GraphTable: CEDAR PROGRAM
IMPORTS Containers, Convert, GraphPrivate, GraphUtil, InputFocus, Rope, TiogaOps, TiogaButtons, ViewerTools
EXPORTS GraphPrivate = { OPEN Graph, GraphPrivate;
GraphButtonData: TYPE = REF GraphButtonDataRec;
GraphButtonDataRec: TYPE = RECORD[
handle: GraphHandle ← NIL,
ref: REF ANYNIL
];
MakeTable: PUBLIC GraphPlaceProc = {
called by NewController, which should have made sure the following not nil: handle, handle.controller, etc.
IF GraphUtil.HandleNotNil[handle] THEN { OPEN handle;
LockedMakeTable: PROC [root: TiogaOps.Ref] = {TopLevelTable[handle, root]};
controller.table ← TiogaButtons.CreateViewer[
info: [
wx: sx, wy: sy, ww: 1000, wh: 1000,
menu: NIL,
parent: controller.viewer,
scrollable: TRUE,
border: FALSE,
caption: FALSE
]];
Containers.ChildXBound[controller.viewer, controller.table];
Containers.ChildYBound[controller.viewer, controller.table];
[] ← TiogaButtons.CreateButton[viewer: controller.table, rope: ""];
TextsTable[handle];
FOR egl: EntityGroupList ← entityGroupList, egl.rest UNTIL egl = NIL DO
NETable[handle, egl.first.ys, NIL];
ENDLOOP;
};
}; -- MakeTable
TextsTable: PROC [handle: GraphHandle] = {
b: TiogaButtons.TiogaButton ← TiogaButtons.CreateButton[
viewer: handle.controller.table, rope: "Texts", looks: "lb"];
b ← TiogaButtons.CreateButton[
viewer: handle.controller.table, rope: ""];
handle.controller.textsParent ← b.endLoc.node;
TiogaOps.SelectPoint[handle.controller.table, b.endLoc];
TiogaOps.Break[];
TiogaOps.Nest[];
FOR ts: Texts ← handle.allTexts, ts.rest UNTIL ts = NIL DO
t: Text ← ts.first; -- error if nil.
TiogaOps.InsertRope[
IF t.text = NIL THEN Convert.RopeFromInt[t.id] ELSE t.text];
b ← TiogaButtons.CreateButtonFromNode[
node: TiogaOps.LastChild[handle.controller.textsParent],
start: , end: ,
proc: TextButtonProc,
clientData: NEW[GraphButtonDataRec ← [handle, t]]
];
TiogaOps.SelectPoint[handle.controller.table, b.endLoc];
TiogaOps.Break[];
ENDLOOP;
TiogaOps.UnNest[];
}; -- TextsTable
EntityListTable: PROC [handle: GraphHandle, entityList: EntityList, parent: TiogaOps.Ref] = {
button: TiogaButtons.TiogaButton;
IF entityList # NIL THEN TiogaOps.Break[];
FOR el: EntityList ← entityList, el.rest UNTIL el = NIL DO
entity: Entity ← el.first; -- error if nil.
TiogaOps.InsertRope[
IF entity.name.IsEmpty[] AND entity.comment.IsEmpty[] THEN Convert.RopeFromInt[entity.id]
ELSE entity.name.Concat[entity.comment]];
button ← TiogaButtons.CreateButtonFromNode[
node: TiogaOps.LastChild[parent],
start: , end: ,
proc: EntityButtonProc,
clientData: NEW[GraphButtonDataRec ← [handle, entity]]
];
TiogaOps.SelectPoint[handle.controller.table, button.endLoc];
TiogaOps.Break[];
ENDLOOP;
}; -- EntityListTable
NETable: PROC [handle: GraphHandle, ne: NestedEntities, parent: TiogaOps.Ref ← NIL] = {
IF ne # NIL THEN {
topLevel: BOOL ← parent = NIL;
look: ROPEIF topLevel THEN "lb" ELSE "b";
IF topLevel THEN parent ← TiogaOps.ViewerDoc[handle.controller.table];
heading
TiogaOps.Break[]; -- one blank line before each NestedEntities
TiogaOps.SetLooks[look, caret];
TiogaOps.InsertRope[ne.name.Concat[ne.comment]];
TiogaOps.SubtractLooks[look, caret];
ne.node ← TiogaOps.LastChild[parent]; -- ne.node is the (currently) last child of parent.
[] ← TiogaButtons.CreateButtonFromNode[
node: ne.node,
start: , end: ,
proc: NestedEntitiesButtonProc,
clientData: NEW[GraphButtonDataRec ← [handle, ne]]
];
TiogaOps.SelectPoint[handle.controller.table, [ne.node, -1]];
TiogaOps.Break[];
TiogaOps.Nest[];
its entity list and children.
EntityListTable[handle, ne.entityList, ne.node];
FOR nel: NestedEntitiesList ← ne.children, nel.rest UNTIL nel = NIL DO
NETable[handle, nel.first, ne.node];
ENDLOOP;
TiogaOps.UnNest[];
};
}; -- NETable
EntityGroupButtonProc: TiogaButtons.TiogaButtonProc = { -- noop for now
handle: GraphHandle ← NARROW[ViewerOps.FetchProp[parent, $GraphController]];
group: EntityGroup ← NARROW[clientData];
some checking might be necessary.
SetIntField[controller.groupId, group.id];
Control[handle, resume, $Group];
SELECT moustButton FROM
red => IF control THEN Control[handle, display, $Group];
blue => IF control THEN Control[handle, remove, $Group];
ENDCASE;
}; -- EntityGroupButtonProc
NestedEntitiesButtonProc: TiogaButtons.TiogaButtonProc = { -- noop for now.
}; -- NestedEntitiesButtonProc
EntityButtonProc: TiogaButtons.TiogaButtonProc = {
data: GraphButtonData ← NARROW[clientData];
proc: GraphProc = {
entity: Entity ← NARROW[data.ref];
SELECT mouseButton FROM
red => {
ViewerTools.SetContents[handle.controller.entityId, Convert.RopeFromInt[entity.id]];
ShowEntity[handle, entity];
};
blue => RemoveEntity[handle, entity];
ENDCASE;
};
IF UserEditAllowed[data.handle] THEN CallWithLock[data.handle, proc];
}; -- EntityButtonProc
TextButtonProc: TiogaButtons.TiogaButtonProc = {
data: GraphButtonData ← NARROW[clientData];
proc: GraphProc = {
t: Text ← NARROW[data.ref];
SELECT mouseButton FROM
red => {
ViewerTools.SetContents[handle.controller.textId, Convert.RopeFromInt[t.id]];
ShowText[handle, t];
};
blue => RemoveText[handle, t];
ENDCASE;
};
CallWithLock[data.handle, proc];
}; -- EntityButtonProc
AddTextButton: PUBLIC PROC [handle: GraphHandle, text: Text] = {
IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND text # NIL THEN {
root: TiogaOps.Ref ← TiogaOps.ViewerDoc[handle.controller.table];
TiogaOps.Lock[root];
TiogaOps.SelectPoint[handle.controller.table,
[TiogaOps.LastChild[handle.controller.textsParent], -1]];
TiogaOps.Break[];
TiogaOps.InsertRope[
IF text.text = NIL THEN Convert.RopeFromInt[text.id] ELSE text.text];
[] ← TiogaButtons.CreateButtonFromNode[
node: TiogaOps.LastChild[handle.controller.textsParent], start: , end: ,
proc: TextButtonProc,
clientData: NEW[GraphButtonDataRec ← [handle, text]]
];
TiogaOps.Unlock[root];
};
}; -- AddTextButton
AddEntityButton: PUBLIC PROC [handle: GraphHandle, entity: Entity] = {
IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND entity # NIL THEN {
root: TiogaOps.Ref ← TiogaOps.ViewerDoc[handle.controller.table];
group: EntityGroup ← entity.group;
TiogaOps.Lock[root];
TiogaOps.SelectPoint[handle.controller.table,
[TiogaOps.LastChild[group.ys.node], -1]];
TiogaOps.Break[];
TiogaOps.Nest[];
TiogaOps.InsertRope[
IF entity.name.IsEmpty[] AND entity.comment.IsEmpty[] THEN Convert.RopeFromInt[entity.id]
ELSE entity.name.Concat[entity.comment]];
[] ← TiogaButtons.CreateButtonFromNode[
node: TiogaOps.LastChild[group.ys.node], start: , end: ,
proc: EntityButtonProc,
clientData: NEW[GraphButtonDataRec ← [handle, entity]]
];
TiogaOps.Unlock[root];
};
}; -- AddEntityButton
AddGroupButton: PUBLIC PROC[handle: GraphHandle, entityGroup: EntityGroup] = {
IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND entityGroup # NIL THEN {
b: TiogaButtons.TiogaButton ← TiogaButtons.CreateButton[
viewer: handle.controller.table,
rope: entityGroup.ys.name.Concat[entityGroup.ys.comment],
looks: "b",
proc: NestedEntitiesButtonProc,
clientData: NEW[GraphButtonDataRec ← [handle, entityGroup.ys]]
];
entityGroup.ys.node ← TiogaOps.LastChild[TiogaOps.ViewerDoc[handle.controller.table]]
};
}; -- AddGroupButton
UpdateTextButton: PUBLIC PROC [handle: GraphHandle, text: Text] = {
replace the rope of a text button
IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND text # NIL THEN {
root: TiogaOps.Ref ← TiogaOps.ViewerDoc[handle.controller.table];
self: TiogaOps.Ref ← NIL;
TiogaOps.Lock[root];
FOR n: TiogaOps.Ref ← TiogaOps.FirstChild[handle.controller.textsParent], TiogaOps.Next[n] UNTIL n = NIL DO
list: TiogaButtons.TiogaButtonList ← NIL;
tb: TiogaButtons.TiogaButton;
gbd: GraphButtonData;
tt: Text;
ref: REF ANY ← TiogaOps.GetProp[n, $TiogaButtonList];
IF ref = NIL THEN LOOP;
IF ISTYPE[ref, TiogaButtons.TiogaButtonList] THEN list ← NARROW[ref] ELSE LOOP;
IF (tb ← list.first) = NIL THEN LOOP;
IF (gbd ← NARROW[tb.clientData]) = NIL THEN LOOP;
IF gbd.ref = NIL THEN LOOP;
IF ISTYPE[gbd.ref, Text] THEN {
tt ← NARROW[gbd.ref];
IF tt = text THEN {self ← n; EXIT};
};
ENDLOOP;
IF self = NIL THEN GraphUtil.BlinkMsg["Can't find the text on table."]
ELSE {
TiogaOps.SetSelection[viewer: handle.controller.table,
start: [self, 0], end: [self, TiogaOps.GetRope[self].Length[]], level: char,
caretBefore: TRUE, pendingDelete: TRUE, which: primary];
TiogaOps.InsertRope[
IF text.text.IsEmpty[] THEN Convert.RopeFromInt[text.id] ELSE text.text];
InputFocus.SetInputFocus[];
};
TiogaOps.Unlock[root];
};
}; -- UpdateTextButton
UpdateEntityButton: PUBLIC PROC [handle: GraphHandle, entity: Entity] = {
replace the rope of an entity button
IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND entity # NIL THEN {
root: TiogaOps.Ref ← TiogaOps.ViewerDoc[handle.controller.table];
self: TiogaOps.Ref ← NIL;
TiogaOps.Lock[root];
FOR n: TiogaOps.Ref ← TiogaOps.FirstChild[entity.parent.node], TiogaOps.Next[n] UNTIL n = NIL DO
list: TiogaButtons.TiogaButtonList ← NIL;
tb: TiogaButtons.TiogaButton;
gbd: GraphButtonData;
te: Entity;
ref: REF ANY ← TiogaOps.GetProp[n, $TiogaButtonList];
IF ref = NIL THEN LOOP;
IF ISTYPE[ref, TiogaButtons.TiogaButtonList] THEN list ← NARROW[ref] ELSE LOOP;
IF (tb ← list.first) = NIL THEN LOOP;
IF (gbd ← NARROW[tb.clientData]) = NIL THEN LOOP;
IF gbd.ref = NIL THEN LOOP;
IF ISTYPE[gbd.ref, Entity] THEN {
te ← NARROW[gbd.ref];
IF te = entity THEN {self ← n; EXIT};
};
ENDLOOP;
IF self = NIL THEN GraphUtil.BlinkMsg["Can't find the entity on table."]
ELSE {
TiogaOps.SetSelection[viewer: handle.controller.table,
start: [self, 0], end: [self, TiogaOps.GetRope[self].Length[]], level: char,
caretBefore: TRUE, pendingDelete: TRUE, which: primary];
TiogaOps.InsertRope[
IF entity.name.IsEmpty[] AND entity.comment.IsEmpty[] THEN Convert.RopeFromInt[entity.id]
ELSE entity.name.Concat[entity.comment]
];
InputFocus.SetInputFocus[];
};
TiogaOps.Unlock[root];
};
}; -- UpdateEntityButton
}.
LOG.
SChen, created at October 9, 1985 6:57:10 pm PDT.