The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

FLTK::Input - One-line text input field

Description

This is the FLTK text input widget. It displays a single line of text and lets the user edit it. The text may contain any bytes (even \0). The bytes 0..31 are displayed in ^X notation, the rest are interpreted as UTF-8 (see utf8decode()).

The default when() is WHEN_RELEASE. This is fine for a popup control panel where nothing happens until the panel is closed. But for most other uses of the input field you want to change it. Useful values are:

WHEN_NEVER

The callback is not done, but changed() is turned on.

WHEN_CHANGED

The callback is done each time the text is changed by the user.

WHEN_ENTER_KEY

Hitting the enter key after changing the text will cause the callback.

WHEN_ENTER_KEY_ALWAYS

The Enter key will do the callback even if the text has not changed. Useful for command fields. Also you need to do this if you want both the enter key and either WHEN_CHANGED or WHEN_RELEASE, in this case you can tell if Enter was typed by testing event_key() == FLTK::EnterKey.

If you wish to restrict the text the user can type (such as limiting it to numbers, a particular length, etc), you should subclass this and override the replace() function with a version that rejects changes you don't want to allow.

If you don't like the keybindings you can override handle() to change them.

All arguments that are lengths or offsets into the strings are in bytes, not the UTF-8 characters they represent.

Functions

at

my $chr = $input->at( $index );

Same as text()[$index], but may be faster in plausible implementations. No bounds checking is done.

copy

my $okay = $input->copy( $to_clipboard );

Put the current selection between mark() and position() into the selection or clipboard by calling copy(). If position() and mark() are equal this does nothing (ie it does not clear the clipboard).

If to_clipboard is true, the text is put into the user-visible cut & paste clipboard (this is probably what you want). If to_clipboard is false, it is put into the less-visible selection buffer that is used to do middle-mouse paste and drag & drop.

To paste the clipboard, call paste(1) and fltk will send the widget a PASTE event with the text, which will cause it to be inserted.

cut

my $okay = $input->cut( );

Wrapper around replace(), this deletes the region between the point and the mark. It does nothing if they are equal.

my $okay = $input->cut( $length );

Wrapper around replace() this deletes up to length characters after the point, or before the point if length is negative. length is bounds checked.

my $okay = $input->cut( $begin, $end );

Wrapper around replace() this deletes the characters between begin and end. The values are clamped to the ends of the string, and end can be less than begin.

handle_key

my $handled = $input->handle_key( );

Handle KEY events. The default handle() method calls this. This provides an Emacs and Windows style of editing. Most Emacs commands are first run through try_shortcut() to test if they are menu items for the program.

Shift: do not move the mark when moving the point
LeftKey, Ctrl+B: move left one character
Ctrl+LeftKey, Alt+B: move left one word
RightKey, Ctrl+F: move right one character
Ctrl+RightKey, Alt+F: move right one word
Ctrl+A: go to start of line, if already there select all text
HomeKey: go to start of line
EndKey, Ctrl+E>: go to end of line
Ctrl+Insert: copy
Shift+Insert: paste
Shift+Delete: cut
Delete, Ctrl+D: delete region or one character
Ctrl+Delete, Alt+D: delete region or one word
BackSpace, Ctrl+H: delete region or left one character
Ctrl+BackSpace, Alt+H: delete region or left one word
Return, KeypadEnter: if when() & WHEN_ENTER_KEY, and no shift keys held down, this selects all and does the callback. Otherwise key is ignored.
Ctrl+K: cuts from the position to the end of line
Ctrl+C: copy
Ctrl+T: swap the two characters around point. If point is at end swap the last two characters.
Ctrl+U: delete all the text
Ctrl+V: paste
Ctrl+X, Ctrl+W: cut
Ctrl+Y: redo
Ctrl+Z, Ctrl+/: undo
All printing characters are run through compose() and the result used to insert text.

For Input widgets in WORDWRAP mode, you can also do these:

UpKey, Ctrl+P: move up one line
DownKey, Ctrl+N: move down one line
PageUpKey: move up 1 line less than the vertical widget size
PageDownKey: move down 1 line less than the vertical widget size
Ctrl+HomeKey, Alt+A: got to start of text
Ctrl+EndKey, Alt+E: go to end of text
Return, KeypadEnter: inserts a newline
Ctrl+O: insert a newline and leave the cursor before it.

This method may be overridden for subclassing.

insert

my $okay = $input->insert( $text );

Wrapper around replace(). This inserts the string at the point and leaves the point after it.

my $okay = $input->insert( $text, $length );

Wrapper around replace(). This inserts length characters from the text (including \0 characters!) at the point and leaves the point after it.

line_end

my $index = $input->line_end( $position );

Returns the location of the next newline or wordwrap space at or after position.

line_start

my $index = $input->line_start( $position );

Returns the location of the start of the line containing the position.

mark

my $mark = $input->mark( );
$input->mark( $new_mark );

Same as $input>position($input->position(),$index).

mouse_position

my $index = $input->mouse_position( $rectangle );

Figure out what character the most recent mouse event would be pointing to, assumming you drew the text by calling draw() with the same rectangle. Returns 0 if the mouse is before the first character, and size() if it is after the last one.

new

my $input = $input->new( $x, $y, $w, $h, $label );

Creates a new FLTK::Input object. Obviously.

position

my $pos = $input->position( );

Returns the current location of the cursor.

$input->position( $new_position );

Same as position($new_position, $new_position).

$input->position( $new_position, $new_mark );

The input widget maintains two pointers into the string. The "position" is where the cursor is. The "mark" is the other end of the selected text. If they are equal then there is no selection. Changing this does not affect the X selection, call copy() if you want that.

Changing these values causes a redraw(). The new values are bounds checked and limited to the size of the string.

