CDMenuSpecialsImpl.mesa (part of ChipNDale)
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, June 5, 1985 8:02:35 pm PDT
Last edited by: Christian Jacobi, December 17, 1986 9:10:47 pm PST
DIRECTORY
CD,
CDMenuSpecials,
PopUpMenus,
Rope,
SymTab,
TerminalIO;
CDMenuSpecialsImpl: CEDAR MONITOR
IMPORTS PopUpMenus, Rope, SymTab, TerminalIO
EXPORTS CDMenuSpecials =
BEGIN
SelectOneOf: PUBLIC PROC[ref: REF, label: Rope.ROPE, allowTypeIn: BOOLFALSE] RETURNS [r: Rope.ROPENIL] = {
cnt: INT ← 0; cntPerMenu: INT = 12;
menu, firstMenu: PopUpMenus.Menu; x: REFNIL;
alreadyUsed: SymTab.Ref ← SymTab.Create[];
NewMenu: PROC [] RETURNS [m: PopUpMenus.Menu] = {
m ← PopUpMenus.Create[header: label];
IF allowTypeIn THEN
[] ← PopUpMenus.Entry[menu: m, entry: "<type in>", entryData: $type, doc: "type in rope to terminal"];
};
AddEntry: PROC [entry: Rope.ROPE] = {
IF SymTab.Insert[alreadyUsed, entry, entry] THEN {
IF (cnt MOD cntPerMenu)=(cntPerMenu-1) THEN {
newMenu: PopUpMenus.Menu ← NewMenu[];
[] ← PopUpMenus.Entry[menu: menu, entry: "<show more>", entryData: newMenu, doc: "show more entries for this menu"];
menu ← newMenu;
};
cnt ← cnt+1;
[] ← PopUpMenus.Entry[menu: menu, entry: entry, entryData: entry];
};
};
EachSymTabEntry: SymTab.EachPairAction = { quit ← FALSE;
AddEntry[key]
};
menu ← firstMenu ← NewMenu[];
WITH ref SELECT FROM
st: SymTab.Ref => [] ← SymTab.Pairs[st, EachSymTabEntry];
rl: LIST OF Rope.ROPE =>
FOR l: LIST OF Rope.ROPE ← rl, l.rest WHILE l#NIL DO
AddEntry[l.first];
ENDLOOP;
ENDCASE => NULL;
IF menu#firstMenu THEN
[] ← PopUpMenus.Entry[menu: menu, entry: "<show again>", entryData: firstMenu, doc: "show beginning entries again"];
IF cnt>0 THEN x ← PopUpMenus.Call[firstMenu] ELSE IF allowTypeIn THEN x ← $type;
WHILE x#NIL AND ISTYPE[x, PopUpMenus.Menu] DO
x ← PopUpMenus.Call[NARROW[x]];
ENDLOOP;
IF x=$type THEN
r ← TerminalIO.RequestRope[Rope.Concat[label, " >"] ! TerminalIO.UserAbort => CONTINUE]
ELSE r ← NARROW[x];
};
END.