man Newt () - Perl bindings for Red Hat newt library

NAME

Newt - Perl bindings for Red Hat newt library

SYNOPSIS

  use Newt;

  Newt::Init();
  Newt::Cls();

  #A lot of Newt operations...

  Newt::Finished();

DESCRIPTION

The Newt module implements perl bindings for the Red Hat newt windowing system, a terminal-based window and widget library for writing applications with a simple, but user-friendly, interface.

Basic Newt functions

Starts Newt services. You must use this command first. Ends Newt services. Clears the background. Foreces an inmediate update of the modified portions of the screen. Sends a beep to the terminal. Returns a tuple containing the screen dimensions.

Keyboard input

Stops program execution until a key is pressed. Discards the contents of the terminal\'s input buffer without waiting for additional input.

Drawing text on the root window

Displays the text in the indicated position. Saves the current help line on a stack and displays the new line. If the text is null, Newt\'s default help line is displayed. If text is a string of length 0, the help line is cleared. Replaces the current help line with the previous one. It is important not to pop more lines than the ones pushed.

Suspending Newt applications

By default, Newt programs cannot be suspended by the user. Instead, programs can specify a callback function which gets invoked whe the user presses the suspend key. To register such function, you can do something like this:

    sub my_cb {
      ...
    }

    Newt::SetSuspendCallback(\&my_cb);

or like this:

    Newt::SetSuspendCallback(sub {
                               ...
                             });

If the application should suspend and continue like most user applications, the suspend callback needs two other newt functions:

    Newt::Suspend();
    Newt::Resume();

The first one tells Newt to return the terminal to its initial state. Once this is done, the application can suspend itself by sending SIGSTP, fork a child program or whatever. When it wants to resume using the Newt interface, is must call CWNewt::Resume() before doing so.

For more information on suspending newt applications, read the original newt documentation.

Components

Components are the basic blocks for construction of Newt interfaces. They all are created in a similar manner. You just have to call the constructor to receive a blessed object of the specified class:

    $object = Newt::Foo();

Once you have a component, you can add it to a panel to create a complex user input interface.

General component manipulation

You can attach a callback for a component like this:

    sub comp_cb {
        ...
    }

    $component->AddCallback(\&comp_cb);

or like this:

    $component->AddCallback(sub {
                              ...
                            });

Exactly when (if ever) the callback is invoked depens on the type of the component.

Yo can tell if a component takes or not focus when traversing a form with the following function:

    $component->TakesFocus($true_or_false);

It is handy to set some arbitrary information on a component for later retrieval. You do this by setting its tag:

    $button->Tag("OK");

If you call this function without an argument, it replies with the actual tag for that component.

In general when the return value of any method of a component isn\'t described the method returns the component itself to allow constructions like:

    $panel
        ->Add(0,0, $componet1->Set( .... ) )
        ->Add(0,1, Newt::Label( .... ) )
        ->Add(0,2, Newt::Panel( .... )
            ->Add( .... )
            ->Add( .... ) )
        ->Add( .... );

Buttons

There are two kinds of buttons: full and compact:

    $normal_button = Newt::Button($text);
    $compact_button = Newt::CompactButton($text);

Labels

Labels are quite simple:

    $label = Newt::Label($text);

You can set the text of an existing label like this:

    $label->Set($text);

Entry boxes

Entry boxes are used to enter text:

    $entry = Newt::Entry($width, $flags, $initial_text);

The initial text is optional. After an entry has been created, it\'s contents can be set by using:

    $entry->Set($text, $cursor_at_end);

The last parameter is optional, and signals if the cursor should be moved to the end of the new value.

To get the current value of the entry box, you do this:

    $entry->Get();

You can filter the characters that may be entered by using a callback filter like this:

    sub my_filter {
      my ($proposed_char, $cursor_position) = @_;

      ...

      return(0) if $char_shoud_be_ignored;
      return(ord $proposed_char) # return ascii code of
                                 # char to be inserted
    }

    $entry->SetFilter(\&my_filter);

