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 ANY _ NIL ]; MakeTable: PUBLIC GraphPlaceProc = { IF GraphUtil.HandleNotNil[handle] THEN { OPEN handle; 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: ROPE _ IF topLevel THEN "lb" ELSE "b"; IF topLevel THEN parent _ TiogaOps.ViewerDoc[handle.controller.table]; 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[]; 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 }; -- 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] = { 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] = { 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. 2GraphTable.mesa, Copyright c 1985 by Xerox Corporation. All rights reserved. Last Edited by: Sweetsun Chen, November 18, 1985 8:45:06 pm PST called by NewController, which should have made sure the following not nil: handle, handle.controller, etc. LockedMakeTable: PROC [root: TiogaOps.Ref] = {TopLevelTable[handle, root]}; heading its entity list and children. 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; replace the rope of a text button replace the rope of an entity button Κ ˜JšœΟmœ1™Mšœ™Icode™/—šΟk ˜ Jšœ žœ˜,Jšœžœ˜Jšœžœpžœ˜–Jšœ žœa˜sJšœ žœ1˜@Jšœ žœ˜!Jšœžœ˜%Jšœ žœ€˜²Jšœ žœc˜uJšœ žœ˜ —J˜šœ žœž˜Jšžœc˜kJšžœžœ˜2—J˜Jšœžœžœ˜/šœžœžœ˜"Jšœžœ˜Jšœžœžœž˜J˜—J˜šΟn œžœ˜$Jšœk™kšžœ žœžœ˜5JšŸœžœ6™Kšœ-˜-šœ˜Jšœ#˜#Jšœžœ˜ Jšœ˜Jšœ žœ˜Jšœžœ˜Jšœ ž˜Jšœ˜——Jšœ<˜Jšœ˜Jšœ0˜0Jšœ$˜$Jšœ& 3˜Yšœ'˜'Jšœ˜Jšœ˜Jšœ˜Jšœ žœ#˜2Jšœ˜—Jšœ=˜=J˜J˜J˜J™Jšœ0˜0šžœ1žœžœž˜FJšœ$˜$Jšžœ˜—J˜J˜J˜—Jšœ  ˜ J˜—šœ8 ˜GJšœžœ0™Lšœžœ ™(Jšœ!™!—Jšœ*™*Jšœ ™ šžœ ž™Jšœžœ žœ"™8Jšœžœ žœ!™8Jšžœ™—Jšœ ˜J˜—šœ; ˜KJšœ ˜J˜—šœ2˜2Jšœžœ ˜+˜Jšœžœ ˜"šžœ ž˜šœ˜JšœT˜TJšœ˜J˜—Jšœ%˜%Jšžœ˜—J˜—Jšžœžœ!˜EJšœ ˜J˜—šœ0˜0Jšœžœ ˜+˜Jšœ žœ ˜šžœ ž˜šœ˜JšœM˜MJšœ˜J˜—Jšœ˜Jšžœ˜—J˜—Jšœ ˜ Jšœ ˜—J˜—šŸ œžœžœ&˜@š žœ)žœžœžœžœžœ˜bJšœA˜AJ˜šœ-˜-Jšœ9˜9—J˜šœ˜Jšžœ žœžœžœ ˜E—šœ'˜'JšœH˜HJšœ˜Jšœ žœ%˜4Jšœ˜—J˜J˜—Jšœ ˜J™—šŸœžœžœ*˜Fš žœ)žœžœžœ žœžœ˜dJšœA˜AJšœ"˜"J˜šœ-˜-Jšœ)˜)—J˜J˜šœ˜Jšžœžœžœ˜YJšžœ%˜)—šœ'˜'Jšœ8˜8Jšœ˜Jšœ žœ'˜6Jšœ˜—J˜J˜—Jšœ ˜J˜—šŸœžœžœ3˜Nš žœ)žœžœžœžœžœ˜i˜8J˜ Jšœ9˜9J˜ Jšœ˜Jšœ žœ/˜>Jšœ˜—JšœU˜UJ˜—Jšœ ˜J˜—šŸœžœžœ&˜CJ™!š žœ)žœžœžœžœžœ˜bJšœA˜AJšœžœ˜J˜šžœXžœžœž˜kJšœ%žœ˜)J˜Jšœ˜J˜ Jšœžœžœ)˜5Jšžœžœžœžœ˜Jš žœžœ$žœžœžœžœ˜OJšžœžœžœžœ˜%Jš žœžœžœžœžœ˜1Jšžœ žœžœžœ˜šžœžœžœ˜Jšœžœ ˜Jšžœ žœ žœ˜#J˜—Jšžœ˜—Jšžœžœžœ4˜Fšžœ˜šœ6˜6JšœL˜LJšœ žœžœ˜8—šœ˜Jšžœžœžœ ˜I—Jšœ˜J˜—J˜J˜—Jšœ ˜—J˜šŸœžœžœ*˜IJ™$š žœ)žœžœžœ žœžœ˜dJšœA˜AJšœžœ˜J˜šžœMžœžœž˜`Jšœ%žœ˜)J˜Jšœ˜J˜ Jšœžœžœ)˜5Jšžœžœžœžœ˜Jš žœžœ$žœžœžœžœ˜OJšžœžœžœžœ˜%Jš žœžœžœžœžœ˜1Jšžœ žœžœžœ˜šžœžœžœ˜!Jšœžœ ˜Jšžœ žœ žœ˜%J˜—Jšžœ˜—Jšžœžœžœ6˜Hšžœ˜šœ6˜6JšœL˜LJšœ žœžœ˜8—šœ˜Jšžœžœžœ˜YJšžœ#˜'J˜—Jšœ˜J˜—J˜J˜—Jšœ ˜—J˜J˜J˜šžœ˜J˜1——…—'€5ή