NAME

PerlVision - Text-mode User Interface Widgets.

SYNOPSIS

use PerlVision;

init PerlVision;

my ($width, $height) = (50,1);
my $dialog = new PerlVision::PVD::yesno ("Yes or no?", $width, $height);
my $answer = $dialog->activate;

PerlVision::done;

DESCRIPTION

PerlVision provides various text-mode user interface widgets, including checkboxes, radiobuttons, pushbuttons, single and multiple selection listboxes, an extensible editbox, a scrollable viewbox, single line text entry fields, a menubar with pulldown menus, and popup dialog boxes with multiple controls.

CLASSES

The following object classes are defined within PerlVision:

"PerlVision"

Not a widget. Provides a few important class methods.

"PerlVision::Static"

A static text control.

"PerlVision::Checkbox"

A single 2-state checkbox.

"PerlVision::Radio"

A single 2-state radiobutton.

"PerlVision::RadioG"

A group of connected radiobuttons.

"PerlVision::Listbox"

A single selection list box.

"PerlVision::Mlistbox"

A multiple selection list box.

"PerlVision::Entryfield"

A single line text entry field.

"PerlVision::Password"

A single line text entry field that echoes '*' to conceal the input.

"PerlVision::Menubar"

A top line menu bar with single-level pulldown submenus.

"PerlVision::Editbox"

A multi-line edit box.

"PerlVision::Viewbox"

A readonly viewer/pager for text files.

"PerlVision::Pushbutton"

A push button that uses 3 lines of screen real estate.

"PerlVision::Cutebutton"

A push button that uses 2 lines of screen real estate.

"PerlVision::Plainbutton"

A no-frills button that fits on a single line.

"PerlVision::Dialog"

A dialog box with multiple controls.

NOTES

Internal Classes

Other classes are defined for internal use by PerlVision and should not be used from outside. Also, see below why use of the PerlVision::Radio control is limited from outside.

Constructors

Constructors for all the classes are called new.

Instance Data

All classes expect that you will not access the object's data yourself.

The activate method

Most controls (except PerlVision::Static and PerlVision::RadioG, see below) have an activate method. It makes the control active, and returns when any traditional shift focus key is pressed. See the section on PerlVision::Dialog for more details.

The stat method

All controls other than PerlVision::Static have a stat method, which returns the status of the control (checked, unchecked, text, whatever).

Widget positioning

The $x and $y arguments for all widgets are the X and Y co-ordinates to place the control, relative to the origin (top left) of the dialog box that contains the control.

CLASS INTERFACES

PerlVision

Provides some helper methods

init

Initializes PerlVision. Call this before creating any widgets.

init PerlVision;
done

Call this before exiting.

PerlVision::done;
getkey

Wait for a keypress and return the key and a keycode.

my ($key, $keycode) = PerlVision::getkey;

$key will contain the actual key pressed, whereas $keycode will contain a key code if the key is a special key recognized by PerlVision. A list of keycodes can be found in the source of the getkey method.

PerlVision::Static

A static text control.

my $static = new PerlVision::Static ("Text", $x1, $y1, $x2, $y2);

This control displays static text in dialog boxes. It doesn't have an activate or stat method.

$static->display;      # Displays the widget.  

If your text doesn't fit in the space you allocate, it'll be truncated. It's also your responsibility to provide line breaks if you don't want all the text to be thought of as a single line.

PerlVision::Checkbox

A single 2-state checkbox.

my $checkbox = new PerlVision::Checkbox ("Label", $x, $y, $stat);

Set $stat to 1 if the Checkbox should be checked by default, 0 if not. "Label" is printed to the right of the checkbox.

$checkbox->display;    # Displays checkbox.
$checkbox->activate;   # Gives it focus. Exits on 1,2,3,4,5,6,7 codes.
$checkbox->select;     # Toggles status.
$checkbox->stat;       # Returns status. (1 checked, 0 unchecked)
PerlVision::Radio

