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: ROPE ← NIL
];
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:
ROPE ←
NIL]
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.