Next: Other Input Routines, Previous: Input Types, Up: Part III Input Objects [Contents][Index]
Whenever the user presses the mouse inside an input field a cursor
will appear in it (and the field will change color to indicate that it
received the input focus). Further input will be directed into this
field. The user can use the following keys (as in emacs(1)
) to
edit or move around inside the input field:
<Backspace>
, <Ctrl>h
<Delete>
<Ctrl><Backspace>
<Ctrl><Delete>
<Ctrl>k
<Meta>h
<Ctrl>a
<Ctrl>e
<Ctrl>b
<Ctrl>f
<Ctrl>n
, <Down>
<Ctrl>p
, <Up>
<Meta>b
<Meta>f
<Home>
<End>
<Ctrl>u
<Ctrl>y
It is possible to remap the the bindings, see below for details.
A single click into the input field positions the cursor at the position of the mouse click.
There are three ways to select part of the input field. Dragging,
double-click and triple-click. A double-click selects the word the
mouse is on and a triple-click selects the entire line the mouse is
on. The selected part of the input field is removed when the user
types the <Backspace>
or <Delete>
key or replaced by
what the user types in.
One additional property of selecting part of the text field is that if
the selection is done with the left mouse button the selected part
becomes the primary (XA PRIMARY
) selection of the X Selection
mechanism, thus other applications, e.g., xterm
, can request
this selection. Conversely, the cut-buffers from other applications
can be pasted into the input field. Use the middle mouse button for
pasting. Note that <Ctrl>y
only pastes the cut-buffer generated
by <Ctrl>k
and is not related to the X Selection mechanism,
thus it only works within the same application. When the user presses
the <Tab>
key the input field is returned to the application
program and the input focus is directed to the next input field. This
also happens when the user presses the <Return>
key but only if
the form does not contain a return button. The order which input
fields get the focus when the <Tab>
is pressed is the same as
the order the input fields were added to the form. From within Form
Designer, using the raising function you can arrange (re-arrange) the
focus order, see Raising and Lowering, in Part II for details. If
the <Shift>
key is pressed down when the <Tab>
is
pressed, the focus is directed to the previous input field.
Leaving an input field using the <Return>
) key does not work for
multi-line input fields since the <Return>
key is used to start
a new line.
Per default the input object gets returned to the application (or the
callback set for the input object is invoked) when the input field is
left and has been changed. Depending on the application, other options
might be useful. To change the precise condition for the object to be
returned (or its callback to become invoked), the
fl_set_object_return()
function can be used with one of
the following values:
FL_RETURN_NONE
Never return or invoke callback
FL_RETURN_END_CHANGED
Default, object is returned or callback is called at the end if the field had been modified.
FL_RETURN_CHANGED
Return or invoke the callback function whenever the field had been changed.
FL_RETURN_END
Return or invoke the callback function at the end regardless if the field was modified or not.
FL_RETURN_ALWAYS
Return or invoke the callback function upon each keystroke and at the end (regardless if the field was changed or not)
See demo objreturn.c for an example use of this.
A few additional notes: when you read "the fields has been changed" this includes the case that the user e.g., deleted a character and then added it back again. Also this case is reported as a "change" (a delete alone isn’t) so the term "changed" does not necessarily mean that the content of the field has changed but that the user made changes (but which still might result in the exact same content as before).
Another term that may be understood differently is "end". In the
versions since 1.0.91 it means that the users either hits the
<Tab>
or the <Return>
key (except for multi-line
inputs) or that she clicks onto some other object that in principle
allows user interaction. These events are interpreted as an
indication the user is done editing the input field and thus are
reported back to the program, either by returning the input object
or invoking its callback. But unless the user goes to a different
input object the input field edited retains the focus.
Up to version 1.0.90 this was handled a bit differently: an "end of edit" event was not reported back to the program when the user clicked on a non-input object, i.e., changed to a different input object. This let to some problems when the interaction with the clicked-on non-input object dependet on the new content of the input object, just having been edited, but which hadn’t been been reported back to the caller. On the other hand, some programs rely on the "old" behaviour. These programs can switch back to the traditional behaviour by calling the new function (available since 1.0.93)
fl_input_end_return_handling(int type);
where type
can be either
FL_INPUT_END_EVENT_ALWAYS
, which is now the default, or
FL_INPUT_END_EVENT_CLASSIC
, which switches back to the type
of handing used in versions up and including to 1.0.90. The function
can be used at any time to change between the two possible types of
behaviour. The function returns the previous setting.
There is a routine that can be used to limit the number of characters
per line for input fields of type FL_NORMAL_INPUT
void fl_set_input_maxchars(FL_OBJECT *obj, int maxchars);
To reset the limit to unlimited, set maxchars
to 0. Note that
input objects of type FL_DATE_INPUT
are limited to 10
characters per default and those of type FL_SECRET_INPUT
to 16.
Although an input of type FL_RETURN_ALWAYS
can be used in
combination with the callback function to check the validity of
characters that are entered into the input field, use of the following
method may simplify this task considerably:
typedef int (*FL_INPUT_VALIDATOR)(FL_OBJECT *obj, const char *old, const char *cur, int c); FL_INPUT_VALIDATOR fl_set_input_filter(FL_OBJECT *obj, FL_INPUT_VALIDATOR filter);
The function filter()
is called whenever a new (regular)
character is entered. old
is the string in the input field
before the newly typed character c
was added to form the new
string cur
. If the new character is not an acceptable character
for the input field, the filter function should return
FL_INVALID
otherwise
FL_VALID
. If FL_INVALID
is returned, the new character
is discarded and the input field remains unmodified. The function
returns the old filter. While the built-in filters also sound the
keyboard bell, this doesn’t happpen if a custom filter only returns
FL_INVALID
. To also sound the keyboard bell logically or it
with
FL_INVALID | FL_RINGBELL
.
This still leaves the possibility that the input is valid for every
character entered, but the string is invalid for the field because it
is incomplete. For example, 12.0e is valid for a float input field for
every character typed, but the final string is not a valid floating
point number. To guard against such cases the filter function is also
called just prior to returning the object with the argument c
(for the newly entered character) set to zero. If the validator
returns FL_INVALID
the object is not returned to the
application program, but input focus can change to the next input
field. If the return value is FL_INVALID | FL_RINGBELL
the
keyboard bell is sound, the object is also not returned to the
application program and the input focus remains in the object.
To facilitate specialized input fields using validators, the following validator dependent routines are available
void fl_set_input_format(FL_OBJECT *obj, int attrib1, int attrib2); void fl_get_input_format(FL_OBJECT *obj, int *attrib1, int *attrib2);
These two routines more or less provide a means for the validator to
store and retrieve some information about user preference or other
state dependent information. attrib1
and attrib2
can be
any validator defined variables. For the built-in class, only the one
of type FL_DATE_INPUT
utilizes these to store the date format:
for attrib1
, it can take
FL_INPUT_MMDD
or
FL_INPUT_DDMM
and attrib2
is the separator between month
and day. For example, to set the date format to dd/mm
, use
fl_set_input_format(obj, FL_INPUT_DDMM, '/');
For the built-in type FL_DATE_INPUT
the default is
FL_INPUT_MMDD
and the separator is '/'
. There is no
limit on the year other than it must be an integer and appear after
month and day.
int fl_validate_input(FL_OBJECT *obj);
can be used to test if the value in an input field is valid. It
returns FL_VALID
if the value is valid or if there is no
validator function set for the input, otherwise
FL_INVALID
.
There are two slightly different input modes for input objects. In the
"normal" mode, when the input field is entered not using the mouse
(e.g., by using of the <Tab> key) the cursor is placed again at the
position it was when the field was left (or at the end of a possibly
existing string when it’s entered for the first time). When an input
object has a maximum number of allowed characters set (via the
fl_set_input_maxchars()
function) and there’s no room
left no new input is accepted until at least one character has been
deleted.
As an alternative there’s an input mode that is similar to the way things were handle in DOS forms etc. Here, when the field is entered by any means but clicking into it with the mouse, the cursor is placed at the start of the text. And for fields with a maximum capacity, that contain already as many characters as possible, the character at the end of the field are removed when a new one is entered.
To switch between the two modes use the function
where mode
is one of
FL_NORMAL_INPUT_MODE
FL_DOS_INPUT_MODE
For selecting the DOS-like input mode (in this mode, when a maximum number of characters has been set, as many characters already have been entered, and a new character is inserted somewhere in the middle the character at the very end gets deleted to make room for the new character)
The function returns the previous setting. Note that the function changes the input mode for all input fields in your application.
Next: Other Input Routines, Previous: Input Types, Up: Part III Input Objects [Contents][Index]