A single 2-state radiobutton.

my $radio = new PerlVision::Radio ("Label", $x, $y, $stat);

PerlVision::Radio is a direct descendant of PerlVision::Checkbox that looks a bit different. All the methods defined for PerlVision::Checkbox are defined for PerlVision::Radio as well, but PerlVision::Radio is not just a different looking PerlVision::Checkbox.

Radio buttons are meant to be grouped and to affect the state of all other buttons in the group. So to use a radio button, it needs to be put in a group with PerlVision::RadioG (see below). Once it's in a group you can use all the methods outlined above for PerlVision::Checkbox.

PerlVision::RadioG

A group of connected radiobuttons.

my $radiog = new PerlVision::RadioG ($radio_1, $radio_2, $radio_3...);

Where $radio_* are PerlVision::Radio objects.

$radiog->display;      # Displays all radio buttons in group.
$radiog->stat;         # To figure out which button is the one that's
                       # selected. This returns the Label of the selected
                       # button.

PerlVision::RadioG has no activate method. You activate the PerlVision::Radio objects directly. This is more flexible for use in dialog boxes.

PerlVision::Listbox

A single selection list box.

my $listbox = new PerlVision::Listbox ($heading, $x1, $y1, $x2, $y2, 
                               "Label1", 0, "Label2", 0...);

Yes, the element following each LabelN should be 0.

Label* are the strings that will be shown in the listbox. $heading will be printed across above the top of the listbox.

$listbox->activate;    # Gives it focus. Exits on 5,6,7,8 exit codes.
$listbox->stat;        # Returns the label of the selected entry.
PerlVision::Mlistbox

A multiple selection list box.

my $mlistbox = new PerlVision::Mlistbox ($heading, $x1, $y1, $x2, $y2, 
                                 "Label1", 0, "Label2", 0...);

Yes, the element following each LabelN should be 0.

Label* are the strings that will be shown in the listbox. $heading will be printed across above the top of the listbox.

$mlistbox->activate;   # Gives it focus. Exits on 5,6,7,8 exit codes.
$mlistbox->stat;       # Returns a list of all selected labels.
PerlVision::Entryfield

A single line text entry field.

my $entry = new PerlVision::Entryfield ($x, $y, $length, $max,
                                "Label", "Initial Value");

$length is the length of the text entry area. $max is the maximum length of the input. This is currently ignored. "Label" is printed to the left of the entry field. Can be "". The entryfield is pre-initialized to "Initial Value". Can be "".

$entry->activate;      # Gives it focus. Exits on 1,2,5,6,7,8 exit codes.
                       # Changed text is always saved, regardless of
  		         # how the loop exited.
$entry->stat;	         # Returns the text value of the entryfield.
PerlVision::Password

A single line text entry field that echoes '*' to conceal the input.

Identical to PerlVision::Entryfield except that it displays '*' instead of each character that the user types.

PerlVision::Menubar

A top line menu bar with single-level pulldown submenus.

The menu bar is a bit odd. The way you do it is set it up with just one pulldown, then add pulldowns to it till you have enough. Don't add too many (i.e. that there's not enough space for their heads on the menubar).

my $menubar = new PerlVision::Menubar ("Head", $width, $depth, 
                               "label1", 0, "label2", 0...);

Just like with the listboxes, each list element is followed by a 0. This list becomes your first pulldown. Now to add more pulldowns, do:

$menubar->add("Head", $width, $depth, "label1", 0, "label2", 0...);

That's the second pulldown, and so on. Because of this step by step method of building up the menubar, you need to display it once you're finished adding pulldowns, it doesn't automatically display itself. Do a:

$menubar->display();

To activate:

$menubar->activate();

It'll exit on 5, 7, and 8. On 8, it'll give you a second element in the return list of the form "Pulldown:Selection". The "Pulldown" is the head of the pulldown menu, the "Selection" is the label of the selection.