or like this:

    $entry->SetFilter(sub {
                        my ($proposed_char, $cursor_position) = @_;

                        ...

                        return(0) if $char_shoud_be_ignored;
                        return(ord $proposed_char) # return ascii code of
                                                   # char to be inserted
                      });

As can be seen, filter callbacks receive a char and an integer which indicates the position that the proposed char would take on the entry. The filter function can return the very same char to indicate that it was accepted, but it can also return another char, to actually substitute the original one. If the filter wants to simply reject the keystroke, it only returns 0.

When an entry is created, some flags may be specified. The flags are the following and may be CWORed: If not specified, the user cannot enter text into the entry box which is wider than the entry box itself. This flag removes this limitation, and lets the user enter data of an arbitrary length. If specified, the value of the entry is not displayed. Useful when an applications needs a password. When specified, the entry will cause the form to stop running if the user pressed return inside the entry box. Nice shortcut for users.

Checkboxes

Newt checkboxes are peculiar, since they may have more than two states. To create a normal one (checked or unchecked), do this:

    $check = Newt::Checkbox("Normal checkbox");

But you can create, for example, a checkbox that switches from not checked to checked with an asterisk and then to checked with an 'M':

    $check = Newt::Checkbox("Normal checkbox", " ", " *M");

As you can see, you can use the two optional parameters to tell the default char first and then the possible chars.

To know if a checkbox is checked after the for is ran, you use the following:

    print "Is checked\n" if $check->Checked();

And you can always get the actual state like this:

    $state = $check->Get();

Radio groups

You create two kinds of radio button groups, vertical and horizontal, by doing this:

    $radio_group1 = Newt::VRadiogroup('Red', 'Green', 'Blue');
    $radio_group2 = Newt::HRadiogroup('Red', 'Green', 'Blue');

You can put any number of options. To have a certain radio button preselected, use one of these alternative forms:

    $rg1 = Newt::VRadiogroupWithDefault(1, 'Red', 'Green', 'Blue');
    $rg2 = Newt::HRadiogroupWithDefault(1, 'Red', 'Green', 'Blue');

The first parameter is the index of the button in the radio group that should be preselected. To know the index of the selected option after the form has run, you do this:

    $index = $radio_group->Get();

Listboxes

Listboxes are the most complicated components Newt provides. They can allow single or multiple selection, and are easy to update. They are created as follows:

    $listbox = Newt::Listbox($height, $flags);

