Widget...utorial(3pm)
π NAME π
okay so this is Widget...utorial(3pm) β the User Contributed Perl Documentation page β and its actual name is Curses::Widget::Tutorial, aka the Widget Usage Tutorial. yes bestie, we're learning widgets today π
β¨ POD VERSION β¨
$Id: Tutorial.pod,v 1.2 2002/11/04 00:44:04 corliss Exp corliss $
π DESCRIPTION π
Using any one of these widgets is lowkey simple, but there is so much flexibility baked into the system that you can control literally every single aspect of how they behave. main character energy, fr fr π
πΈ ENVIRONMENT πΈ
Because the widgets use Curses constants and because of how the screen gets controlled, you have to be careful setting up the environment you're running in. no cap. Step one: start a Curses session on the console the normal way:
$mwh = new Curses;
Then we turn echoing off, because the widgets are the ones deciding what gets sent where on the display:
noecho();
ngl, I usually go with half-blocking input reads, because there might be periodic routines I want to run while I'm waiting around for input. If that's your vibe too, do the same:
halfdelay(5);
Next up I turned on cooked input, since the widgets make heavy use of constants to recognise special keys:
$mwh->keypad(1);
And finally we set the cursor visibility to invisible, because the widgets will supply their own cursor whenever they need one:
curs_set(0);
Once you've done all that, you're ready to start splashing widgets onto the screen and handling input. slay β¨
π¦ USAGE INSTRUCTIONS π¦
π« BASIC USAGE π«
When you're using the widgets, you have to have a use line for every single type of widget your program uses. Also, it's good practice to pull in the base class too, since it hands you some genuinely useful functions for reading input and managing colour pairs. it's giving responsible programmer π
Example:
========
use Curses;
use Curses::Widgets;
use Curses::Widgets::TextField;
# Initialise the environment
$mwh = new Curses;
noecho();
halfdelay(5);
$mwh->keypad(1);
curs_set(0);
Next, we instantiate the widget(s) we want to use:
$tf = Curses::Widgets::TextField->new({
X => 5,
Y => 5,
COLUMNS => 10,
CAPTION => 'Login'
});
One thing you must remember: COLUMNS (and LINES, for the widgets that support it) always refers to the content area inside the widget. If the widget supports bordered mode, the actual dimensions go up by two on both the Y and the X axis. In other words β since TextFields have borders on by default β the widget above actually uses 10 columns and 3 lines. respectively. π math is math.
To make the widget show itself, call the draw method:
$tf->draw($mwh, 0);
The first argument is a handle to the window you want the widget to draw itself in. All widgets are drawn in derived windows. The second argument should be a Perlish boolean value that tells the draw method whether or not it should draw the cursor.
When you're ready to accept input, the simplest method is the execute method:
$tf->execute($mwh);
This method is a blocking call until the widget gets fed a character matching the class defined by FOCUSSWITCH ([\n\t] by default). Until it receives a matching character, the widget responds appropriately to all user input and updates the display automatically. it's just doing its thing π«Ά
Once the execute method call exits, you can grab the widget's final value with the getField method:
$login = $tf->getField('VALUE');
π₯ ADVANCED USAGE π₯
Sometimes you need to run periodic routines while you're waiting for (or handling) user input. The simplest way to add that functionality is to write your own input handler. The default handler (the one provided by Curses::Widgets, scankey) is coded like this:
sub scankey {
my $mwh = shift;
my $key = -1;
while ($key eq -1) {
$key = $mwh->getch;
}
return $key;
}
If, say, we wanted that function to update a clock (and we're just gonna pretend the actual code for that lives in the update_clock function), we could drop that call right inside the while loop of our new input handler:
sub myscankey {
my $mwh = shift;
my $key = -1;
while ($key eq -1) {
$key = $mwh->getch;
update_clock($mwh);
}
return $key;
}
Then we can hand that function to the widgets either at instantiation time, or via the setField method:
$tf = Curses::Widgets::TextField->new({
X => 5,
Y => 5,
INPUTFUNC => \&myscankey
});
-- Or --
$tf->setField(INPUTFUNC => \&myscankey);
Another way to handle this is to set up your own loop, and instead of letting each widget call it privately, handle all the input yourself and send it to the right widget through each widget's input method:
while (1) {
while ($key eq -1) {
$key = $mwh->getch;
update_clock($mwh);
}
# Send numbers to one field
if ($key =~ /^\d$/) {
$tf1->input($key);
# Send alphas to another
} elsif ($key =~ /^\w$/) {
$tf2->input($key);
# Send KEY_UP/DOWN to a list box
} elsif ($key eq KEY_UP || $key eq KEY_DOWN) {
$lb->input($key);
}
# Update the display
foreach ($tf1, $tf2, $lb) {
$_->draw($mwh, 0);
}
}
This is a pretty simplistic example, but hopefully the applications are obvious. You could easily set hot key sequences for switching focus between various widgets, or use input from one widget to update another, and so on. the possibilities?? endless π«
π CONCLUSION π
That, in a nutshell, is how you use the widgets. Hopefully the system is flexible enough to be bound to the event model and input systems of your choice. periodt π
π HISTORY π
2001/12/09 β First draft.
π AUTHOR/COPYRIGHT π
(c) 2001 Arthur Corliss (corliss@digitalmages.com)
and that's the whole page bestie π«Ά this was perl v5.34.0, dated 2022-06-12, filed under Widget...utorial(3pm) β go forth and make your terminal gorgeous, iykyk ππΈ
π¦ where this page comes from
- debian bookworm: libcurses-widgets-perl 1.997-8
- debian trixie: libcurses-widgets-perl 1.997-8
- ubuntu noble: libcurses-widgets-perl 1.997-8
- ubuntu resolute: libcurses-widgets-perl 1.997-8
- ubuntu stonking: libcurses-widgets-perl 1.997-8
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms