Up: Part IV Events [Contents][Index]

### 26.1 Shortcuts

The Forms Library has a mechanism of dealing with keyboard shortcuts. In this way the user can use the keyboard rather than the mouse for particular actions. Obviously, only "active" objects can have shortcuts (i.e., not objects like boxes, texts etc.).

The mechanism works as follows. There is a routine

    void fl_set_object_shortcut(FL_OBJECT *obj, const char *str,
                                int showit);

with which one can bind a series of keys to an object. E.g., when `str` is `"acE#d^h"` the keys `'a'`, `'c'`, `'E'`, `<Alt>d` and `<Ctrl>h` are associated with the object. The precise format is as follows: Any character in the string is considered as a shortcut, except `'^'` and `'#'`, which stand for combinations with the `<Ctrl>` and `<Alt>` keys. (The case of the key following `'#'` or `'^'` is not important, i.e., no distiction is made between e.g., `"^C"` and `"^c"`, both encode the key combination `<Crl>C` as well as `<Crtl>C`.) The key `'^'` itself can be set as a shortcut key by using `"^^"` in the string defining the shortcut. The key `'#'` can be obtained as a shortcut by using th string `"^#"`. So, e.g., `"#^#"` encodes `<ALT>#`. The `<Esc>` key can be given as `"^["`.

Another special character not mentioned yet is `'&'`, which indicates function and arrow keys. Use a sequence starting with `'&'` and directly followed by a number between 1 and 35 to represent one of the function keys. For example, `"&2"` stands for the `<F2>` function key. The four cursors keys (up, down, right, and left) can be given as `"&A"`, `"&B"`, `"&C"` and `"&D"`, respectively. The key `'&'` itself can be obtained as a shortcut by prefixing it with `'^'`.

The argument `showit` tells whether the shortcut letter in the object label should be underlined if a match exists. Although the entire object label is searched for matches, only the first alphanumerical character in the shortcut string is used. E.g., for the object label `"foobar"` the shortcut `"oO"` would result in a match at the first `o` in `"foobar"` while `"Oo"` would not. However, `"^O"` and `"#O"` would match since for keys used in combination with `<Crtl>` and `<Alt>` no distiction is made between upper and lower case.

To use other special keys not described above as shortcuts, the following routine must be used

    void fl_set_object_shortcutkey(FL_OBJECT *obj, unsigned int key);

where `key` is an X KeySym, for example `XK_Home`, `XK_F1` etc. Note that the function `fl_set_object_shortcutkey()` always appends the key specified to the current shortcuts while `fl_set_object_shortcut()` resets the shortcuts. Of course, special keys can’t be underlined.

Now, whenever the user presses one of these keys, an `FL_SHORTCUT` event is sent to the object. The key pressed is passed to the handle routine (in the argument `key`). Combinations with the `<Alt>` key are given by adding `FL_ALT_MASK` (currently the 25th bit, i.e., `0x1000000`) to the ASCII value of the key. E.g., the key combinations `<Alt>E` and `<Alt>e` are passed as `FL_ALT_MASK + 'E'`. The object can now take action accordingly. If you use shortcuts to manipulate class object specific things, you will need to create a routine to communicate with the user, e.g., `fl_set_NEW_shortcut()`, and do your own internal bookkeeping to track what keys do what and then call `fl_set_object_shortcut()` to register the shortcut in the event dispatching module. The idea is NOT that the user himself calls `fl_set_object_shortcut()` but that the class provides a routine for this that also keeps track of the required internal bookkeeping. Of course, if there is no internal bookkeeping, a macro to this effect will suffice. For example `fl_set_button_shortcut()` is defined as `fl_set_object_shortcut()`.

The order in which keys are handled is as follows: First for a key it is tested whether any object in the form has the key as a shortcut. If yes, the first of those objects gets the shortcut event. Otherwise, the key is checked to see if it is `<Tab>` or `<Return>`. If it is, the `obj->wantkey` field is checked. If the field does not contain `FL_KEY_TAB` bit, input is focussed on the next input field. Otherwise the key is sent to the current input field. This means that input objects only get a `<Tab>` or `<Return>` key sent to them if in the `obj->wantkey` field the `FL_KEY_TAB` bit is set. This is e.g., used in multi-line input fields. If the object wants all cursor keys (including `<PgUp>` etc.), the `obj->wantkey` field must have the `FL_KEY_SPECIAL` bit set.

To summarize, the `obj->wantkey` field can take on the following values (or the bit-wise or of them):

`FL_KEY_NORMAL`

  The default. The object receives left and right cursor, `<Home>` and `<End>` keys plus all normal keys (0-255) except `<Tab>` `<Return>`.

`FL_KEY_TAB`

  Object receives the `<Tab>`, `<Return>` as well as the `<Up>` and `<Down>` cursor keys.

`FL_KEY_SPECIAL`

  The object receives all keys with a KeySym above 255 which aren’t already covered by `FL_KEY_NORMAL` and `FL_KEY_TAB` (e.g., function keys etc.)

`FL_KEY_ALL`

  Object receives all keys.

This way it is possible for a non-input object (i.e., if `obj->input` is zero) to obtain special keyboard event by setting `obj->wantkey` to `FL_KEY_SPECIAL`.

Up: Part IV Events [Contents][Index]