A listbox is created at a certain position and a given height. The CW$height is used for two things. First of all, it is the minimum height the listbox will use. If there are less items in the listbox then the height, suggests the listbox will still take up that minimum amount of space. Secondly, if the listbox is set to be scrollable (by setting the CWNEWT_FLAG_SCROLL flag, CW$height is also the maximum height of the listbox. If the listbox may not scroll, it increases its height to display all of its items.

The following flags may be used when creating a listbox: The listbox should scroll to display all of the items it contains. When the user presses return on an item in the list, the form should return. A frame is drawn around the listbox, which can make it easier to see which listbox has the focus when a form contains multiple listboxes. By default, a listbox only lets the user select one item in the list at a time. When this flag is specified, they may select multiple items from the list.

Once a listbox has been created, items are appended to the bottom like this:

    $listbox->Append($item1, $item2, ...);

Appending is not the only way to add items to the list. You can insert items in any position by telling the item that should be before with the following command:

    $listbox->Insert($before, $item1, $item2, ...);

And you can change any item just by telling:

    $listbox->Set($original, $new);

Of course you can delete entries:

    $listbox->Delete($item1, $item2, ...);

Or just clear out the listbox:

    $listbox->Clear();

You can select and unselect items, with the following:

    $listbox->Select($item1, $item2, ...);

    $listbox->Unselect($item1, $item2, ...);

    $listbox->ClearSelection();

but if you did not sepecify the flag CWNEWT_FLAG_MULTIPLE when constructing your listbox, only the last item on the argument list of CWUnselect() will remain selected.

To get a list of the selected items, just issue:

    @selected_items = $listbox->Get();

Scales

Scales provide an easy way for telling the user the advance on some lengthy operation. It is a horizontal bar graph which the application updates as the operation continues:

    $scale = Newt::Scale($width, $fullvalue);

It is set as expected:

    $scale->Set($amount);

Textboxes

A text box is used for displaying large amounts of text. They are created as follows:

    $textbox = Newt::Textbox($width, $height, $flags, $text, ...);

The CW$text parameter is optional, and if not supplied, the textbox is created only, but it does not fill it with data. To do so, use:

    $textbox->Set($text, ...);

All the arguments are simply concatenated using the double quote operator.

The flags that can be passed to the constructor are the following: All text in the textbox should be wrapped to fit the width of the textbox. If this flag is not specified, each newline-delimited line in the text is truncated if it is too long to fit. When Newt wraps text, it tries not to break lines on spaces or tabs. Literal newline characters are respected, and may be used to force line breaks. The text should be scrollable. When this option is used, the scrollbar which is added increases the width of the area used by the textbox by 2 characters.

Reflowing text

When applications need to display large amounts of text, it is common not to know exactly where the linebreaks should go. While textboxes are quite willing to scroll the text, the programmer still must know what width the text will look ``best'' at (where ``best'' means most exactly rectangular; no lines much shorter or much longer then the rest). This common is specially prevalent in internationalized programs, which need to make a wide variety of message string look good on a screen.

To help with this, Newt provides routines to reformat text to look good. It tries different widths to figure out which one will look ``best'' to the user. As these commons are almost always used to format text for textbox components, Newt makes it easy to construct a textbox with reflowed text.

The following function reflows the provided text to a target width. the actual width of the longest line in the returned text is between CW$width - $flexdown and CW$width + $flexup; the actual maximum line length is chosen to make displayed text look rectangular. In array context, the function returns a tuple consisting of the reflowed text and the actual width and height of it.

    ($r_text, $width, $height) = Newt::ReflowText($width,
                                                  $flexdown,
                                                  $flexup,
                                                  $text);

In scalar context only the reformatted text is returned.

When the reflowed text is being placed in a textbox it may be easier to use the following:

    $textbox = Newt::TextboxReflowed($width, $flexdown, 
                                     $flexup, $flags,
                                     $text, ...);

which creates a textbox, reflows the text, and places the reflowed text in the listbox. Its parameters consist of the position of the final textbox, the width and flex values for the text (which are identical to the parameters passed to CWNewt::Reflow(), and the flags for the textbox (which are the same as the flags for CWNewt::Textbox(). This function does not let you limit the height of the textbox, however, making limiting its use to constructing textboxes which do not need to scroll.

To find out how tall the textbox created by CWNewt::TextboxReflowed() is, use CWNewt::GetNumLines(), which returns the number of lines in the textbox. For textboxes created by CWNewt::TextboxReflowed(), this is always the same as the height of the textbox.

Please note that the order of the parameters of Newt::ReflowText and Newt::TextboxReflowed differs from the C API to allow lists of text but currently only TextboxReflowed allows this.

Scrollbars

Scrollbars may be attached to panel to let them contain more data than they have space for. Currently, there can only be vertical scrollbars:

    $scroll = Newt::VScrollbar($height, 
                               $normalColorset, 
                               $thumbColorset);

When a scrollbar is created, it is given a position on the screen, a height, and two colors. The first color is the color used for drawing the scrollbar, and the second color is used for drawing the thumb. This is the only place in newt where an application specifically sets colors for a component. It s done here to let the colors a scrollbar use match the colors of the component the scrollbar is mated too. When a scrollbar is being used with a form, CW$normalColorset is often CWNEWT_COLORSET_WINDOW and CW$thumbColorset CWNEWT_COLORSET_ACTCHECKBOX.

If you do not want to bother with colors, you can omit the last two parameters and let Newt use the defaults.

To set the position of the scrollbar, use:

    $scroll->Set(5, 10);

The first parameter is the current position, the second is the logical range of the scrollbar. In the above example, the thumb would be positioned 50% of the way along the scrollbar.

Forms

Forms are the basic method of interaction with with a set components and correspond directly to the newt construct of the same name. Because of the way component objects are created in Newt, you should not use forms directly; use panels instead, which are documented below.

If you still wish to use forms rather than panels, use the various <component>XY constructors to explicitly provide positional coordinates. For example:

    $form = Newt::Form();
    $form->Add(Newt::LabelXY(2, 3, "Some text"));
    $form->Add(Newt::TextboxXY(4, 3, 4, 20, 0, "Starting text"));
    $form->Run();

To change the background color of a form, use:

    $form->SetBackground($color);

where the value of CW$color is one onf the colorset constants.

To change the height of a form, use:

    $form->SetHeight($height);

Running a form

To run a form as a toplevel and get user input, you may do the following:

    ($reason, $data) = $form->Run();

    if ($reason == NEWT_EXIT_HOTKEY) {
      if ($data == NEWT_KEY_F12) {
        print "F12 hotkey was pressed\n";
      } else {
        print "Some hotkey other than F12 was pressed\n";
      }
    } else {
      print 'Form terminated by button ', $data->Tag(), "\n";
    }

As can be seen on the example, when called in a list context CWRun() returns two values, one is the reason why the form terminated and the other is an associated data. In a scalar context only the data is returned. Posible values for the reason are: The form exited because a hotkey was pressed. The associated data contains the key pressed, that is, one of NEWT_KEY_* values. See Hotkeys later for more information. The form exited because a component was activated, a button, for instance a button. The associated data is a reference to the component involved. The form exited because the timer associated with it expired. In this case the associated data is CWundef.

Hotkeys

Normally, a panel terminates when the user presses a button, but you can define some keys as hotkeys that will make the CWRun() function return with CWNEWT_EXIT_HOTKEY. Yo do this by issuing the folowing:

   $form->AddHotKey(NEWT_KEY_F11);

F12 is always defined to be a hotkey.

Panels

Panels are high level constructs, based on forms, that allow you more control over the layout and grouping of components. Panels also eliminated the need for the programmer to manage windows. You create panels by specifying the number of columns and rows you want, as well as a caption to be used when the panel is displayed as a toplevel:

   $panel = Newt::Panel(2, 3, "Panel example");

When run, panels are centered by default, but you can specify a position relative to the topleft corner of the screen by appending two optional integers:

   $panel = Newt::Panel(2, 3, "Panel example", 5, 5);

Adding components to a panel is straightforward, you just have to indicate the position the component will take in the grid:

   $panel1->Add(0, 0, $mycomponent);

Several optional parameters may be used, however, when adding components:

   $panel1->Add($col, 
                 $row, 
                 $mycomponent,
                 $anchor,
                 $padleft, 
                 $padtop,
                 $padright,
                 $padbottom,
                 $flag);

You can specify the side of the cell to which the component will be aligned by specifying an anchor. The anchor values avalaible are CWNEWT_ANCHOR_LEFT, CWNEWT_ANCHOR_RIGHT, CWNEWT_ANCHOR_TOP, CWNEWT_ANCHOR_BOTTOM.

You can ask for more space on the sides of the component, perhaps to get a cleaner, less cluttered presentation using the padding parameters, and specifiying an integer value.

Panels may be nested. For this to be done you only have to add a panel to another as you would with any other component.

Because panels are derived from forms, they also support all the methods provided by forms, e.g. SetBackground, AddHotKey etc. Running a panel is exactly the same as Running a form Running a form.

Moving panels around the screen

Panels may be moved around the screen using the Move method:

   $panel1->Move($col, $row);

This adjusts the position of the panel relative to the top left corner of the screen.

Drawing panels instead of running them

When you run a panel the terminal is blocked until the user presses a component or a key that causes the panel to exit. Sometimes is useful to present the interface to the user without blocking the execution of code. This can be done by only drawing the panel, not running it. It is easy to show an advance status for a lengthy operation like this:

   $i = 1;
   foreach (@items) {
      $label->Set("Processing item $i");
      $panel->Draw();
      $scale->Set($i);
      process_item($_);
      $i++
   }

Hiding panels

Panels can be hidden in case you want by using the following:

   $panel->Hide();

Constants

You can import all the constants exported by this package as needed or using several predefined tags, with the following syntax:

    use Newt qw(:exits :keys);
exits NEWT_EXIT_* constants
keys NEWT_KEY_* constants
anchors NEWT_ANCHOR_* constants
colorsets NEWT_COLORSET_* constanst
flags NEWT_FLAG_* constants
entry NEWT_ENTRY_* constants
fd NEWT_FD_* constants
grid NEWT_GRID_* constants
textbox NEWT_TEXTBOX_* constants
macros
macros to make useful buttons and panels: OK_BUTTON, CANCEL_BUTTON, QUIT_BUTTON, BACK_BUTTON, OK_CANCEL_PANEL, OK_BACK_PANEL. This macros only create components which are properly tagged.

Non Object-oriented Interface

For those who prefer a procedural interface, this module also exposes the underlying library API. Wherever possible, this module maintains the function signatures of the underlying C API. However, any functions which return parameters by reference through their arguments have been alter to provide these return values as a list. In addition, the Perl API to the newt library enforces strong typing, i.e. it is not possible to pass a Checkbox item as the first argument of a function that expects a Label.

Using this interface, especially when using the Listbox functions, requires extra care on the part of the programmer as it is very easy to leak memory or lose track of items in components due to the memory-based identification scheme the newt library uses.

Items missing from the Procedural API

The following functions from the library API are not included in the Perl API.

newtButtonBarv
newtWinMessagev
These two functions expect a C style va_list as their last parameter, a construct that has no Perl equivalent. Instead pass up to fifteen arguments to newtButtonBar and newtMessage respectively.
newtCheckboxTreeAddArray
Instead of using this function to pass the element sequence as an array, you can pass an array reference as the last argument to newtCheckboxTreeAddItem like so:
   my $ref = [3, 2, 5];
   newtCheckboxTreeAddItem($cb, $text, $data, $flags, $ref);

Items with different function signatures

The following items do not have the same function signatures as the underlying library API. This is usually due to differences in the parameter and return value passing mechanisms between the library API and Perl.

newtButtonBar
When used in scalar context, this function returns a grid containing the buttons created. In list context, this function returns the grid containing the buttons followed by the buttons themselves.
newtCheckboxTreeGetMultiSelection
newtCheckboxTreeGetSelection
newtListboxGetSelection
When used in scalar context, instead of returning an array of the selected items these functions return the number of items selected. In list context, these functions return a list of references to the data elements associated with any selected items.
newtCheckboxTreeFindItem
This function returns the sequence of element positions that form the path to the item as a list, regardless of the context in which the function is invoked.
newtFormRun
In scalar context, this function returns the value of the hotkey or a reference to the component that caused the form to terminate. In list context, this function also returns the reason for termination, either NEWT_EXIT_HOTKEY, NEWT_EXIT_COMPONENT, NEWT_EXIT_FDREADY or NEWT_EXIT_TIMER. The reason code is returned after the component.
newtGridGetSize
This function returns a list with the width and height of grid in that order, regardless of the context in which the function is invoked.
newtListboxGetEntry
In scalar context, this function returns the data element associated with the requested entry. In list context, the function returns a list of the text label and the data entry associated with the requested entry. If the requested entry does not exist, the function returns undef.

Mixing the object oriented and functional approaches

In general, don\'t! If you really must, however, the GetCompenent method returns a pair of values to make this possible. The first value is the class of component, either NEWT_GRID_COMPONENT or NEWT_GRID_SUBGRID. The second value is a reference to the underlying newt element. This is the save value returned by the constructors in the library API, e.g newtButton. The GetComponent method is most useful for calls to newtGridSetField, which is the only way it is used internally.

TO DO

Scrollable panels.
Some forms stuff, like watching file descriptors.

SEE ALSO

Writing programs using Newt, by Erik Troan.

THANKS TO

Erik Troan, for writing this useful library. Thanks for his tutorial, too, from where I stole complete paragraphs for this documentation, I'm afraid.

AUTHOR

The original author of the Red Hat newt library is Erik Troan, <ewt@redhat.com> The author of this Perl bindings is Alejandro Escalante Medina, <amedina@msg.com.mx>

This library has been enhanced and altered to more correctly support a native Perl API for Debian by Stephen Zander <gibreel@debian.org>

DATE

Version 0.1, 5th Nov 1998