Help context does not come through on the 5 exit code. i.e. you can't tell which pulldown was active when help was requested, or which selection in which pulldown.

PerlVision::Editbox

A multi-line edit box.

my $editbox = new PerlVision::Editbox ($x1, $y1, $x2, $y2, $margin, 
                               "Text", $index, $start);

$margin is the word-wrap boundary. If it's bigger than the size of the box, that's your headache.

$text is a text string to be pre-loaded into the editbox. it will be stripped of CRs (not LFs), TABs, and nulls, and justified the way the editbox does it (see below).

$index is the start position within the text to initially place the cursor at. First char is 0.

$start is the line number to position at the top of the editbox, if possible. First line is 0.

$editbox->activate;  # Gives it focus. Exits on 5,6,7 exit codes.
                     # Changed text is always saved, regardless of
		       # how the loop exited.
$editbox->stat;      # Returns the text value of the editbox.

There are some hooks to enable extending the edit box by creating a subclass. One is an empty sub statusbar that's called every-time the display is refreshed. Another is an empty sub process_key which is used extensively in rap to build a full editor out of the editbox control.

The editbox does automatic word-wrapping and reverse word-wrapping. The style of auto-wrapping I chose is what personally irritates me the least (all auto-wraps irritate me). Trying to change the wrap style is likely to be very hairy, and will probably break the editbox.

PerlVision::Viewbox

A readonly viewer/pager for text files.

my $viewbox = new PerlVision::Viewbox ($x1, $y1, $x2, $y2, $text, $start);

Much like PerlVision::Editbox but it's readonly and the arrow keys have different bindings.

PerlVision::Pushbutton, PerlVision::Cutebutton, PerlVision::Plainbutton

Three styles of pushbuttons.

my $button1 = new PerlVision::Pushbutton ("Label", $x1, $y1);
my $button2 = new PerlVision::Cutebutton ("Label", $x1, $y1);
my $button3 = new PerlVision::Plainbutton ("Label", $x1, $y1);

Makes a push button of the specified type.

$button1->display();    # Displays it.
$button1->activate();   # Activates it.

Exits on codes 1,2,3,4,5,6,7,8. On 8, it 'depresses' and it's up to you to 'undepress' it by calling the display method.

PerlVision::Pushbutton is BIG. It uses 3 lines on the screen. PerlVision::Cutebutton is smaller - it uses only two lines, and 'depresses' when clicked. PerlVision::Plainbutton is a basic one-line button which does nothing fancy but is useful in some situations (e.g. for hypertext links).

PerlVision::Dialog

A dialog box with multiple controls.

This is the widget that brings other controls together, and manages focus switching between multiple controls. Once you've created all the controls you need, you can add them to a PerlVision::Dialog object to create a functional UI panel.

PerlVision::Dialog uses the return code from each control's activate method do decide how to switch focus between controls. The activate method for all controls returns an exit code when focus is released. This is what these codes mean:

1 = Up Arrow (Traditional shift-focus key)

2 = Down Arrow (Traditional shift-focus key)

3 = Right Arrow (Traditional shift-focus key)

4 = Left Arrow (Traditional shift-focus key)

5 = M-h (For help)

6 = M-x (For menu)

7 = Tab (Traditional shift-focus key)

8 = Enter (Traditional 'Done here' key)

These codes are used by the PerlVision::Dialog control to figure out how to switch focus between controls, and when to exit. Here's how to create a PerlVision::Dialog object:

$dialog = new PerlVision::Dialog ("Title", $x1, $y1, $x2, $y2, $style, $color,
                          $control1, 1, 2, 2, 1, 1, 1, 2, 0,
                          $control2, 1, 3, 3, 1, 2, 2, 3, 0,
                          ...);

"Title" is currently ignored.

$style: if 1, creates a popup that is 'raised'. if 0, creates a popup that is 'depressed'

$color is the background color for the dialog. I'd recommend 6 (cyan) because of the overall hardcoded nature of colors at present.