It is up to the caller to make sure the position and mark are at the borders of UTF-8 characters!

replace

my $return = $input->replace( $begin, $end, $text, $length );

This call does all editing of the text. It deletes the region between begin and end (either one may be less or equal to the other), and then inserts length (which may be zero) characters from the string text at that point and leaves the mark() and position() after the insertion. If the text is changed the callback is done if the when() flags indicate it should be done.

begin and end are bounds checked so don't worry about sending values outside the length of the string.

reserve

$input->reserve( $newsize );

Reserve the interal private buffer of at least newsize bytes, even if the current text() is not that long. Can be used to avoid unnecessary memory reallocations if you know you will be replacing the text() with a longer one later.

size

my $length = $input->size( );

Returns the number of characters in text(). This may be greater than length($input-text())> if there are NULL characters in it.

static_text

my $ret = $input->static_text( $string, $length );

Same as text($string, $length), except it does not copy the string, instead it makes text() return a pointer to $string (unless $length is 0, in which case it makes it point to a zero-length string).

$string must point to static memory that will not be altered until at least the Input widget is destroyed or the text() is changed again. If the user attempts to edit the string it is then copied to the internal buffer and the editing done there. This can save a lot of time and memory if your program is changing the string to various constants a lot but the user rarely edits it.

my $ret = $input->static_text( $string );

Same as $input->static_text($string, $string ? length($string) : 0).

text

my $different = $input->text( $string, $length );

Change the text() to return the first length bytes of string and size() to return length, and set the position() to length and the mark() to zero (thus highlighting the entire value).

Returns true if the bytes in the new string are different than the old string.

my $different = $input->text( $string );

Same as $input->text($string, $string ? length($string) : 0).

my $string = $input->text( );

The current string, as edited by the user. size() returns how many bytes are in the string.

undo

my $okay = $input->undo( );

If this is the most recent widget on which replace() was done on, this will undo that replace() and probably several others (ie if the user has typed a lot of text it will undo all of it even though that was probably many calls to replace()). Returns true if any change was made.

up_down_position

$input->up_down_position( $position, $keepmark );

Does the correct thing for arrow keys. position must be the location of the start of a line. Sets the position (and mark if keepmark is false) to somewhere after position, such that pressing the arrows repeatedly will cause the point to move up and down.

word_end

my $index = $input->word_end( $position );

Returns the location of the next word boundary at or after position.

word_start

my $index = $input->word_start( $position );

Returns the location of the first word boundary at or before position.

xscroll

my $x = $input->xscroll( );

yscroll

my $y = $input->yscroll( );

Values for type

NORMAL
FLOAT_INPUT
INT_INPUT
SECRET
WORDWRAP

Subclassing FLTK::Input

The following methods may be overridden in subclasses of FLTK::Input:

handle

You may override handle which accepts an event and a rectangle. The passed rectangle is the area the text is to be drawn into. This method is provided so a subclass can place the text into a subrectangle.

The default handle...

  • Handles FOCUS, UNFOCUS

  • May do callback on HIDE

  • Any keystrokes call handle_key()

  • Handles PUSH, DRAG, RELEASE to select regions of text, move the cursor, and start drag & drop. Double click selects words, triple click selects lines (triple click is broken on Windows).

  • Receives drag&drop and accepts.

  • Handles PASTE events caused by accepting the drag&drop or by calling paste() (which handle_key() does for ^V)

handle_key

Handle KEY events. The default handle() method calls this. This provides an Emacs and Windows style of editing. Most Emacs commands are first run through try_shortcut() to test if they are menu items for the program.

Shift: do not move the mark when moving the point
LeftKey, Ctrl+B: move left one character
Ctrl+LeftKey, Alt+B: move left one word
RightKey, Ctrl+F: move right one character
Ctrl+RightKey, Alt+F: move right one word
Ctrl+A: go to start of line, if already there select all text
HomeKey: go to start of line
EndKey, Ctrl+E>: go to end of line
Ctrl+Insert: copy
Shift+Insert: paste
Shift+Delete: cut
Delete, Ctrl+D: delete region or one character
Ctrl+Delete, Alt+D: delete region or one word
BackSpace, Ctrl+H: delete region or left one character
Ctrl+BackSpace, Alt+H: delete region or left one word
Return, KeypadEnter: if when() & WHEN_ENTER_KEY, and no shift keys held down, this selects all and does the callback. Otherwise key is ignored.
Ctrl+K: cuts from the position to the end of line
Ctrl+C: copy
Ctrl+T: swap the two characters around point. If point is at end swap the last two characters.
Ctrl+U: delete all the text
Ctrl+V: paste
Ctrl+X, Ctrl+W: cut
Ctrl+Y: redo
Ctrl+Z, Ctrl+/: undo
All printing characters are run through compose() and the result used to insert text.

For Input widgets in WORDWRAP mode, you can also do these:

UpKey, Ctrl+P: move up one line
DownKey, Ctrl+N: move down one line
PageUpKey: move up 1 line less than the vertical widget size
PageDownKey: move down 1 line less than the vertical widget size
Ctrl+HomeKey, Alt+A: got to start of text
Ctrl+EndKey, Alt+E: go to end of text
Return, KeypadEnter: inserts a newline
Ctrl+O: insert a newline and leave the cursor before it.

Author

Sanko Robinson <sanko@cpan.org> - http://sankorobinson.com/

License and Legal

Copyright (C) 2008-2010 by Sanko Robinson <sanko@cpan.org>

This program is free software; you can redistribute it and/or modify it under the terms of The Artistic License 2.0. See the LICENSE file included with this distribution or notes on the Artistic License 2.0 for clarification.

When separated from the distribution, all original POD documentation is covered by the Creative Commons Attribution-Share Alike 3.0 License. See the clarification of the CCA-SA3.0.