HELP PWMMENUS                                   Ben Rubinstein, Dec 1986
                                             Revised: Nic Ford, Apr 1987
                                        Revised: Gareth Palmer, Sep 1989

Making and using pop-up menus with the POPLOG Window Manager.

Keywords: PWM, menu, mouse, WIMP

    pwm_make_menu(<string>) -> <menu-id|false>

    pwm_display_menu(<menu-id|string>) -> <integer|false>
    pwm_display_menu(<menu-id|string>,
                    <window-id>, <integer:X>, <integer:Y>) -> <integer|false>

    pwm_make_menucall(<menu-id|string>, <list|vector>, <procedure|false>)
                                                        -> <integer|false>
    pwm_kill_menu(<menu-id>)

== CONTENTS - (Use <ENTER> g to access sections) ==

 -- Introduction
 -- Menu specifications
 -- Creating and destroying menus
 -- Using menus
 -- Menu trees: pwmselectedmenu

-- Introduction -------------------------------------------------------

The POPLOG Window Manager (see HELP *PWM) includes facilities for
offering the user menus from which they can select with the mouse.  A
menu is a static object which must be created and destroyed and which
can be displayed at any time in between these events.  Once created, a
menu is referenced by a special object, a "menu-id".

A menu consists of an optional title followed by items offering
choices to the user.  It is possible to specify that an item should be
displayed (usually in a lighter colour) but not selectable; and some
items can be separated by a horizontal bar.

Not all window systems support all these features: some may require all
menus to have a title, in which case an empty title will be used if you
don't specify one. Some don't allow non-selectable items; in this case,
if the user selects an item which you specified as non-selectable, the
PWM will report that none of the items were selected.  Some don't
provide horizontal bars: in this case requests for such a bar will be
ignored. In short, a legal specification of a menu will be accepted by
any PWM; where necessary, it will degrade gracefully.

-- Menu specifications ------------------------------------------------

Menus are defined by a string, which consists of the title (if any), and
the options which the user can select.  Each of these items is separated
by a control character: either `\t` (ASCII 9) or `\b` (ASCII 8).  The
second of these characters is used to request that a bar should be
displayed separating the preceding item from the following one
(mnemonic `\b`=Bar).

The first item is assumed to be a title: if it is empty (i.e. the
first character in the string is one of the separator characters) this
specifies that no menu is required.

Finally, the first character of an option can be one of the control
characters `\^N` or `\^A`.  The first specifies that this item is a
normal, selectable, option (mnemonic `\^N`=Normal); the second that this
should be a non-selectable option (mnemonic `\^A`=Advisory). If neither
one is specifed, the item is taken to be a normal selectable option.
(These options cannot be specified for the title, which is never
selectable: if one is given, it will be ignored.)

An example may make this clearer.  The following string:

    'Help level\tOne\tTwo\t\^AThree\bNone\t'

specifies a menu with the title "Help level", and four options, "One",
"Two", "Three" and "None"; the third item should be displayed but
non-selectable; and there should be a bar between the first three items
and the last one.

-- Creating and destroying menus --------------------------------------

A new menu can be created by the call

    pwm_make_menu(<string>) -> <menu-id|false>

The string is as described above: the result of the call is either a PWM
identifier object (see HELP *PWMWINDOWS) or false.  If the result is an
identifier, the PWM has succesfully parsed the menu specification string
as described above; it has now stored a description of the menu, and you
can reference it using the identifier.  If it is false, then something
went wrong: the most likely explanations are that either there was an
error in the string, or the PWM had no room to store another menu
definition.  It could also return false if there was an error in
communicating with the PWM: this can be checked by examining the
variable -pwmgotreport- (see HELP *PWMGENERAL).

If the PWM was unable to store the menu definition because it was
already storing too many menus, you should destroy one or more of the
menus that the PWM is currently storing.  The procedure

    pwm_kill_menu(<menu-id>)

instructs the PWM to forget the definition of the specified menu, and
reclaim the resources associated with it.  This will allow more menus
to be created.  The identifier can no longer be used, since the menu
it refers to no longer exists.

-- Using menus --------------------------------------------------------

To use a menu, it is displayed on screen and the PWM waits for the user
to select one of the options, or reject all of them.  The basic call is

    pwm_display_menu(<menu-id|string>) -> <integer|false>

As can be seen, a title string as described above can be supplied in the
place of a menu identifier (in fact, in some versions of the PWM not all
menu procedures, -pwm_make_menu- for one, have been implemented, and so
-pwm_display_menu- can only be called with a string). This form is
useful for menus whose content is likely to be useful only for one call;
it also avoids the problem of the PWM having used up all the space
allocated for storing menus. False is returned if something went wrong
(see HELP *PWMGENERAL); otherwise the call returns an integer, which is
either the number of the option the user selected, or zero if none of
them were selected.

The PWM will determine where on the screen to display the menu
(generally it will try and display it close to the mouse): however,
there is another form which allows you to suggest a position for the
menu, as a coordinate relative to a window:

    pwm_display_menu(<menu-id|string>, <window-id>, <integer:X>, <integer:Y>)
                                                    -> <integer|false>

In the above form also, instead of a menu-id for a previously defined
menu, you can pass a menu-specification string.

It is often the case that you want to call one of a list of procedures
according to which item the user picked off a menu.  To make this
easier, the function -pwm_make_menucall- takes some arguments for either
call form of -pwm_display_menu-, and two additional arguments; a list or
vector of procedures, one for each option on the menu, and another
procedure or false:

    pwm_make_menucall(<menu-id|string>, <list|vector:P>, <procedure|false:D>)
        -> <integer|false>

First -pwm_display_menu- will be called.  If the user selects one of the
options, the corresponding procedure from P will be called.  If,
however, -pwm_display_menu- returned zero or false, and you supplied D
as a procedure it will be called with the result (i.e. zero or false).
If you supply false as the last argument, then no action will be taken
if none of the options are picked; and in all cases the value returned
by -pwm_display_menu- will be returned by -pwm_make_menucall- (after
calling a procedure as appropriate if any of the options were selected).

As an example

    pwm_make_menucall('Range:\tCopy\tDelete\t', [^ved_copy ^ved_d], false) ->;

will create a two entry menu with the title "Range:", and allow the user
to choose one of the options "Copy" or "Delete", resulting in a call of
-ved_copy- or -ved_d- respectively. The default procedure is actually
passed to -pwm_make_menucall- as "false", so if neither option is chosen
no further action is taken. In any case, the integer representing the
choice (or false, if there was any problem) is discarded.

-- Menu trees: pwmselectedmenu ----------------------------------------

In the future, the menu definitions will be extended to support
heirarchichal menus, (cf. Sun "walking menus").  This will be done in an
upwardly compatible manner: for the present it can be noted that the
variable -pwmselectedmenu- holds the identifier of the menu from which the
most recent selection was made, or false if the selection came from a
menu that was not first defined (in which case it must be the top-level
menu).  Currently, therefore, this variable can be ignored.

--- C.pwm/help/pwmmenus ------------------------------------------------
--- Copyright University of Sussex 1987. All rights reserved. ----------