$control* are PerlVision::* objects that you created beforehand They can't be PerlVision::Menubar objects. Note that the controls must be positioned relative to the origin (top left) of the dialog box, not relative to the screen origin.

How the dialog box works is that the control+exitcode matrix tells PerlVision::Dialog which control to switch focus to on each of the 8 exit codes listed above. So when you do a:

$dialog->activate;

PerlVision::Dialog starts off by displaying itself and giving focus to $control1. When $control1 exits, $dialog looks in the list that follows $control1 in the constructor syntax above to figure out which control to give focus to next. The list is simply numbers that say which control. So 1 represents $control1, 2 represents $control2, and so on, based on the order in which the controls appear in the constructor invocation.

The special value 0 is reserved to tell PerlVision::Dialog to exit and hide the dialog box. I also use it as a place-holder for those exit-codes that a certain control never returns, for example of $control1 above was a PerlVision::Editbox, I'd put 0's in the list following $control1 at positions 1,2,3 and 4 because the edit box object never exits on those codes (those keys have meaning within the editbox)

If you don't want focus to switch off a control when a certain exitcode is returned, simply put that control's own number in the corresponding position in the list.

Look in the rap code for an example of PerlVision::Dialog use, the $options object.

When PerlVision::Dialog's activate method exits, it returns a two-element list. The first element tells you which was the last control to be active (again numbered as they appear in the constructor invocation), and the second element tells you what exitcode that control returned.

After the dialog box has exited, you can call stat on each control to determine its status. Remember, don't put PerlVision::RadioG controls in a dialog box; they don't have an activate method. Put the corresponding PerlVision::Radio controls in. When you call stat, call it on the PerlVision::RadioG object.

Also, don't put a PerlVision::Static as the first control in a PerlVision::Dialog. It doesn't have an activate method. If you just want a pop-up box with text and no other controls, you could use a PerlVision::Viewbox control.

PerlVision::PVD

PerlVision also defines three often needed dialog box styles:

PerlVision::PVD::message

A simple message box with OK button

PerlVision::PVD::yesno

An option box with Yes/No buttons

PerlVision::PVD::entry

A text entry box with OK/Cancel buttons

All three self-center on the screen, and make sure the box is big enough to hold the buttons. They don't check if the screen is big enough to hold the dialog box, or if the dialog box will hold your text. A dialog box can be created as below:

my $dialog = new PerlVision::PVD::message ("Text", $width, $height);

my $dialog = new PerlVision::PVD::yesno ("Text", $width, $height);

PerlVision::PVD::yesno returns 1 for Yes and 0 for No.

PerlVision::PVD::entry returns 0 if Cancel was clicked, or the text from the text entry box if OK was clicked.

$width and $height are how big you want the text part of the box to be (the buttons are separate).

PerlVision::PVD::entry expects an additional argument, the max size of the entry field.

my $dialog = new PerlVision::PVD::entry ("Text", $width, $height, $entrysize);

AUTHOR

Ashish Gulhati <perlvision at hash.neo.email>

BUGS

$max in PerlVision::Entryfield is a misnomer. It's actually used internally and should be set to 0 when you create a new entryfield object.

Colors are more-or-less hardcoded.

We should check if the terminal can support the minimum capabilities required, as well as eval uncertain curses calls.

Error checking needs work.

Text justification in the editbox control should be optional.

Please report any bugs or feature requests to bug-perlvision at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=PerlVision. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

COPYRIGHT AND LICENSE

Copyright (c) Ashish Gulhati. All Rights Reserved.

This software package is Open Software; you can use, redistribute, and/or modify it under the terms of the Open Artistic License 4.0.

Please see the LICENSE file included with this package, or visit http://www.opensoftware.ca/oal40.txt, for the full license terms, and ensure that the license grant applies to you before using or modifying this software. By using or modifying this software, you indicate your agreement with the license terms.