home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!wupost!waikato.ac.nz!aukuni.ac.nz!cs18.cs.aukuni.ac.nz!jwil1
- Newsgroups: comp.sys.acorn.tech
- Subject: (long) Better definition of what menu template should do
- Message-ID: <1993Jan7.213310.16932@cs.aukuni.ac.nz>
- From: jwil1@cs.aukuni.ac.nz (TMOTA)
- Date: Thu, 7 Jan 1993 21:33:10 GMT
- Sender: jwil1@cs.aukuni.ac.nz (TMOTA)
- Organization: Computer Science Dept. University of Auckland
- Lines: 460
-
- Ah... I've just found that file I was working on a while back.
-
- This is a menu template system that I've designed around a text-file
- (i.e. easily editable) format for my own use. The main idea of this
- one is to give all the features listed below, while being small and
- reasonably efficient to implement, and easy and convenient to use from
- within your program. The text file format is very simple so as to
- force minimal parsing code on the application. Obviously a Glass file
- binary format for this data will reducethe file size and the amount of
- loading-support-code needed.
-
- Hopefully this will explain all the details of what I want out of a
- menu template system a bit better... Obviously the actual syntax of the
- file is of little relevance, but it still serves to illustrate the ideas.
-
- (sorry, 2400bps users, but it's a bit long)
-
- ---
-
- The Menu Template System
- by Jason Williams
-
- We already use template files containing definitions for windows in our
- applications: They make life much quicker and easier for the programmer,
- and allow the user to alter the layout of windows (at least to some extent)
- to suit themselves.
-
- However, a startling omission from RISC OS is the lack of a similar function
- for definition of menu structures. Partially this stems from the dynamic
- nature allowed by the menu system, but I feel it is mostly caused by laziness
- and mis-design of menus...
-
- In most cases, menus can be designed as fixed entities, with an occasional
- menu (a font list, for example) being created 'on the fly'. Much of the
- data-entry of menu items *should* be placed into dialogue boxes which are
- available in a menu, and by clicking a menu item, and by pressing a certain
- key-combination. Some other data may be placed as a group of 'tickable' menu
- items, in which the programmer currently has to do all the work of only
- allowing one item to be ticked at once. Another failing in many applications
- is that when they shade (make unselectable) an item which leads to a submenu,
- the submenu can no longer be brought up in order to see what is in it.
-
- The menu template system is a C code library which solves all of these
- problems in one go. It goes further than any attempt I have ever seen to
- provide a menu-template system.
-
- The template system, as well as providing an automated system by which menu
- templates can be loaded, and used to create menu trees, also gives functions
- which automatically handle menus in useful ways, and make menu decoding much
- simpler for the programmer.
-
- The fundamental concepts behind the template system are:
- * Text file (easily read/edited) contains the templates
- * Intermediate interface between the user, the OS and the program, with
- the program using tags to which menu items are attached, and the user
- being free to edit item data. Thus, the program doesn't have to worry
- about what language the menus are displaying, or where in the menu tree
- an item was when it was selected: A unique tag allows the user to move
- any item anywhere, and it will still operate as normal.
- * Extra automated handling to ease the work of the programmer. Correct
- menu shading and tickable-item e.s.g. handling are provided.
-
- ---
-
- Menu template file syntax
- =========================
-
- COMMENTS
- Blank lines, and any line whose first non-blank character is a '#' will
- be treated as comments. Everything on a line after a '#' will be ignored,
- excepting if the '#' appears in a string (between a pair of double quotes)
-
-
- TAGS
- Menus and their items are referred to using tags. For speed and simplicity
- these tags are 4 characters long, and are handled by the loading code in
- such a way as to allow
- definition in file: tag1
- comparison in C: if (thetag == 'tag1')
- switch (thetag)
- {
- case 'tag1':
- case 'tag2':
- }
- which really is extremely convenient.
- Tags can be defined as less than 4 characters, in which case, they will be
- padded out with space characters, so t1 will become the tag 't1 '.
-
- Item tags are localised within each menu definition, but *PLEASE* use
- globally unique tags for menu items. This will allow you to act on a
- selection of any menu item regardless of where it was situated in any menu
- tree. The user could then edit your menus to look completely different,
- split menus, and generally rearrange anything anywhere anytime, and your
- application would continue to run correctly, completely unaffected (except
- for the external menu interface for the user).
- This will also improve the chances of porting this code to work as an
- interface layer for other operating systems so that porting RISC OS WIMP
- applications to other WIMPs might be made easier.
-
- Menu tags should be different from all other menu tags, but need not be
- different from item tags.
-
-
- MENU
- A menu is a set of n items, with a header containing the menu tag, the
- title text, and the number of items in the menu. NOTE that the numitems
- value can be larger than the menu needs (for future menu adjustment), but
- must not be smaller.
- Each entry must be on a single separate line as shown:
-
- menu = MENU tag:4 "title" numitems
- item
- item
- ...
- ENDMENU
-
-
- ITEM
- Each item specifies the item tag, item text, and a set of space-separated
- flags.
-
- item = ITEM tag:4 text [flags]
-
-
- The text is an arbitrary string contained within double quotes (double quotes
- not allowed within the string: tough titty). For a writable icon, this string
- is used as the default text.
-
- text = "any string"
-
- The flags are explained in detail below.
- Each flag is separated by a space.
- A summary of the flags is:
-
- flags > ; has subwindow
- >menu ; has submenu "menu"
- _ ; dotted line after this item
- - ; "
- T01+ ; this item is tickable, with
- ; esg number 1 & is ticked
- K020 ; Key equivalent (decimal)
- ?6 ; Writable, 6 chars allowed
- S ; Shaded
-
- Full flag descriptions:
- >
- This specifies that the item should have a sublink arrow and generate a
- sublink message, for the program to provide the appropriate window.
-
- >menu
- This specifies that this item will bring up the named submenu.
-
- _ or -
- This specifies that the item is followed by a dotted line
- This may also be used on it's own on a line to indicate the same.
- (Everything after the first _ or - will be ignored)
-
- T00+
- This specifies that the item is tickable.
- The following decimal number (not optional) specifies the esg number for the
- tick. Values from 0 to 250 are allowed (251-255 are used internally as
- special values, so do not use them). The esg number of 0 is special,
- indicating no esg - the item is unrelated to any other items.
- ESGs are localised to within one (sub)menu definition.
- Optionally, this can be followed by a + which indicates that the item is
- ticked. If no + is present, the item is not ticked.
-
- K020
- This specifies the decimal wimp keycode for the key equivalent.
- You should also set the item text to show this key equivalent to the right
- side of the menu, in the standard format.
-
- ?6
- This indicates that the item is writable, with a maximum of 6 characters
- allowed in it. NOTE: This doesn't count the terminator (as the WIMP does),
- so 6 means allow up to 6 characters to be entered.
-
- S
- This indicates that the item should be shaded by default.
- (NOTE: If this item also has a submenu, the item will be made grey but will
- remain selectable in order to allow users to see the submenu. If such an
- item is shaded, all items below it recursively will be shaded as well, in
- the internal database, though, this 'global' shading is kept separate from
- individual item shading so that unshading a menu item will restore the
- previous single-item shading in the submenu.)
-
-
- QUICKKEYS
- This extra feature has been added, as it is very esy to integrate, and saves
- extra work along similar lines in another portion of your code.
- The quickkeys segment of the template file MUST be the last thing in the file
- (i.e. no menu definitions may follow it)
-
- It simply defines a set of mappings between tags and WIMP key codes. These
- are stored by the Menu manager, and when you request a check for a quickkey,
- the menu manager scans all the quick-keys in the menu items it owns, as well
- as the quick-key list. If any quick-key is matched, it's tag will be returned
- to your menu-selection handler. Thus, all possible functions should be given
- a unique tag and be connected by it into your menu-selection handler, so that
- your program becomes a simple macro processor (in future a scheme may be
- added whereby several tags may be attached to a keypress, such that a single
- keypress will be able to perform the equivalent of several menu selections
- in sequence)
-
-
- Example:
- menu save "Save format" 2 # Save submenu, 2 items
- item sav1 "Armadeus " > S # Shaded, has a sub-window
- item sav2 "DataVox " > # Has a sub-window
- endmenu
-
- menu optn "Options" 3 # Options submenu, 3 items
- item opt1 "Type 1" T01 # Tickable, esg = 1, not ticked
- item opt2 "Type 2" T01+ # Tickable, esg = 1, ticked
- item opt3 "Thingo" T00+ # Tickable, NO esg, ticked
- endmenu
-
- menu main "DSEdit II" 8 # Main menu, up to 8 items long
- info "Info ^I" K009 > # Key equiv. 9 (ctrl-I), subwindow
- ----------- # ...with dotted line underneath
- optn "Options " >optn S # optn (options) submenu, shaded
- save "Save " >save # save (save format) submenu
- ----------- # ...with dotted line underneath
- quit "Quit " # Nothing special about this item
- endmenu
-
- quickkeys # This must be last thing in file
- ok K13 # "OK" key is return
- canc K27 # "Cancel" key is escape
-
-
- Will generate this set of menus:
- +---------------+
- | DSEdit II |
- +---------------+
- | Info ^I => | -> to Info window
- | - - - - - - - | +---------+
- | Options => | | Options | +-------------+
- | Save => | +---------+ | Save format |
- | - - - - - - - | | Type 1 | +-------------+
- | Quit | |/Type 2 | | Armadeus => | -> to save-as window
- +---------------+ |/Thingo | | DataVox => | -> to save-as window
- +---------+ +-------------+
- The options submenu will automatically pop up from the "Options" item if you
- move the pointer over the arrow.
- The Save format submenu will automatically pop up from the "Save" item...
-
- As well as generating the menus, the above template will set up information
- needed ny the handers to handle various things such as ticked items, shading,
- submenu linking, and quick-keys automatically.
-
- ---
-
- Supplied Functions
- ==================
-
- Menu_Init(void)
- Initialises the menu system. Call this once (only) before you call any
- other menu functions. If not called, effects are unpredictable.
-
- BOOL Menu_LoadTemplates(char *filename)
- Loads all menus from the given template file, allocating exactly the
- needed space. Returns TRUE if it succeeds, FALSE if it fails.
-
- Menu_ReleaseTemplates()
- Deallocates the memory used by ALL the menus.
-
- Menu_Show(menutag menu, BOOL iconbar)
- Creates and opens the menu structure requested. If iconbar == TRUE, then
- the menu is placed at the correct height above the iconbar, else it is
- placed at the current mouse pointer position.
-
- Menu_Reopen()
- Re-opens the last menu created. Internal call called by Menu_Decode when
- an adjust-click is used on a menuitem.
-
- Menu_Decode(wimp_eventstr *event, menutag *menu, menutag *item)
- When you recieve a menu selection (9) event from the WIMP, for a menu
- you opened with a Menu_Open() call, call this function, which will decode
- the event into menu and item tags.
-
- If the item tag returned is menu_INVALID, ignore the event (do nothing)
- -This can occur from invalid selections and most notably from greyed
- items that have been left selectable to allow the user to see submenus.
- The menu decoder will work out if the selection is valid for you.
-
- Upon receipt, use the *item* tag to determine your action. If *absolutely*
- necessary, you can use the menu tag for this determination, but this will
- remove the ability for anyone to move items to arbitrary positions in
- the menu tree (Also, try to use globally unique tags, although this is
- not enforced by the menu code). The menu tag returned is meant to only
- be used if it is necessary to tick/shade the item or read data from a
- writable...
-
- Menu_CheckKey(wimp_eventstr *event, menutag *menu, menutag *item)
- When you recieve a keypress event from the WIMP, call this function to
- check for quick-keys after checking any more important keypresses. If
- it returns values other than menu_INVALID for the menu/item, then a
- quick-key is being requested, and you should pass these tags to the
- same handling code that you call on a menu selection event.
-
- Menu_ShadeItem(menutag menu, menutag item, BOOL shaded)
- Shades/unshades the given menuitem. Two different shading values are used
- by the menu system (really shaded, and just greyed out so that submenus can
- still be seen). The menu system will not return a click on either type
- of shaded icon. Shading/unshading an item in a globally-shaded menu will
- alter the internal database, but will only have a noticable effect when the
- entre menu is globally-un-shaded.
-
- Menu_TickItem(menutag menu, menutag item, BOOL ticked)
- Ticks/unticks the menu item, with the following provisos:
- * Won't alter an untickable item
- * Will only untick an item with esg 0, which indicates it is a 'loner'.
- If the item is part of an esg group, it will be ticked regardless.
- * Will search for other items of the same esg in the submenu, and will
- untick them, guaranteeing that only one of them is ever ticked.
-
- Menu_SetWritable(menutag menu, menutag item, char *newtext)
- Will set the text in a writable menu item to the given text. It will be
- truncated if necessary to fit the template buffer size.
-
- char *Menu_ReadWritable(menutag menu, menutag item)
- Returns a pointer to the text buffer of the writable. This should ONLY
- be treated as a read-only resource. Use the above call if you wish to
- write to this buffer. If you want to use/alter the text, make a copy
- of the string to your own workspace.
-
- Attaching your own submenus/tweaking the WIMP menu data
- If you want a dynamic menu (e.g. a font list) anywhere in your menus, you
- must create it separately yourself, and then attach it to the Menu_()
- created menu tree manually. If you want to 'twiddle' any of the base WIMP
- menu items (as passed to Wimp_CreateMenu), then you also need to build and
- show the menu in two steps.
-
- Example of adding a submenu:
- mainmenu = Menu_Build("main"); /* Create the main menu structure */
- itemptr = Menu_ReturnAddress("show","font");
- /* find the "Show => Font" submenu item */
- menuptr = Create_My_Font_Menu(); /* Create the font submenu */
- itemptr->sublink = menuptr; /* Link it in as this item's submenu */
- Menu_Open(mainmenu, FALSE);
-
- Changing other data for an item is a very similar process to the above.
-
- menu_block *Menu_Build(menutag menu)
- Recursively builds the given menu structure, returning a pointer to
- the WIMP menu definition block. You'll have to use Menu-ReturnAddress
- to chain down the menu structure to a leaf-item where you can attach
- your own submenu (e.g. a font menu), or you can attach this menu tree
- as a subtree of your own menu...
-
- Menu_ReturnAddress(menutag menu, menutag item)
- Returns the address of the last place to which this item was 'built'.
- (So be careful to only use this call when the menu has just been built)
- You can then modify the item's WIMP data directly to tweak things, attach
- your own dynamic submenus, etc.
- If the item tag passed in is menu_INVALID, the address of the menu header
- will be returned instead.
-
- Menu_Open(menu_block *menu, BOOL iconbar)
- Opens the WIMP menu defined in the given block under the pointer. If
- iconbar == TRUE, then it is opened at the appropriate height above the
- icon bar.
-
- ---
-
- Internal Data Structures
- ========================
-
- /* Actual WIMP menu blocks... */
- typedef struct
- {
- unsigned int ticked : 1;
- unsigned int dotted : 1;
- unsigned int writable : 1;
- unsigned int reserved1 : 4;
- unsigned int lastitem : 1;
- unsigned int reserved2 : 24;
- } menu_flags
-
-
- typedef union
- {
- int value;
- window_handle window;
- struct menu_item *submenu;
- }
-
-
- typedef struct
- {
- menu_flags flags;
- menu_sublink sublink;
- icon_flags iconflags;
- icon_data data;
- } menu_item;
-
-
- typedef struct
- {
- char title[12];
- int colours;
- int width;
- int height;
- int gap;
- /* menu_item items[]; */
- } menu_block;
-
-
- /* New structures for holding augmented menu structures... */
-
- /* ESG numbers: 0 means this is tickable, but not in any ESG (a loner)
- * 250-254 are reserved for future expansion
- * 255 means this is not tickable
- */
- #define ESG_LONER 0
- #define ESG_NOTICK 255
-
- #define menu_INVALID 0;
- typedef int menutag;
-
- typedef struct
- {
- unsigned int shaded :1; /* greyed and unselectable */
- unsigned int greyed :1; /* greyed, but still selectable */
- unsigned int writable :1; /* Item is writable */
- unsigned int ticked :1; /* This item is ticked */
-
- unsigned int lastitem :1; /* This is the last valid menu item */
-
- unsigned int reserved1 :3;
-
- unsigned int tickesg :8; /* Tickable esg number (see above) */
- unsigned int buffsize :8; /* Writable maximum text length */
-
- unsigned int reserved2 :8;
- } menuflags;
-
-
- typedef struct
- {
- menutag tag;
- menutag sublink; /* Either menu tag or SUBWINDOW */
- char *text; /* Pointer to text/writable buffer */
- menuflags flags;
- menu_item *lastaddress; /* Ptr to last place WIMP item for this was */
- } menuentry;
-
-
- typedef struct
- {
- menutag tag;
- char *title;
- menu_block *lastaddress; /* Ptr to last place WIMP defn for this was */
- char numitems; /* Max. # of items: size of allocated array */
- char menuwidth; /* Menu width (in characters) */
- menuentry *items; /* Pointer to array of items */
- } menuheader;
- --
- themasterofthearcanejwil1@cs.aukuni.ac.nzthismessagewassentonrecycledelectrons
-