The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Curses::Widgets -- Curses-based widgets and functions

Doc/Module Version info

$Id: Widgets.pod,v 1.2 2000/03/17 00:30:03 corliss Exp corliss $

SYNOPSIS

        use Curses::Widgets;

        --or--

        use Curses::Widgets qw( :standard );    # same as above
        use Curses::Widgets qw( :functions );   # just functions
        use Curses::Widgets qw( :all );         # everything

REQUIREMENTS

Requires the Curses module, Curses or nCurses libraries. You must still 'use Curses;' in your script as well.

DESCRIPTION

This module provides a standard library of functions and widgets for use in creating Curses-based interfaces. Should work reliably with both Curses and nCurses libraries.

Current widgets include:

        Text field (txt_field)
        List box (list_box)
        Button sets (buttons)
        Calendar (calendar)
        Message box (msg_box)
        Input box (input_box)

Extra functions include:

        select_colour
        line_split
        grab_key
        init_scr

Note that all of the widgets strictly use named parameters, while the functions use unamed arguments. All of them either return values, or modify references that were passed as arguments.

Also note, for purpose of screen geometry, that all values passed for specifying 'cols' and 'lines' refers only to the dimensions of the actual content area, and does not include the border decorations. You will typically need to plan for an additional 2 for both 'cols' and 'lines' to account for these.

EXPORTED

Default

  • txt_field

  • buttons

  • list_box

  • calendar

  • msg_box

  • input_box

  • select_colour

  • init_scr

OK

  • line_split

  • grab_key

WIDGETS

Text field

The text field widget creates a derived window (which uses coordinates relative to the passed window) with a border surrounding the text. When used interactively, it handles its own input, passing back only the keys it doesn't know how to handle, as well as the final content string and cursor position.

If border decorations are enabled (they are, by default), the widget provides an arrow superimposed on the border to indicate whether there is content that can be scrolled to in that direction. The arrow only appears when the content exceeds the display area. The field is underlined if border decorations are turned off.

Currently, this widget will handle any normal characters to be inserted into the content string, and the following keys:

        Key             Curses Constant
        -------------------------------
        backspace       KEY_BACKSPACE
        delete          KEY_DC
        left arrow      KEY_LEFT
        right arrow     KEY_RIGHT
        up arrow        KEY_UP
        down arrow      KEY_DOWN
        page up         KEY_PPAGE
        home            KEY_HOME,KEY_FIND
        end             KEY_END,KEY_SEARCH

All parameters are passed as named parameters:

        Parameter       Commments
        -----------------------------------
        window          object handle to parent
                        window for the widget
        ypos            integer, optional,
                        default is 1
        xpos            integer, optional,
                        default is 1
        lines           integer, optional,
                        default is 1
        cols            integer, optional,
                        default is $COLS - 2
        content         string, optional,
                        default is "\n"
        password        integer, optional
                        default is 0
        pos             integer, optional
                        default is 0
        border          string, optional
                        default is 'red'
        decorations     integer, optional
                        default is 1
        edit            integer, optional
                        default is 1
        hz_scroll       integer, optional
                        default is 0
        function        reference, optional
        draw_only       integer, optional
                        default is 0
        l_limit         integer, optional
        c_limit         integer, optional
        title           string, optional
        regex           string, optional,
                        default is "\t"
        cursor_disable  integer, optional
                        default is 0

'window' is a object handle to a predefined window or subwindow. A quick tip for debugging: if either 'xpos', 'ypos', 'lines', or 'cols' cause any portion of the window to extend passed the boundaries of the parent window, the module will print an error message to STDERR, and immediately exit the routine--no attempt will be made to draw or activate the widget.

'border' is the English name of the common console colours. See the 'select_colour' function for a list of available colours.

'content' is a string containing the text you wish to fill the field with.

'password' will cause all text to show up as asterixs when printed. This is obviously intended for input that needs visual feedback, while maintaining content security.

'pos' refers to the cursor position for use in interactive mode, so that input can be inserted or appended to the content string. This is ignored if passed in conjunction with the draw_only parameter. Valid settings are 0 - length($string), or -1 to place the cursor at the end of the string.

'decorations' enables or disables the border/title/arrow decorations on the field. When disabled, the field will be underlined, to give some visual indication of the size of the field.

'edit' turns on or off editing capabilities in the widget. The field is still navigable with all special keys, but no cursor will be printed, and the content will not be affected by typed input.

'hz_scroll' enables horizontal scrolling in the text field, instead of the normal behaviour of splitting on white space and presenting a new line. This will only work with one line widgets. If you call this widget with any value of 'lines' greater than one, horizontal scrolling will automatically be disabled.

'function' is a scalar reference to a subroutine that can be called by the widget when it times out, waiting for input. For this to work, it assumes a halfdelay(10) has been called, or on some other interval.

