.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Widgets::Tutorial 3pm" .TH Widgets::Tutorial 3pm "2002-11-14" "perl v5.20.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Curses::Widget::Tutorial \-\- Widget Usage Tutorial .SH "POD VERSION" .IX Header "POD VERSION" \&\f(CW$Id:\fR Tutorial.pod,v 1.2 2002/11/04 00:44:04 corliss Exp corliss $ .SH "DESCRIPTION" .IX Header "DESCRIPTION" Usage of any given widget is fairly simple, but plenty of flexibility is built into the system in order to allow you to completely control every aspect of their behaviour. .SS "\s-1ENVIRONMENT\s0" .IX Subsection "ENVIRONMENT" Due to the usage of Curses constants and the way that the screen is controlled, care must be taken in how the running environment is set up. To begin, one would initiate a Curses session on the console in a typical fashion: .PP .Vb 1 \& $mwh = new Curses; .Ve .PP We then turn off echoing, since the widgets will determine what and were any input is sent to the display: .PP .Vb 1 \& noecho(); .Ve .PP I typically use half-blocking input reads, since there may be periodic routines that I want to run while waiting for input. If you're comfortable with that, you can do the same: .PP .Vb 1 \& halfdelay(5); .Ve .PP Next, I turned on cooked input, since the widgets make heavy use of constants for recognising special keys: .PP .Vb 1 \& $mwh\->keypad(1); .Ve .PP Finally, we set the cursor visibility to invisible, since the widgets will provide their own as necessary: .PP .Vb 1 \& curs_set(0); .Ve .PP From this point, we're not ready to start splashing widgets to the screen and start handling input. .SH "USAGE INSTRUCTIONS" .IX Header "USAGE INSTRUCTIONS" .SS "\s-1BASIC USAGE\s0" .IX Subsection "BASIC USAGE" When using the widgets, you must have \fBuse\fR line for each type of widget used in your program. In addition, it's good practice to include the base class as well, since it provides some useful functions for handling both reading input and managing colour pairs. .PP .Vb 2 \& 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); .Ve .PP Next, we instantiate the widget(s) we want to use. .PP .Vb 6 \& $tf = Curses::Widgets::TextField\->new({ \& X => 5, \& Y => 5, \& COLUMNS => 10, \& CAPTION => \*(AqLogin\*(Aq \& }); .Ve .PP One thing you need to remember is that \fB\s-1COLUMNS\s0\fR (and \fB\s-1LINES\s0\fR, for those widgets that support it) always pertain to the \fIcontent\fR area in the widget. If the widget supports a bordered mode, the actual dimensions will increase by two in both the Y and the X axis. In other words, since TextFields have borders on by default, the actual number of columns and lines that will be used by the above widget is 10 and 3, respectively. .PP To cause the widget to display itself, call the \fBdraw\fR method: .PP .Vb 1 \& $tf\->draw($mwh, 0); .Ve .PP The first argument is a handle to the window in which you want the widget to draw itself. All widgets are drawn in derived windows. The second argument should be a Perlish boolean value which instructs the draw method whether or not to draw the cursor. .PP When you're ready to accept input, the simplest method is to use the \&\fBexecute\fR method: .PP .Vb 1 \& $tf\->execute($mwh); .Ve .PP This method is a blocking call until the widget is fed a character matching the class defined by \s-1FOCUSSWITCH \s0([\en\et] by default). Until it recieves a matching character, the widget will respond appropriately to all user input and update the display automatically. .PP Once the \fBexecute\fR method call exits, you can retrieve the final value of the widget via the \fBgetField\fR method: .PP .Vb 1 \& $login = $tf\->getField(\*(AqVALUE\*(Aq); .Ve .SS "\s-1ADVANCED USAGE\s0" .IX Subsection "ADVANCED USAGE" You may have a need to run period routines while waiting for (or handling) user input. The simplest way add this functionality is to create your own input handler. The default handler (provided by Curses::Widgets: \fBscankey\fR) is coded as such: .PP .Vb 3 \& sub scankey { \& my $mwh = shift; \& my $key = \-1; \& \& while ($key eq \-1) { \& $key = $mwh\->getch; \& } \& \& return $key; \& } .Ve .PP If, for example, we wanted that function to update a clock (the actual code for which we'll pretend is in the \fBupdate_clock\fR function) we could insert that call inside of our new input handler's while loop: .PP .Vb 3 \& sub myscankey { \& my $mwh = shift; \& my $key = \-1; \& \& while ($key eq \-1) { \& $key = $mwh\->getch; \& update_clock($mwh); \& } \& \& return $key; \& } .Ve .PP We can then hand this function to the widgets during instantiation, or via the \&\fBsetField\fR method: .PP .Vb 5 \& $tf = Curses::Widgets::TextField\->new({ \& X => 5, \& Y => 5, \& INPUTFUNC => \e&myscankey \& }); \& \& \-\- Or \-\- \& \& $tf\->setField(INPUTFUNC => \e&myscankey); .Ve .PP Another way to handle this is to set up your own loop, and instead of each widget calling it privately, handle all input yourself, sending it to the appropriate widget via each widget's \fBinput\fR method: .PP .Vb 1 \& while (1) { \& \& while ($key eq \-1) { \& $key = $mwh\->getch; \& update_clock($mwh); \& } \& \& # Send numbers to one field \& if ($key =~ /^\ed$/) { \& $tf1\->input($key); \& \& # Send alphas to another \& } elsif ($key =~ /^\ew$/) { \& $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); \& } \& \& } .Ve .PP This is a rather simplistic example, but hopefully the applications of this are obvious. One could easily set hot key sequences for switching focus to various widgets, or use input from one widget to update another, and so on. .SS "\s-1CONCLUSION\s0" .IX Subsection "CONCLUSION" That, in a nutshell, is how to use the widgets. Hopefully the system is flexible enough to be bound to the event model and input systems of your choice. .SH "HISTORY" .IX Header "HISTORY" 2001/12/09 \*(-- First draft. .SH "AUTHOR/COPYRIGHT" .IX Header "AUTHOR/COPYRIGHT" (c) 2001 Arthur Corliss (corliss@digitalmages.com)