MenuSystemImpl.mesa
Copyright © 1985, Xerox Corporation. All rights reserved.
Last edited by Eric Nickell, March 27, 1985 7:10:21 pm PST
DIRECTORY
MenuSystem,
PopUpMenu USING [RequestSelection],
SymTab USING [Create, Delete, Fetch, Ref, Store]
;
MenuSystemImpl: CEDAR MONITOR
IMPORTS PopUpMenu, SymTab
EXPORTS MenuSystem
= BEGIN
OPEN MenuSystem;
MenuSystem: TYPE ~ REF MenuSystemRec;
MenuSystemRec: PUBLIC TYPE ~ RECORD [
x: SymTab.Ref ← SymTab.Create[],
defaultTitle: ROPENIL
];
CreateMenuSystem: PUBLIC PROC RETURNS [ms: MenuSystem] ~ {
RETURN [NEW[MenuSystemRec]]
};
InstallMenu: PUBLIC PROC [ms: MenuSystem, menu: Menu] ~ {
InstallRefMenu[ms, NEW[Menu ← menu]];
};
InstallRefMenu: PUBLIC ENTRY PROC [ms: MenuSystem, menu: REF Menu] ~ {
ENABLE UNWIND => NULL;
[] ← SymTab.Store[ms.x, menu.title, menu];
ms.defaultTitle ← menu.title;
};
RemoveMenu: PUBLIC ENTRY PROC [ms: MenuSystem, title: ROPE] ~ {
ENABLE UNWIND => NULL;
[] ← SymTab.Delete[ms.x, title];
};
InstallAction: PUBLIC ENTRY PROC [ms: MenuSystem, title: ROPE, action: REF] ~ {
ENABLE UNWIND => NULL;
[] ← SymTab.Store[ms.x, title, action];
};
Select: PUBLIC ENTRY PROC [ms: MenuSystem, title: ROPENIL] RETURNS [action: REF] ~ {
ENABLE UNWIND => NULL;
IF title=NIL THEN title ← ms.defaultTitle;  --Left by sticky menus
DO
ref: REF;
found: BOOLEAN;
[found, ref] ← SymTab.Fetch[ms.x, title];
IF ~found THEN RETURN [title]; --Thus, if at some end node, no action has been placed in the table, we'll return the ROPE itself
WITH ref SELECT FROM
menu: REF Menu => {
options: LIST OF ROPE ← menu.options;
choice: CARDINAL ← PopUpMenu.RequestSelection[
label: menu.title,
choice: options,
default: 0   --Until PopUpMenu.RequestSelection fixed
default: menu.defaultSelection
];
IF menu.sticky THEN ms.defaultTitle ← title;
IF choice=0 THEN RETURN [NIL]; --After all this, the user did nothing
Find the new ``title'' from the list
THROUGH [1..choice) DO
options ← options.rest;
ENDLOOP;
title ← options.first;
};
ENDCASE => RETURN [ref]; --Return the REF which was associated with title, but which was not a REF Menu
ENDLOOP;
};
CallUnderLock: PUBLIC ENTRY PROC [proc: PROC] ~ {
ENABLE UNWIND => NULL;
proc[];
};
END.