DIRECTORY Imager USING [Context], Rope USING [ROPE], ViewerClasses USING [NotifyProc, Viewer]; Menus: CEDAR DEFINITIONS = BEGIN Viewer: TYPE = ViewerClasses.Viewer; ROPE: TYPE = Rope.ROPE; Trigger: TYPE = {leftUp, middleUp, rightUp, shiftLeftUp, shiftMiddleUp, shiftRightUp}; TriggerEnabled: TYPE = BOOL _ FALSE; TriggerSet: TYPE = PACKED ARRAY Trigger OF TriggerEnabled; -- SET OF Trigger allTriggers: TriggerSet = ALL[TRUE]; allNonShifts: TriggerSet = [leftUp: TRUE, middleUp: TRUE, rightUp: TRUE]; allShifts: TriggerSet = [shiftLeftUp: TRUE, shiftMiddleUp: TRUE, shiftRightUp: TRUE]; noTriggers: TriggerSet = ALL[FALSE]; targetNotFound: SIGNAL; MenuName: TYPE = ATOM; Menu: TYPE = REF MenuRec; MenuRec: TYPE = RECORD[ name: MenuName, beginsActive: BOOL _ TRUE, breakBefore: BOOL _ TRUE, breakAfter: BOOL _ TRUE, notify: ViewerClasses.NotifyProc _ NIL, entries: LIST OF Entry _ NIL ]; Entry: TYPE = REF EntryRec; EntryRec: TYPE = RECORD[ name: ROPE, guarded: BOOLEAN _ FALSE, displayData: REF ANY _ NIL, -- if supplied, must narrow to ROPE or REF DrawingRec actions: LIST OF Action _ NIL ]; Action: TYPE = REF ActionRec; ActionRec: TYPE = RECORD[ triggers: TriggerSet, -- triggers that invoke this action input: LIST OF REF ANY _ NIL, -- input to be passed to the notify proc popupDoc: ROPE _ NIL, guardResponse: REF ANY _ NIL, -- if supplied, must narrow to ROPE or REF UnGuardRec makeActive: LIST OF MenuName _ NIL, makeInactive: LIST OF MenuName _ NIL, toggle: LIST OF MenuName _ NIL ]; DrawingRec: TYPE = RECORD [ proc: DrawingProc, -- procedure to call to do the drawing data: REF ANY _ NIL -- will be passed as the 'clientData' parameter to the procedure ]; UnGuardRec: TYPE = RECORD [ proc: UnGuardProc, -- procedure to call when menu becomes unguarded data: REF ANY _ NIL -- will be passed as the 'clientData' parameter to the procedure ]; MenuEntryDisplayOp: TYPE = {query, draw}; DrawingProc: TYPE = PROC [op: MenuEntryDisplayOp, context: Imager.Context _ NIL, clientData: REF ANY _ NIL] RETURNS[width: INTEGER _ 64]; UnGuardProc: TYPE = PROC [clientData: REF ANY _ NIL]; RegisterMenu: PROC [menu: Menu]; AlreadyRegistered: PROC [name: MenuName] RETURNS [registered: BOOLEAN]; ReRegisterMenu: PROC [menu: Menu, paint: BOOL _ TRUE]; GetRegisteredMenu: PROC [name: MenuName] RETURNS [menu: Menu]; ClearMenus: PROC [viewer: Viewer, paint: BOOL _ TRUE]; AddMenu: PROC [viewer: Viewer, name: MenuName, paint: BOOL _ TRUE, addBefore: MenuName _ NIL]; MakeActive: PROC [viewer: Viewer, menu: MenuName, paint: BOOL _ TRUE]; MakeInactive: PROC [viewer: Viewer, menu: MenuName, paint: BOOL _ TRUE]; Toggle: PROC [viewer: Viewer, menu: MenuName, paint: BOOL _ TRUE]; MenuInViewer: PROC [viewer: Viewer, menu: MenuName] RETURNS [exists: BOOLEAN]; ParseDescription: PROC [def: ROPE, prevlist: LIST OF Menu _ NIL, errorFile: ROPE _ NIL] RETURNS [LIST OF Menu]; END. Menus.mesa; Written by Randy Pausch Menus are collections of entries. Entries are selectable regions at the top of viewers that can cause TIP-like actions to be passed to notifyProcs. Menus are useful for manipulating sets of entries as a group. Menus can be created and registered with the viewers package (after which they are referred to by their unique rope "name"), and then attached to viewers. Each viewer has a list of menus associated with it, and at any given time each menu may be "active" in that viewer (visible to the user and ready to have its entries selected), or "inactive", in which case it exists in the viewer's list of menus but is currently not displayed to the user. For example, the standard Tioga viewer has three menus: the "main" one, which is initially active, and the "Levels" and "Places" menus, which are initially inactive. Last Edited by: Pausch, August 26, 1983 10:18 am Last Edited by: Wyatt, October 10, 1983 6:42 pm Menu entries may specify different user actions as their triggers. Depending on the state of the shift key and which mouse button was used, different results may be obtained from clicking a menu entry. In addition, there is a standard way (holding control down and clicking) for users to request a list of all possible functions for a menu entry. A TriggerSet specifies which triggers will invoke an action. Some calls require locating entries by their names. This signal is raised if an entry doesn't exist. A 'menu' is a set of entries defined and manipulated as a group. A menu is uniquely identified by its name after it is registered with the viewers package. This is all designed for ease in 'passively' describing menus as data structures. If beginsActive is TRUE, the menu will be accessible to the user when the menu is added to a viewer. Each viewer has a list of menus associated with it, and they are "laid out" like text, as many as will fit onto a line. breakBefore and breakAfter can be used to force "line breaks" in the menus. When the user clicks a menu entry, the 'notify' procedure is called with the input actions for that entry; if notify=NIL, the notify proc of the viewer owning the menu will be called. Menu entries are uniquely identified by name. If 'guarded' is TRUE, the user will have to click the entry twice in a short period of time to cause action actually to occur. If something other than the name of the entry should be displayed, this can be done by making 'displayData' either a ROPE (which will be displayed instead of the name), or a REF DrawingRec, which will draw the entry itself. Menus may have more than one action associated with them. Each action has a record with the list of triggers that cause the action, what to pass to the notify proc, and a ROPE to describe the action for use in the user interface. 'guardResponse' is used after the first mouse hit; the rope associated with the trigger is shown in the message window, or the indicated procedure is called. 'makeActive', 'makeInactive', and 'toggle' specify the menus to affect when the trigger is handled; this makes it easy to describe typical menu actions in the data structure, rather than writing code to handle making menus active and inactive. If op is 'query' the client should return the width he would like to have. (Height will be ViewerSpecs.menuHeight). If 'op' is 'draw', the procedure should draw into the passed context to display the entry on the screen. operations to register menus with the viewers package: The menu data is recorded by the viewers package and associated with the name in the record. All future references may be made through the name alone. returns TRUE iff a menu with the given name has been registered. The previous definition of the menu is forgotten, and the new one takes its place. If 'paint' is true, all viewers containing the menu will be found and repainted with hint=menu. The definition for the menu is returned operations to attach menus to viewers: Any menus that had been associated with the viewer are no longer attached to the viewer. They are still registered with the viewers package, however. If 'paint' is true, the equivalent of a 'PaintViewer[viewer,hint=caption] will be done. The menu registered under the name 'name' is added to the viewer's list of menus. If 'addBefore' is non-NIL, the new menu will be added in the list before the menu with name 'addBefore'. If 'paint' is true, the equivalent of a 'PaintViewer[viewer,hint=caption] will be done. 'menu' is made accessible to the human user. 'menu' is made inaccessible to the human user. If 'menu' is currently active, it is made inactive. Otherwise, it is made active. Returns TRUE if the menu already exists in the viewer, FALSE otherwise. operations to parse menu descriptions: The rope is parsed for multiple menu descriptions, as laid out in MenuBNF.tioga. Any errors are written to "errorFile." If 'prevlist' is not NIL, the returned list will be added to and "layered" on top of 'prevlist'. If 'errorFile' is NIL, errors will be written to "menus.errlog". If any errors are found, NIL will be returned. Κ’– "cedar" style˜JšΟc#™#J™J™ΊJ™J™0J™/J˜šΟk ˜ Jšœžœ ˜Jšœžœžœ˜Jšœžœ˜)J˜—Jšœžœž œžœ˜!J˜Jšœžœ˜$Jšžœžœžœ˜J˜Jšœ žœI˜VJšœžœžœžœ˜$Jšœ žœžœžœ žœžœžœ˜LJšœžœžœ˜$Jšœ$žœ žœ žœ˜IJšœ&žœžœžœ˜Ušœžœžœ˜$Jšœš™š—J™šœžœ˜Jšœd™d—J™Jšœ žœžœ˜J˜Jšœžœžœ ˜šœ žœžœ˜Jšœ˜Jšœžœžœ˜Jšœ žœžœ˜Jšœ žœžœ˜Jšœ#žœ˜'Jšœ žœžœ ž˜Jšœ˜Jšœ„žœΝ™ΥJ˜—Jšœžœžœ ˜šœ žœžœ˜Jšœžœ˜ Jšœ žœžœ˜Jš œ žœžœžœžžœ ˜RJšœ žœžœ ž˜J˜Jšœ?žœαžœ5žœ.™ŽJ˜—Jšœžœžœ ˜šœ žœžœ˜Jšœ¬žœΚ™ϊJšœ#˜9Jš œžœžœžœžœžœ(˜FJšœ ž œ˜Jš œžœžœžœžžœ ˜SJšœ žœžœ žœ˜#Jšœžœžœ žœ˜%Jšœžœžœ ž˜Jšœ˜—J˜šœ žœžœ˜Jšœ&˜9Jšœžœžœžœ@˜TJ˜J˜—šœ žœžœ˜Jšœ0˜CJšœžœžœžœ@˜TJ˜J˜—šœžœ˜)Jš-œ°™έ—J˜JšΟn œžœžœ4žœžœžœžœžœžœ˜‰J˜Jš Ÿ œžœžœžœžœžœ˜5J˜Jš6™6šŸ œžœ˜ Jšœ—™—J™—šŸœžœžœžœ˜GJšœ@™@J™—šŸœžœžœžœ˜6J™³J™—šŸœžœžœ˜>Jšœ'™'—J™J™&šŸ œžœžœžœ˜6Jšœς™ς—šŸœžœ!˜.Jšœžœžœžœ˜/Jšœ–™–—šŸ œžœ)žœžœ˜FJšœ.™.J™—šŸ œžœ)žœžœ˜HJšœ.™.J™—šŸœžœ)žœžœ˜BJšœR™RJ™—šŸ œžœ"žœ žœ˜NJšœžœ+žœ ™G—J˜J™&šŸœžœžœ žœžœžœ žœžœ˜WJšžœžœžœ˜Jšœžœ]žœFžœ™Ν—J˜Jšžœ˜—…— B$ώ