TajoMenusImpl.mesa
Copyright © 1985, Xerox Corporation. All rights reserved.
Last edited by Eric Nickell, March 29, 1985 2:33:50 pm PST
DIRECTORY
PopUpMenu USING [RequestSelection],
Rope USING [Cat, Equal, Substr],
SymTab USING [Create, Fetch, Insert, Ref],
TajoMenus
;
TajoMenusImpl: CEDAR PROGRAM
IMPORTS PopUpMenu, Rope, SymTab
EXPORTS TajoMenus
= BEGIN
OPEN TajoMenus;
TajoSystem: TYPE ~ REF TajoSystemRec;
TajoSystemRec: PUBLIC TYPE ~ RECORD [
x: SymTab.Ref ← SymTab.Create[]
];
PopUp: TYPE ~ REF PopUpRec;
PopUpRec: TYPE ~ RECORD [
list: LIST OF ROPENIL,
action: SEQUENCE len:NAT OF REF
];
DuplicateName: PUBLIC ERROR ~ CODE;
filler: ROPE ~ " "; --Lots of spaces
CreateTajoSystem: PUBLIC PROC [menus: LIST OF TajoMenu] RETURNS [ts: TajoSystem] ~ {
ring: LIST OF ROPELIST[menus.first.title];
ringTail: LIST OF ROPE ← ring;
nMenus: CARDINAL ← 0;  --Number of menus
ts ← NEW[TajoSystemRec];
Choose first default menu as the first one listed
defaultTitle ← menus.first.title;
Count number of main menus
FOR each: LIST OF TajoMenu ← menus, each.rest UNTIL each=NIL DO
nMenus ← nMenus + 1;
ENDLOOP;
Create a ring of ROPEs from the original list
FOR each: LIST OF TajoMenu ← menus.rest, each.rest UNTIL each=NIL DO
ringTail ← ringTail.rest ← LIST[each.first.title];
ENDLOOP;
ringTail.rest ← ring;  --Close the ring
Set up the PopUp menu for each of the main entries
FOR eachMenu: LIST OF TajoMenu ← menus, eachMenu.rest UNTIL eachMenu=NIL DO
AppendToPopUp: PROC [r: ROPE] ~ {
tail ← tail.rest ← LIST[r];
};
optionList: LIST OF ROPELIST["Dummy"]; --The actual list of rope for this menu
tail: LIST OF ROPE ← optionList;  --Always points to tail of optionList
popUp: PopUp;
nEntries: CARDINAL ← 0;   --Will contain the number of entries exclusive to this menu
tempEntry: LIST OF TajoEntry ← eachMenu.first.options;
Count the number of entries
FOR eachEntry: LIST OF TajoEntry ← eachMenu.first.options, eachEntry.rest UNTIL eachEntry=NIL DO
nEntries ← nEntries+1;
ENDLOOP;
Create the PopUp record
popUp ← NEW[PopUpRec[nMenus+nEntries+1]];
popUp.action[0] ← NIL;
Add the other menu titles to the PopUp menu to be presented for this TajoMenu
UNTIL Rope.Equal[ringTail.first, eachMenu.first.title] DO--Point ringTail at our title
ringTail ← ringTail.rest;
ENDLOOP;
FOR index: CARDINAL IN [1..nMenus] DO
rope: ROPE;
ringTail ← ringTail.rest;  --Set up title name
rope ← Rope.Cat[Rope.Substr[base: filler, len: (nMenus-index)*2], ringTail.first];
IF index=nMenus THEN rope ← Rope.Cat[rope, "-----------"];
popUp.action[index] ← ringTail.first;
AppendToPopUp[rope];
ENDLOOP;
Add the menu entries to the PopUp menu
FOR index: CARDINAL IN [1..nEntries] DO
ref: REFIF tempEntry.first.action=NIL THEN tempEntry.first.rope ELSE tempEntry.first.action;
AppendToPopUp[tempEntry.first.rope];
popUp.action[nMenus+index] ← ref;
tempEntry ← tempEntry.rest;
ENDLOOP;
Install the popUp menu into the TajoSystem
popUp.list ← optionList.rest;
IF ~SymTab.Insert[ts.x, eachMenu.first.title, popUp] THEN ERROR DuplicateName[];
ENDLOOP;
};
defaultTitle: ROPENIL;  --Remembers last title brought up
Select: PUBLIC PROC [ts: TajoSystem, title: ROPENIL] RETURNS [action: REF] ~ {
IF title=NIL THEN title ← defaultTitle;
DO  --This is an iterative process
popUp: PopUp;
found: BOOLEAN;
ref: REF;
choice: CARDINAL;
[found, ref] ← SymTab.Fetch[ts.x, title];
IF ~found THEN RETURN [title]; --This is where ROPEs are returned from
Here, we have found a menu to bring up.
defaultTitle ← title;  --Remember this menu as the new default
popUp ← NARROW[ref];
choice ← PopUpMenu.RequestSelection[choice: popUp.list];
action ← popUp.action[choice];
WITH action SELECT FROM
r: ROPE => title ← r;
ENDCASE => RETURN [action];
ENDLOOP;
};
END.