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]