Cmenu
view release on metacpan or search on metacpan
# $sel_text = &menu_display("Select using arrow keys");
# ...
# &menu_terminate();
#
#
# Cmenu - Perl library module for curses-based menus & data-entry
# Copyright (C) 2001 Andy Ferguson, AFC Commercial, Bangor BT19 1PF, UK
#
# This Perl library module is free software; you can redistribute it
# and/or modify it under the terms of the GNU Library General Public
# License (as published by the Free Software Foundation) or the
# Artistic License.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#****************************************************************************
#
#****************************************************************************
# BUGS
#
# 1. Refresh does not redraw top and bottom few lines of the backdrop
# if the display gets totally trashed
# Tried defining "screen" as a "window" to no avail
#
# 2. Cannot find the ncurses BACK-TAB key so there is no default BACK
# function. User needs to map this to another key
#
# 3. Does not resize when called as a subshell or whatever, eg. as when called
# from within "mc". Rsize works OK in a basic xterm.
#
# 4. No line checking with multi-line subtitles; subtitle or pane may
# overflow window
#****************************************************************************
package Cmenu;
use Curses;
use Text::Wrap;
use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
@ISA = qw(Exporter);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw(
menu_initialise
menu_init
menu_item
menu_display
menu_show
menu_popup
menu_button_set
menu_terminate
);
@EXPORT_OK = qw (
$menu_sep
$menu_sepn
);
$Cmenu::VERSION ='1.01';
use vars qw($VERSION $menu_sep $menu_sepn);
BEGIN {
# Field seperator characters returned after menu activity
# menu_sep seperates individual fields
# menu_sepn breaks up field name from field contents
$menu_sep="¬";
$menu_sepn="~";
}
# ##################################################################################
# Public variables and functions
# ==============================
# These variables and functions are available for user programs
# While others may be accessed, they are in fact surreal
# and may cease to exist in later releases
# ---< variables >------------------------------------------------------------------
# $menu_screen : the base curses screen
# $menu_screen_lines : current logical depth of the screen
# $menu_screen_cols : current logical width of the screen
# $menu_inlay : the main display
# $menu_inlay_lines : depth of the menu inlay
# $menu_inlay_cols : width of the menu inlay
# $menu_inlay_y : y offset of inlay from screen top 0
# $menu_inlay_x : x offset of inlay from screen left 0
# $menu_advice : standard text for display at foot
# ---< functions >------------------------------------------------------------------
# All menu functions generally apply keypad, echo and other Curses ops, on
# return from any function Curses settings can be guaranteed as if these calls
# had been made directly
# &echo();
# &nocbreak();
# &curs_set(1);
# keypad control is only applied to new windows which should always be destroyed
# before returning.
# ----------------------------------------------------------------------------------
# &menu_initialise : sets up all menu variables and constructs
# &menu_button_set : swicthes menu buttons on and off
# &menu_item : create a menu item
# &menu_display : display a menu and get a response from it
# &menu_popup : flash a busy window
# &menu_show : gives a full screen text display
# &menu_terminate : close the menu environment down
# ----------------------------------------------------------------------------------
# All Curses functions can of course be used in user programs but be aware that
# management of all windows then becomes the users responsibility and behaviour
# of the menuing environment may be unpredictable
# ##################################################################################
# ##################################################################################
# Variable Definitions
# ##################################################################################
my $did_initterm = 0; # We already got escape sequences for arrows, etc.
# Keystroke arrays
my %kseq=(); # hash for function key translation
my $key_max=0; # longest keystroke
# Windows
my $menu_screen; # the backdrop
my $menu_inlay; # background for the menu window with shadow etc
my $menu_window; # menu window with text elements
my $menu_pane; # where the menu options actually get drawn
my $menu_popup; # special for popup and splash displays
# Window elements
my $menu_title; # title of script in backdrop
my $menu_top_title; # title of menu
my $menu_sub_title; # sub-title of a menu
my $menu_sub_title_lines; # depth of sub-title
my $menu_advice; # message at foot of backdrop
my $menu_item_pos; # where menu items will start
my $menu_indent; # where menu item labels will start
my $menu_index; # counter of menu items
# Extent of display screen - fixed - unchangeable - from TERM settings
# Always starts at 0,0
my $menu_screen_cols=0; # - COLS from Curses } size of the full screen
my $menu_screen_lines=0; # - LINES from Curses }
# Extent of Menu Inlay - size and position of main window
# Amendable via preferences
# Mono screens lose the shadow so get a bigger inlay
my $menu_inlay_lines=0;
my $menu_inlay_cols=0;
my $menu_inlay_y=3; # 2 for mono
my $menu_inlay_x=6; # 4 for mono
# Extent of Menu text pane
# All defined at runtime depending on the menu items
my $menu_pane_lines=0;
my $menu_pane_cols=0;
my $menu_pane_y=0;
my $menu_pane_x=0;
my $menu_pane_scroll;
my $menu_resized=0; # trigger for terminal resizing
my $menu_style=0; #
my $max_item_len=0; # longest menu item
my $max_sel_len=0; # longest label length
my $menu_top_option=0; # current menu item at the top of the display
my $menu_cur_option=0; # the active menu option during navigation
# define global colour variables
my %menu_attributes=(); # load and hold color definitions
my $menu_hascolor; # terminal colour capability flag
# Initialise menu item arrays
my @menu_sel_text =(); # Menu item text
my @menu_sel_style =(); # Menu item type
my @menu_sel_label = (); # Menu item label
my @menu_sel_flag = (); # Menu item special
my @menu_sel_return = (); # value to be returned on selection
my @menu_sel_pos = (); # Menu item position (data fields)
# max length + dec.places + 0
# User hacks
my($menu_hack25)=0; # hack to make a small screen bigger
# Set the default file for help display
my $menu_help="help.txt";
my $menu_help_root="/etc/Cmenu/";
# either termcap or terminfo
# --------------------------------------------------------------------------------
$kseq{scalar(KEY_HOME)}="HOME"; # home
$kseq{scalar(KEY_END)}="END"; # end
$kseq{scalar(KEY_PPAGE)}="PREV"; # page up
$kseq{scalar(KEY_NPAGE)}="NEXT"; # page down
$kseq{scalar(KEY_IC)}="INS"; # insert toggle
$kseq{scalar(KEY_DC)}="DEL"; # delete
$kseq{scalar(KEY_BACKSPACE)}="BS"; # backspace
$kseq{"\cI"}="TAB"; # tab
$kseq{scalar(KEY_BTAB)}="BTAB"; # shifted tab
$kseq{scalar(KEY_UP)}="UP"; # up arrow
$kseq{scalar(KEY_DOWN)}="DOWN"; # down arrow
$kseq{scalar(KEY_LEFT)}="LYNXL"; # left arrow
$kseq{scalar(KEY_RIGHT)}="LYNXR"; # right arrow
$kseq{scalar(KEY_ENTER)}="RET"; # enter key
$kseq{scalar(KEY_BREAK)}="EXIT"; # break
$kseq{"\cJ"}="RET"; # normal return key
# Functions keys have no special meaning - user mapable
# some helpful defaults are set here but are not necessary
$kseq{scalar(KEY_F(1))}="HELP"; # Func key 1
$kseq{scalar(KEY_F(2))}="NOP"; # Func key 2
$kseq{scalar(KEY_F(3))}="NOP"; # Func key 3
$kseq{scalar(KEY_F(4))}="NOP"; # Func key 4
$kseq{scalar(KEY_F(5))}="NOP"; # Func key 5
$kseq{scalar(KEY_F(6))}="NOP"; # Func key 6
$kseq{scalar(KEY_F(7))}="NOP"; # Func key 7
$kseq{scalar(KEY_F(8))}="QUIT"; # Func key 8
$kseq{scalar(KEY_F(9))}="EXIT"; # Func key 9
$kseq{scalar(KEY_F(10))}="NOP"; # Func key 10
$kseq{scalar(KEY_F(11))}="NOP"; # Func key 11
$kseq{scalar(KEY_F(12))}="EXIT"; # Func key 12
# ##################################################################################
# BLOCK 3
# =======
# Load defaults from a config file if it exists
# ##################################################################################
# Does the terminal have colour?
$menu_hascolor = eval { has_colors() };
if($menu_hascolor==1) {
# Set default colours for init_pairs
$menu_attributes{"backdrop"}="6.4.NORMAL";
$menu_attributes{"advice"}="6.4.BOLD";
$menu_attributes{"text"}="0.7.NORMAL";
$menu_attributes{"title"}="3.7.BOLD";
$menu_attributes{"option"}="1.7.BOLD";
$menu_attributes{"button"}="7.7.BOLD";
$menu_attributes{"scroll"}="2.7.BOLD";
$menu_attributes{"rtext"}="7.4.BOLD";
$menu_attributes{"rtitle"}="6.4.BOLD";
$menu_attributes{"roption"}="3.4.BOLD";
$menu_attributes{"edge"}="7.7.BOLD";
$menu_attributes{"dull"}="0.7.BOLD";
$menu_attributes{"help"}="0.2.BOLD";
$menu_attributes{"warn"}="7.3.NORMAL";
$menu_attributes{"error"}="7.1.NORMAL";
$menu_attributes{"popup"}="3.2.BOLD";
$menu_attributes{"shadow"}="0.0.NORMAL";
} else {
# Set mono defaults
$menu_attributes{"backdrop"}="DIM";
$menu_attributes{"advice"}="NORMAL";
$menu_attributes{"text"}="NORMAL";
$menu_attributes{"title"}="NORMAL";
$menu_attributes{"option"}="BOLD";
$menu_attributes{"button"}="DIM";
$menu_attributes{"scroll"}="NORMAL";
$menu_attributes{"rtext"}="REVERSE";
$menu_attributes{"rtitle"}="REVERSE";
$menu_attributes{"roption"}="REVERSE|BLINK";
$menu_attributes{"edge"}="DIM";
$menu_attributes{"dull"}="DIM";
$menu_attributes{"help"}="REVERSE";
$menu_attributes{"warn"}="REVERSE";
$menu_attributes{"error"}="REVERSE";
$menu_attributes{"popup"}="NORMAL";
}
if(-e "/etc/Cmenu/cmenurc") {
# load system wide preferences
&menu_config_file("/etc/Cmenu/cmenurc");
}
if(-e "~/.cmenurc") {
# Load the users specific preferences
&menu_config_file("~/.cmenurc");
}
if(-e "cmenurc") {
# Load the application specific preferences
&menu_config_file("cmenurc");
}
# Now setup colour rendering
menu_set_colours();
# ##################################################################################
# BLOCK 4
# =======
# Draw the screens backdrop and establish dimensions
# ##################################################################################
&menu_redraw_backdrop();
$did_initterm = 1;
}
# Calculate the longest keystroke sequence
$key_max=0;
foreach $key(sort(keys(%kseq))) {
if(length($key)>$key_max) { $key_max=length($key); }
}
}
#**********
# MENU_CONFIG_FILE
#
# Function: Loads user over-rides from a config file
#
# Call format: &menu_config_file("filename");
#
# Notes: See the modules sample file for data structure
#**********
sub menu_config_file {
my ($filename) = @_;
my ($type,$key,$action);
open(IN,"<$filename");
while(<IN>) {
if(length($_)>1) {
chop;
# Remove all spaces
s/ //g;
($type,undef,$key,$action)=split(/:/);
if(($type eq "C")&&($menu_hascolor)) { $menu_attributes{$key}=$action; }
if(($type eq "M")&&(!$menu_hascolor)){ $menu_attributes{$key}=$action; }
if($type eq "H") { $menu_help_root=$action; }
if($type eq "K") { $kseq{$key}=$action; }
if($type eq "X") {
$b[3]=$menu_inlay_cols-$b[1];
};
}
# clear the button bar and redraw it as required
$j=1;
for($i=1;$i<=3;$i++) {
$x=length($menu_button[$i]);
if($x!=0) {
if($menu_hot_button==$i) {
&menu_hot_button($b[$j]-1-$x/2,$menu_button[$i]);
} else {
&menu_draw_button($b[$j]-1-$x/2,$menu_button[$i]);
}
$j++;
}
}
&noutrefresh($menu_inlay);
&doupdate();
}
# Draw the active button
sub menu_hot_button {
my ($h_indent,$text) = @_;
my ($cap);
# Pick out the capital letter
$cap=ord(uc($text));
&attrset($menu_inlay,$menu_attributes{"rtext"});
&move($menu_inlay,$menu_inlay_lines-2,$h_indent);
addstr($menu_inlay,"<");
&attrset($menu_inlay,$menu_attributes{"rtitle"});
addstr($menu_inlay,$text);
&attrset($menu_inlay,$menu_attributes{"rtext"});
addstr($menu_inlay,">");
&attrset($menu_inlay,$menu_attributes{"roption"});
&move($menu_inlay,$menu_inlay_lines-2,$h_indent+1);
addch($menu_inlay,$cap);
}
# Draw an inactive button
sub menu_draw_button {
my ($h_indent,$text) = @_;
&attrset($menu_inlay,$menu_attributes{"button"});
&move($menu_inlay,$menu_inlay_lines-2,$h_indent);
addstr($menu_inlay,"<");
addstr($menu_inlay,$text);
addstr($menu_inlay,">");
}
# ##################################################################################
# Splash screen for Popups and Text displays
# ##################################################################################
#**********
# MENU_POPUP
#
# Function: Pops up a single line text message
# Can be used to keep users interested while a lengthy process
# completes; popup remains on screen until destroyed by
# calling the routine again with no message
#
# Call format: &menu_popup(message,title); # create a popup
# &menu_popup(); # destroy popup
#
# Arguments: - message - a text message to be displayed;
# should be single line only, will be truncated if too long
# If the message is empty an old popup will be destroyed
# - title - title centred in the popup border
# defaults to "processing" if not provided
#
# Returns: nothing
#
# Notes: popup may appear over a blank screen since the menu windows
# may have been removed (not guaranteed)
#**********
sub menu_popup {
my ($message,$ptitle) = @_;
if(!$ptitle) {$ptitle="processing"; }
&menu_advice(" ");
if(!$message) {
# no message so destroy the old popup
# curses cookery
echo(); # no input echo until enabled explicitly
curs_set(1); # turn the cursor on
&delwin($menu_popup);
&menu_redraw_backdrop();
} else {
# create a new popup
noecho(); # no input echo until enabled explicitly
curs_set(0); # turn the cursor off
while(length($message)>$menu_screen_cols-8) {
chop $message;
};
# Initialise menu pane and control variables
$menu_popup=newwin(3,$menu_screen_cols-6,($menu_screen_lines/2)-2,3);
bkgd($menu_popup,$menu_attributes{"popup"});
clear($menu_popup);
&border($menu_popup,0,0,0,0,0,0,0,0);
move($menu_popup,0,($menu_screen_cols-8-length($ptitle))/2);
addstr($menu_popup," $ptitle ");
move($menu_popup,1,($menu_screen_cols-6-length($message))/2);
addstr($menu_popup,$message);
&refresh($menu_popup);
&doupdate();
}
}
#**********
# MENU_SHOW
#
# Function: Pops up a text message with a button bar
# Used as a user confirmation advice before a process
# is performed
# Button bar defined according to current button settings
# Help screen is called directly
#
# Call format: &menu_show(message);
#
# Arguments: - message - a text message to be displayed;
# can be multiline (left-just) or single (centred), choice
# depends on size of window
#
# Returns: a simple string either YES or NO
#
# Notes: Uses Text::Wrap to fill the window if the text to be shown
# is longer than a line - this allows some formatting to be
# performed
# \n forces a line break
# Check docs for Text::wrap for more info
# At present only fills to current window depth and will lose
# any additional text; no scrolling supported yet
#
# Useful as a debugging tool for your own scripts to see
# what is going one since "print" will not work under
# Curses.
#
#**********
sub menu_show {
my ($temp_title,$message,$colour) = @_;
my ($attributes,$work,$x,$i,$j);
my ($menu_popup);
my (@b);
&menu_advice(" ");
if(!$colour) { $colour="ERROR"; }
SET_COLOR: for ($colour) {
/WARN/ && do {
$attributes=$menu_attributes{"warn"};
};
/HELP/ && do {
$attributes=$menu_attributes{"help"};
};
/ERROR/ && do {
$attributes=$menu_attributes{"error"};
};
};
if(!$message) {
# no message given so ignore the call
return("NO");
} else {
# create a popup with button bar
bkgd($menu_inlay,$attributes);
erase($menu_inlay);
&border($menu_inlay,0,0,0,0,0,0,0,0);
move($menu_inlay,0,($menu_inlay_cols-length($temp_title)-2)/2);
addstr($menu_inlay," $temp_title ");
&noutrefresh($menu_inlay);
# Initialise menu pane and control variables
# First define window and draw border
$menu_pane_y=$menu_inlay_y+1;
$menu_pane_x=$menu_inlay_x+1;
$menu_pane_lines=$menu_inlay_lines-3;
$menu_pane_cols=$menu_inlay_cols-2;
&noutrefresh($menu_inlay);
$menu_popup=newwin($menu_pane_lines-2,$menu_pane_cols-2,$menu_pane_y,$menu_pane_x+1);
bkgd($menu_popup,$attributes);
erase($menu_popup);
# curses cookery
cbreak(); # permits keystroke examination
noecho(); # no input echo until enabled explicitly
curs_set(0); # turn the cursor off
if(length($message)<$menu_pane_cols) {
move($menu_popup,$menu_pane_lines/2,($menu_pane_cols-length($message))/2);
addstr($menu_popup,$message);
&refresh($menu_popup);
} else {
$Text::Wrap::columns=$menu_pane_cols-2;
addstr($menu_popup,wrap("","",$message));
&refresh($menu_popup);
}
if($colour eq "HELP") {
# We have to do this since HELP can be called while in a menu
# when menu_show would otherwise trash the button labels
move($menu_inlay,$menu_inlay_lines-2,($menu_inlay_cols/2)-7);
&attrset($menu_inlay,$attributes|A_BOLD);
addstr($menu_inlay,"<Press any Key>");
&refresh($menu_inlay);
getch($menu_inlay);
} else {
do {
# Calculate position of buttons
DO_BUTTONS: for ($menu_buttons) {
/1/ && do {
$b[1]=$menu_inlay_cols/2;
};
/2/ && do {
$b[1]=$menu_inlay_cols/3;
$b[2]=$menu_inlay_cols-$b[1];
};
/3/ && do {
$b[1]=$menu_inlay_cols/4;
$b[2]=$menu_inlay_cols/2;
$b[3]=$menu_inlay_cols-$b[1];
};
}
# Draw buttons
$j=1;
for($i=1;$i<=3;$i++) {
$x=length($menu_button[$i]);
if($x>0) {
# Draw Okay button
if($menu_hot_button==$i) {
# Make it hot
move($menu_inlay,$menu_inlay_lines-2,$b[$j]-($x/2)-1);
&attrset($menu_inlay,$attributes|A_BOLD);
addstr($menu_inlay,"<$menu_button[$i]>");
} else {
# make it cool
move($menu_inlay,$menu_inlay_lines-2,$b[$j]-($x/2)-1);
&attrset($menu_inlay,$attributes);
addstr($menu_inlay,"<$menu_button[$i]>");
}
$j++;
}
}
&refresh($menu_inlay);
$work=&menu_key_seq($menu_inlay);
CONFIRM: for ($work) {
/TAB/ && do {
$menu_hot_button++;
do {
$menu_hot_button++;
if($menu_hot_button>3) { $menu_hot_button=1; }
} until (length($menu_button[$menu_hot_button])>0);
$work="";
last CONFIRM;
};
/BACK/ && do {
do {
$menu_hot_button--;
if($menu_hot_button<1) { $menu_hot_button=$menu_buttons; }
} until (length($menu_button[$menu_hot_button])>0);
$work="";
last CONFIRM;
};
/RET/ && do {
if($menu_hot_button==1) { $work="YES"; }
if($menu_hot_button==2) { $work="HELP"; }
if($menu_hot_button==3) { $work="NO"; }
last CONFIRM;
};
$work="";
};
} until ($work ne "");
}
# curses cookery
nocbreak(); # permits keystroke examination
echo(); # no input echo until enabled explicitly
curs_set(1); # turn the cursor on
&delwin($menu_popup);
&menu_redraw_backdrop();
}
$work;
}
# ##################################################################################
# End of Module
# ##################################################################################
1;
__END__
# Below is the stub of documentation for the module.
=head1 NAME
Cmenu - Perl extension for menuing and data entry in perl scripts
=head1 SYNOPSIS
use Cmenu;
use Curses;
use Text::Wrap;
&menu_initialise($main_title,$advice);
&menu_init($title,$sub-title,$topest,$menu_help);
&menu_item($item_text,$item_label,$item_style,$item_data,$item_pos)
&menu_item($item_text,$item_label,$item_style,$item_data,$item_pos)
...
&menu_item($item_text,$item_label,$item_style,$item_data,$item_pos)
$sel=&menu_display($advice,$start_item);
&menu_button_set($button,$button_text);
&menu_popup($title,$text);
...
&menu_popup();
&menu_show($title,$text,$colour);
&menu_terminate($message);
=head1 DESCRIPTION
CMENU is a Perl Module designed to provide functions for the
creation of menus in perl scripts.
It follows on from perlmenu but uses a Curses interface for
screen manipulation. It also uses the Text::Wrap module to
process large chunks of text for display. These two modules
should be loaded by user scripts.
The sequence of menu processing is as follows;
1. Initialise the module
loop
2. Define a menu structure
3. Define several menu options
4. Call the menu
5. Deal with the menu selections
loop
6. Terminate the module
The module also provide some extra functions.
=head2 menu_initialise
This routine initialises Curses and creates necessary structures
for the menu module. It accepts two parameters which may be empty;
$main_title A script-wide title displayed on all pages
$advice A short text advisory displayed at the foot
of every screen (unless over-ridden by the
module).
The routine returns nothing.
=head2 menu_init
The routine creates a graphic backdrop in the style of the
command-line utility "dialog". It accepts 3 parameters
$title a menu title displayed at the top
$sub_title sub-title text used to give more description
$menu_help a help-file to be displayed when the Help key
is pressed. The help file is located in a
standard location as defined in the configuration
file. (optional)
=head2 menu_item
Each line of a menu is created using this call.
$item_text The text to be displayed as the menu option
$item_label A text label which may be displayed beside
the text
$item_style How the menu option should be drawn or behave
Should be a number from 0 to 9
0 (default) preceeds the text with a text label
the label is returned if the item is selected
1 use number instead of a text label; numbered in
2 decimal places
=head2 menu_display
Actually performs the menu display and navigation. Returns
information relevant to the action selected. Accepts 2 parametrs;
$menu_prompt Displayed at the foot of the screen as advice
$menu_start Which item should be active from the start
This allows items other than the first declared
to be selected; useful when returning to a menu
after an earlier selection (optional)
This is the important call which returns the result of menu
navigation. Depending on the style of menu items defined, various results
will be returned. Generally all selections are a tokenised list seperated
by a standard character ($Cmenu::menu_sep - can be changed by user). For
simple menus, only the selected text label (0,1,4,5) or offset (8) will be
returned.
For radio and check lists (2 and 3) all the selected items will be returned
using each items text label
For edited data fields, more complex values are returned. All editable fields
on a menu will have a token (whether edited or not) returned. Each token has two
fields - the field label and the new field contents; these are seperated by
$Cmenu::menu_sepn.
Since any type of item can be included in a menu, return values may be
equally complex. For complex return values, tokens can be split out using
a command fragment such as
chop($return_value=&menu_display("Menu Prompt",$start_on_menu_item));
@selection=split(/$Cmenu::menu_sep/,$return_value);
for($loop=1;$loop<=$#selection;$i++) {
# deal with each token
($field_label,$field_content) = split(/$Cmenu::menu_sepn,$selection[$i]);
# processing each field accordingly
...
}
The first token returned ($selection[0]) is usually the key pressed to close the
menu was closed; this will rarely be a valid menu item - check it to make sure
an "abort" was not requested.
=head2 menu_button_set
Each menu has up to 3 buttons which can be activated. Usually these give
options to either Accept a menu item or Abort the menu prematurely. A Help
facility may also be called.
This routine switches buttons on and off and, specifies the text label of the button
(button actions cannot be altered yielding "ACCEPT", "HELP" or "EXIT" although your
scripts can interret these responses however you wish). The <TAB> key
traverses the buttons bar.
Parameters for this routine are;
$button a number 1, 2 or 3 specifying which button is to be set
$label the text label for the button; an empty string switches the button off
=head2 menu_popup
Allows a simple screen to pop-up if a lengthy process has been launched. The popup
has only one line of text to give an indication of what the system is doing;
To start a popup - call with $message
To close a popup - call with NO message
Remember to close the popup or the menu display will get confused.
=head2 menu_show
Allows a variety of information to be shown on the screen; the display
generally replaces normal menu rendering until the user presses an approriate key.
The routines takes 3 parameters
$title the title of the display
$message the message to be displayed. If this is only one line it will be
centred; if longer the external routine Text::wrap is used to
manipulated the text to fit on the screen. Text formatting
is quite primitive.
The display cannot be scrolled if it exceeds the dimensions of
the active window
$colour colour style to render the display chosen from HELP|WARN|ERROR
HELP screens have an automatic button to continue; WARN and ERROR
can have multiple buttons (use menu_button_set to control these)
=head2 menu_terminate
Called as the script terminates to close down menu facilities and Curses.
The terminal should be left in a sane state. The $message parameter prints
to STDOUT as the script/routine finishes.
If a scripts aborts before calling this, the sanity of the tty will likely
get lost; use the command "reset" to restore sanity.
=head1 AUTHOR
Andy Ferguson andy@moil.demon.co.uk
=head1 FILES
cmenurc configuration file to set terminal and screen defaults
this file may be
System Wide - in /etc/Cmenu/.cmenurc
User specific - ~/.cmenurc
Run Specific - ./cmenurc
See the distributed file for contents.
vt100-wy60 A tic (terminfo) file for VT100 emulation on a Wyse 60
terminal; this sets the functions keys appropriately
demo A sample script showing how menus can be rendered with the module.
=head1 BUGS
* No continuation pages or checks for text displays overflowing the windows.
* Resize and Refresh functions can misbehave in spawned shells
* BACKTAB definition from Curses is lost so can only TAB forwards thru buttons
perl(1).
=cut
( run in 1.308 second using v1.01-cache-2.11-cpan-364913b4093 )