'l_limit' and 'c_limit' are completely optional, and can be used together, if desired. Both are integers, and can limit the content in the text field. Which ever limit is hit first will be honoured.

'title' is an optional string that will be superimposed over the top-left border in reverse video.

'regex' is a string of all the characters that you wish to use to shift focus off the text field, and return the contents. By default, the tab character is used ("\t"). This string is interpolated inside of character class brackets, so don't include regex specific punctuation. If you wish both new lines and tabs to shift focus, you would use "\t\n".

'cursor_disable' disables the internal routine that prints it's own cursor. It's best used when you are passing it a background function that updates another portion of the screen, otherwise, when that update occurs, the cursor would disappear from the field. However, if you don't have such a function, the cursor will appear right next to the software cursor, giving it the appearance of a two character cursor. In those situations, you should use this option to disable the software cursor.

The memory allocated for the window is released when the widget routine exits.

        B<Example (non-Interactive)>

        txt_field( 'window'     => $window,
                   'ypos'       => 2,
                   'xpos'       => $COLS - 5,
                   'lines'      => $LINES - 10,
                   'cols'       => $COLS - 10,
                   'content'    => $note,
                   'border'     => 'red',
                   'draw_only'  => 1);
        
        B<(Interactive)>

        ($key, $rtrnd_note, $pos) = txt_field( 'window' => $window,
                                         'ypos'         => 2,
                                         'xpos'         => $COLS - 5,
                                         'lines'        => $LINES - 10,
                                         'cols'         => $COLS - 10,
                                         'content'      => $note,
                                         'border'       => 'green',
                                         'pos'          => length($note),
                                         'function'     => \&clock);

List box

The list box widget creates a derived window that holds a scrollable list of items, surounded by a border. When called interactively, it handles it's own input for navigation. Any keys not used for navigation are returned, as well as the currently selected item, unless the 'regex' option is used. If so, it will only return if the key matches the regex.

        Key             Curses Constant
        -------------------------------
        up arrow        KEY_UP
        down arrow      KEY_DOWN
        page up         KEY_PPAGE
        page down       KEY_PPAGE

The widget provides an arrow superimposed on the border to indicate whether there is content that can be scrolled to in that direction. The arrow only appears when the content exceeds the display area.

All parameters are passed as named parameters:

        Parameter       Commments
        -----------------------------------
        window          object handle to parent
                        window for the widget
        ypos            integer, optional,
                        default is 1
        xpos            integer, optional,
                        default is 1
        lines           integer, optional,
                        default is 1
        cols            integer, optional,
                        default is $COLS - 2
        list            hash or array reference
        border          string, optional
                        default is 'red'
        selected        integer, optional,
                        default is first element
        function        reference, optional
        draw_only       integer, optional
                        default is 0
        title           string, optional
        regex           string, optional
        sort            string, optional
                        default is 'numeric'

All previously described parameters maintain their same use and warnings.

'list' can be either a hash reference or an array reference. If a hash is passed, the value will be displayed, but the key will be returned as the selected entry. The list will also be numerically sorted according to key value when displayed.

If 'list' is an array reference, the list will be displayed in array order, and the index number of the element will be returned as the selected value.

'regex' works in the same manner as the the equivalent option in txt_field.

'sort' determines the type of sort used on the key values of lists passed as hashes (it has no affect on lists passed as lists). It defaults to a 'numeric' sort, but if you wish it to use an 'alphabetic' sort, you just need to set it accordingly.

        B<Example (non-Interactive)>

        list_box( 'window'      => $main,
                  'ypos'        => 2,
                  'lines'       => 10,
                  'cols'        => 25,
                  'list'        => \%list,
                  'border'      => 'red',
                  'selected'    => 1,
                  'draw_only'   => 1);

        b<(Interactive)>

        ($input, $selected) = list_box( 'window'        => $main,
                                        'ypos'          => 2,
                                        'xpos'          => 5,
                                        'lines'         => 10,
                                        'cols'          => 25,
                                        'list'          => \@list,
                                        'border'        => 'green',
                                        'selected'      => $last,
                                        'function'      => \&clock);

Button set

The button bar creates a derived window as well, printing the passed buttons, and handles the key strokes to navigate amongst them, while passing any other keystrokes and the currently selected button. The button set can be rendered either vertically or horizontally, and the keystrokes that can be used for navigation depend upon that. Like the list_box, if the 'regex' option is used, it will only return on matching values.

        Key             Curses Constant
        -------------------------------
        left arrow      KEY_LEFT
        right arrow     KEY_RIGHT
        up arrow        KEY_UP
        down arrow      KEY_DOWN

