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
CDMenuSpecialsImpl:
CEDAR
MONITOR
IMPORTS PopUpMenus, Rope, SymTab, TerminalIO
EXPORTS CDMenuSpecials =
SelectOneOf:
PUBLIC
PROC[ref:
REF, label: Rope.
ROPE, allowTypeIn:
BOOL←
FALSE]
RETURNS [r: Rope.
ROPE←
NIL] = {
cnt: INT ← 0; cntPerMenu: INT = 12;
menu, firstMenu: PopUpMenus.Menu; x: REF←NIL;
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];
};