All parameters are passed as named parameters:

        Parameter       Commments
        -----------------------------------
        window          object handle to parent
                        window for the widget
        buttons         reference
        ypos            integer, optional,
                        default is 1
        xpos            integer, optional,
                        default is 1
        active_button   integer, optional
        function        reference, optional
        vertical        integer, optional
        draw_only       integer, optional
                        default is 0
        spacing         integer, default is 2
        regex           string, optional

Again, all previously described parameters remain the same. Boundary checking is still done for the entire bar, and if it exceeds them it will simply be skipped without drawing, while sending an error message stating as much to STDERR.

'buttons' is an array reference with each element a separate button. 'active_button' is the element's positional reference. 'spacing' is the number of whitespace used to separate the buttons (spaces in horizontal mode, lines in vertical mode).

If 'vertical' is passed with a Perlish true value the button set will be rendered as a vertical set.

        B<Example (non-Interactive)>

        buttons( 'window'       => $win_bar,
                 'buttons'      => \@buttons,
                 'active_button'=> 2,
                 'draw_only'    => 1);

        b<(Interactive)>

        ($input, $selected) = buttons( 'windows'        => $win_bar,
                                       'buttons'        => \@buttons,
                                       'active_button'  => $last,
                                       'function'       => \&clock);

Calendar

The calendar widget creates a fully navigable calendar in a derived, bordered window. The calendar controls its own input until it captures a keystroke it doesn't explicitly handle. In that case, it returns the key. Like the button_bar and list_box, though, this widget has a regex function.

        Key             Curses Constant
        -------------------------------
        left arrow      KEY_LEFT
        right arrow     KEY_RIGHT
        up arrow        KEY_UP
        down arrow      KEY_DOWN
        home            KEY_HOME
        page up         KEY_PPAGE
        page down       KEY_NPAGE

The home key, in this case, moves the selected date to the the current date. The page up and down keys move the calendar from month to month.

All parameters are passed as named parameters:

        Parameter       Commments
        -----------------------------------
        window          object handle to parent
                        window for the widget
        ypos            integer, optional,
                        default is 1
        xpos            integer, optional,
                        default is 1
        date_disp       reference
        border          string, optional
                        default is 'red'
        function        reference, optional
        draw_only       integer, optional
                        default is 0
        t_colour        string, optional
                        default is 'yellow'
        e_colour        string, optional
                        default is 'red'
        events          reference
        regex           string, optional

'date_disp' is an array reference that holds the desired date to display (in day, month, year format). If date_disp is not passed (or an empty list reference is given instead), it will be initialised with the current date. Should the widget be called in interactive mode, the reference will be modified to display the last date navigated to by the user. The first element, [0], is the day, the second, [1], the month, and the third, [2], the year.

't_colour' highlights the current date in the desired colour. If colour is not available, then the current date will be displayed in bold. 'e_colour' will highlight each date found in the 'events' array ref in the desired colour. Date formats for the 'event' array must be 'dd/mm/yyyy', with no leading zeros.

        B<Example (non-Interactive)>

        calendar( 'window'      => $main,
                  'date_disp'   => \@date,
                  'border'      => 'red',
                  'draw_only'   => 1);

        B<(Interactive)>

        $input = calendar( 'window'     => $main,
                           'date_disp'  => \@date,
                           'border'     => 'blue',
                           'function'   => \&clock);

Message Box

The msg_box displays the passed message in a new window that erases once acknowledged. It automatically scales and centers itself according to the console and the passed message.

        Parameter       Commments
        -----------------------------------
        title           string, optional
        message         string, optional
        border          string, optional
                        defaults to 'blue'
        function        reference, optional
        mode            integer, optional

All previously described options remain the same. It only responds to the ENTER or space key. Mode refers to the buttons drawn with the message. By default, it only draws an OK button, but if set to 2, it will display both an OK and a CANCEL button. In that instance, the widget will return a 1 if OK was selected, or a 0 if CANCEL was selected.

        B<Example>

        msg_box( 'title'        => "Critical Error!",
                 'message'      => "Now, you've done it!",
                 'border'       => "red");

Note that there is a minimum needed console size for this to work, which is currently 5 rows by 14 columns. If the console size is at least that size, the message box will render. Also note, though, that both the message and the title may get chomped down to alloted window space, if you pass it more than it can display.

Further, if the function parameter is used, and the passed function updates the screen, you may see the message box disappear, though it is still trapping key strokes. To avoid this behaviour, refresh the current screen before calling this function.

Input Box

The input_box displays a dialog box with a prompt, a one-line input field, and a two buttons, OK and CANCEL. Like the msg_box, this widget automatically scales and centers itself according to the prompt.

Unlike the msg_box, however, this widget returns two values; the first being the value of the text field, the second being a 1 if the OK button was pressed, or a 0 if the CANCEL button was pressed. Hitting ENTER while in the text field is a shortcut for pressing the OK button.

        Parameter       Commments
        -----------------------------------
        title           string, optional
        prompt          string, optional
        cols            integer, optional
        border          string, optional
                        defaults to 'blue'
        f_colour        string, optional
                        defaults to 'yellow'
        c_limit         defaults to 4096
        content         string, optional
        function        reference, optional

'cols' overrides the internally calculated width requirements (formerly determined by the prompt width) to the specified setting. This forces the field width to be cols - 2 in width as well.

'f_colour' is the colour to use for the text field border when it has the focus. It will use the same colour set in 'border'

This widget requires a minimum console size for this to work, which is 8 rows by 24 columns. Both the title and the prompt may be chomped to accomodate available screen space.

'c_limit' is simply passed to the text widget to restrict the length of the typed string. Horizontal scrolling is enabled.

        B<Example>

        ($field, $button) = input_box( 'title'          => 'Password',
                                       'prompt'         => 'Enter Password:',
                                       'border'         => 'blue');

If the function parameter is used, and the passed function updates the screen, you may see the message box disappear, though it is still trapping key strokes. To avoid this behaviour, refresh the current screen before calling this function.

FUNCTIONS

select_colour

Usage: select_colour($window, foreground [, background])

This function sets the character attributes for all subsequent characters to the specified colour, for the specified window. The first two arguments are required, the first being an object handle to the window, and the second a string denoting the desired foreground colour. A background colour can also be given, but if not, it defaults to black.

Valid colours are black, cyan, green, magenta, red, white, blue, and yellow. All attributes stay in effect until another set is declared, or all attributes are reset via attrset(0).

        B<Example>

        select_colour($main, 'yellow');

init_scr

Usage: init_scr($miny, $minx)

This function tests the terminal for both minimum dimensions and interactivity. If either condition is detected to be unsatisfactory, it produces a warning on STDERR, and returns a false condition. If it tests okay, however, it will return a handle to a new Curses object. It will also set the default keypad, halfdelay, noecho, and cbreak options.

The miny and minx, minimum lines and columns, respectively, are optional. If omitted, the standard console size of 25 lines by 80 columns will be checked for.

        B<Example>

        $mwh = init_scr(40, 80);

line_split (not exported by default)

Usage: line_split(string, line_length)

This function returns the submitted string as a list, each element being a separate line. It accounts for not only column limits, but whitespace as well, splitting a sentence by whitespace, so as to not break words.

        B<Example>

        @lines = line_split($note, 80);

grab_key (not exported by default)

Usage: grab_key($wh [, \&func_ref])

This function returns the pressed key, calling the passed function reference while waiting.

Only the first argument is mandatory, that being the object handle for the window gathering the key strokes. The function reference passed will be called while waiting for a key to pressed, but only works if you've initialised the console for half-blocking mode. Ie., to call that function every half a second:

        halfdelay(5);

Troubleshooting

Curses::Widgets will never intentionally kill your script. It does do some basic checks before executing some routines, and if it finds something amiss, it will use the warn function to report the error.

When testing scripts that use this module, you'd be well advised to pipe STDERR to a file, so that it doesn't mess with the current display. Checking that file later will show you what specific areas of the script have problems. Otherwise, the display might become corrupted, and cause perfectly valid function calls to appear screwey, when it was only the fact that the STDERR moved the cursor location before the next STDOUT output could be rendered.

You should also consider overloading the __DIE__ signal handler, to make sure that Curses returns your terminal to a usable state in case of fatal errors.

If you run into problems that appear to be the fault of the module, please send me the STDERR output and a script that demonstrates the problem.

HISTORY

See the Changelog for in depth change history. So far, I haven't broken any of the default exported functions, so most scripts should run unmodified.

2000/02/21 -- v1.1 Improved error handling/reporting, misc bug fixes, and major feature additions to the input_box, txt_field, list_box, and calendar. Added init_scr function 2000/01/15 -- v1.0 Version promotion for first stable release 2000/01/15 -- v0.10 Degugging, added input_box, msg_box widgets 1999/11/17 -- v0.9 Internal calendar generation, improved error handling/ reporting, added spacing argument to button bar, removed init_colours function 1999/06/17 -- v0.8 Added line_split function, title options, minor rewrites 1999/04/14 -- v0.7 Added l_limit/c_limit to text field 1999/02/02 -- v0.6 Colour-capability detection added, up/down charactersadded for content out-of-view indication, additional debugging 1999/01/11 -- v0.5 Debugging 1999/01/10 -- v0.4 Special key support added, special character constants used, new select_colour function 1999/01/03 -- v0.3 rewrite/optimisation 1998/12/30 -- v0.2 rewrite/optimisation 1998/12/29 -- v0.1 Initial release (text field, list box, buttons, calendar)

AUTHOR

All bug reports, gripes, adulations, and comments can be sent to Arthur Corliss, at corliss@odinicfoundation.org.