Cmenu
view release on metacpan or search on metacpan
# Version 2.3 -- Jun, 1994 -- Bug fixes
# Version 3.0 -- Jan, 1995 -- Templates, lots of new options on
# many calls, Perl5 interfacing.
# Version 3.1 -- Mar, 1995 -- Bug fixes, new "menu_template_setexit"
# call, new menu_pref.
# Version 3.2 -- Jun, 1995 -- Bug fixes, template "required field"
# support, template Control-L refresh.
# Version 3.3 -- Feb, 1996 -- Bug fixes, help routines, templates
# from arrays ("menu_load_template_array")
# Version 4.0 -- Feb, 1997 -- Converted to "pm" module, highlighted
# selection cursor pref, Multiple-column
# menus pref, bug fixes
# Version 5.0 -- Jan, 2001 -- Complete re-write using Curses code and dialog
# 'look and feel'. Simplified sub-calls and
# colour support. Preferences stored in file.
# Version 5.1 -- Jan. 2001 -- Put check on edit field length to stop
# edit fields exceeding the window. Field
# layout looks marginally better
# Corrected some fencepost errors in radio and
# checklist routines (oops). Watch out for these
# checklist routine only returns items checked
# left alone. tigetstr continues to not work on Linux/Curses
# --------------------------------------------------------------------------------
# Functional mappings are
# Cursor movement
# UP : move up
# DOWN : move down
# RITE : move right
# LEFT : move left
# LYNXR : move right - can mimic lynx-style motion
# LYNXL : move left - can mimic lynx-style motion
# Large cursor movement
# HOME : go to top (of menu)
# END : go to bottom (of menu)
# NEXT : next page
# PREV : previous page
# JUMP : leap to a specific menu item
# action
# HELP : display active help page/info
# RET : action current selection
# EXIT : cancel or abort current operation
# QUIT : go back a menu
$kseq{`tput kent`}="RET"; # Carriage-return
# HP-UX 9.05 users: try $kseq[4] = `tput cr` if
# "tput kent" gives errors
$kseq{ `tput nel`}="RET"; # New-line
# --------------------------------------------------------------------------------
# Method 4
# Explicit control sequences - should work for all terminals regardless
# These should be Uncommented for all systems/platforms
# Hacks for Xterms and standard emacs style definitions
# --< Xterm hacks >---------------------------------------------------------------
$kseq{"\033[A"}="UP"; # Ansi cursor-up (for DEC xterm)
$kseq{"\033[B"}="DOWN"; # Ansi cursor-down (for DEC xterm)
$kseq{"\033[C"}="RITE"; # Ansi cursor-right (for DEC xterm)
$kseq{"\033[D"}="LEFT"; # Ansi cursor-left (for DEC xterm)
# added mapping for Home/End and Page buttons for xterms
$kseq{"\033[E"}="PREV"; # Ansi guess (for DEC xterm)
$kseq{"\033[F"}="END"; # Ansi end key (for DEC xterm)
$kseq{"\033[G"}="NEXT"; # Ansi guess (for DEC xterm)
$kseq{"\033[H"}="HOME"; # Ansi home key (for DEC xterm)
# --< kvt specials >---------------------------------------------------------------
# -- KDE2 and its terminal kvt do funny things with the keys
# -- keymaps may be lost entirely with the key bindings
$kseq{scalar(KEY_SELECT)}="END"; # end key (for kvt)
$kseq{scalar(KEY_FIND)}="HOME"; # home key (for kvt)
#**********
sub menu_terminate {
my ($message)=@_;
my($key);
&delwin($menu_inlay);
&standend();
&clear();
&refresh(); # clears the screen
&curs_set(1); # turn the cursor back on
&endwin(); # closes all structures and auto restores tty
print "$message\r\n";
exit();
}
# ##################################################################################
# Menu Processing and Navigation
# ##################################################################################
#**********
my $ret="";
# Check for no "menu_item" calls.
if ($#menu_sel_text < 0) {
return("%EMPTY%".$menu_sep);
}
# curses cookery
cbreak(); # permits keystroke examination
noecho(); # no input echo until enabled explicitly
curs_set(0); # turn the cursor off
# reset and draw button bar
$menu_hot_button=1;
&menu_button_bar(0);
&menu_draw_window();
noutrefresh($menu_window);
# Compute prepend length (for stuff we prepend to each selection text)
# indent : indent to centre items
# (or we know we don't care)
$action = &menu_key_seq($menu_pane);
# ------------------------------------------------------------------------------
# Switch construct for dealing with key sequence input
# ------------------------------------------------------------------------------
KEYWAIT: for ($action) {
# Set return value as current option
$ret=$menu_sel_return[$menu_cur_option].$menu_sep;
# General cursor movement
/LEFT/ && do { # Left arrow
# Treat this like an UP-Menu request
$action="UP";
# redo KEYWAIT;
};
/RITE/ && do { # Right arrow
# Treat this like a RETURN
$action="DOWN";
# redo KEYWAIT;
};
}
redo if ($menu_sel_style[$menu_cur_option]==9);
&menu_draw_active($menu_cur_option,$menu_indent);
};
&noutrefresh($menu_pane);
&menu_advice("");
}
&doupdate();
last KEYWAIT;
};
# larger cursor motion
/PREV/ && do { # Page up
if($menu_top_option<=0) {
# Hit the bottom
menu_advice("There are no more options!");
} else {
$menu_cur_option=$menu_cur_option-($menu_pane_lines-3);
$menu_top_option=$menu_top_option-($menu_pane_lines-3);
&menu_draw_pane();
&menu_advice("");
}
$help="";
open(IN,"<".$menu_help_root.$menu_help);
while(<IN>) {
$help=$help.$_;
}
close(IN);
&menu_show("Help File ".$menu_help_root.$menu_help,$help,"HELP");
# these get switched off by menu_show so do this
cbreak(); # permits keystroke examination
noecho(); # no input echo until enabled explicitly
curs_set(0); # turn the cursor off
&menu_refresh();
} else {
beep();
&menu_advice("Help file ".$menu_help_root.$menu_help." not found");
&doupdate;
}
$action="NOP";
last KEYWAIT;
};
/REFS/ && do { # Refresh screen
}
};
} until ($action eq "STOP");
# We have made our selection so dump the menu windows
&delwin($menu_pane);
}
# curses cookery
nocbreak(); # permits keystroke examination
echo(); # no input echo until enabled explicitly
curs_set(1); # turn the cursor on
delwin($menu_window);
$ret;
}
#**********
# MENU_DRAW_INLAY
#
# Function: Draws a menu inlaid box to contain menu options
scrollok($menu_pane,1);
$menu_top_option=0;
keypad($menu_pane,1);
&menu_draw_pane();
}
#*********
# MENU_DRAW_PANE
#
# Function: Draws the actual menu especially after a keystroke
# Usually only necessary after big relocations of the menu cursor
#
# Input: Nothing
#
# Returns: Nothing
#
#*********
sub menu_draw_pane {
my ($i);
# Performs test to make sure the items are aligned correctly to use as much of the
if(!$numbers) {$numbers=0; }
# Initialise field
$field=$menu_sel_text[$m_item];
if(!$field) { $field=""; } # Make sure something is defined
$menu_field=newwin(1,$item_len,$item_line,$item_col);
bkgd($menu_field,$menu_attributes{"advice"});
# curses cookery
curs_set(1); # turn the cursor off
$ins=1; # turn insert mode on
$pos=length($field);
# Now edit the field
READ_KEY: do {
# Collect key sequences until something we recoginize
# (or we know we don't care)
# Format numbers correctly
if($numbers==1) {
move($menu_field,0,$pos);
noutrefresh($menu_field);
doupdate();
$action = &menu_key_seq($menu_pane);
# ------------------------------------------------------------------------------
# Switch construct for dealing with key sequence input
# ------------------------------------------------------------------------------
EDITKEY: for ($action) {
# General cursor movement
/DOWN/ && do { # down arrow
$action="ACCEPT";
redo EDITKEY;
};
/UP/ && do { # Up arrow
$action="ACCEPT";
redo EDITKEY;
};
/LYNXL/ && do { # Left arrow
$action="LEFT";
/LEFT/ && do { # Left arrow
$pos--;
if($pos<0) {$pos=0; }
last EDITKEY;
};
/RITE/ && do { # Right arrow
$pos++;
if($pos>length($field)) {$pos=length($field); }
last EDITKEY;
};
# larger cursor motion
/PREV/ && do { # Page up
$action="ACCEPT";
redo EDITKEY;
};
/NEXT/ && do { # Page down
$action="ACCEPT";
redo EDITKEY;
};
/HOME/ && do { # Home
$pos=0;
$i=substr($field,0,$pos).$action.substr($field,$pos+1);
if($pos==length($field)) {$pos++; }
if($pos>=$item_len) {$pos--; }
}
$field=$i;
}
}; # end of option check
} until ($action eq "STOP");
# return screen to normal after field edit
curs_set(0); # turn the cursor off
delwin($menu_field);
move($menu_pane,$m_item-$menu_top_option,$m_indent);
clrtoeol($menu_pane);
&noutrefresh($menu_window);
}
# ##################################################################################
# ***************************************************************************
# Button Bar
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);
&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($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
# ##################################################################################
#: Buffer KILL YANK BUFF
#: Toggles INS HELP
#: Tabbing TAB BTAB
#: Return RET EXIT QUIT
#: Do nothing NOP
#:------------------------------------------------
#: These are the default control sequences
#: --------
#: ANSI sequences for xterm
#: --------
#K:Ansi cursor-up ^[[A :[A:UP
#K:Ansi cursor-down ^[[B :[B:DOWN
#K:Ansi cursor-right ^[[C :[C:RITE
#K:Ansi cursor-left ^[[D :[D:LEFT
#K:Ansi guess ^[[E :[E:PREV
#K:Ansi end key ^[[F :[F:END
#K:Ansi guess ^[[G :[G:NEXT
#K:Ansi home key ^[[H :[H:HOME
#: --------
#: Emacs control sequences
#: --------
#K:begin of line ^A::HOME
#K:end of line ^E::END
#K:next char ^F::RITE
doc/Cmenu.tex view on Meta::CPAN
\item [menu\_redraw\_backdrop] redraw the backdrop
\item [menu\_refresh] redraw the whole screen especially after resizing a terminal window
\end{description}
\section{Application Preferences}
Cmenu provides a facility to read a \textit{preferences} file to configure a common look-and-feel for all your applications. Preferences can be setup for all users (using file \textit{/etc/Cmenu/cmenurc}). individual users (using \textit{\~/.cmenurc}...
\begin{description}
\item [colour] the colours to be used in all screen renditions including special mono-chrome renderings. Cmenu allows a combination of explicit colours and terminal attributes like bold and dim.
\item [keyboard] cmenu is pre-configured to interpret a variety of key-sequences as specific cursor commands; these can be tailored, disabled or supplemented. This includes use of functions keys.\\
Menu navigation uses normal cursor keys and page keys for larger movement; navigation can also behave like \textit{lynx} where right and left move between menus - this can be disabled.
\item [helpfiles] help files can be stored in locations other than running directories
\item [hacks] when rendered on 25-line mono-screens, a large amount of screen space is taken up with superfluous cosmetic frippery; ultra-serious people can reclaim an extra-line.
\end{description}
A heavily commented sample preferences files is included with the distribution. The preferences file is strictly structured; not following the prescribed layout may corrupt display elements or deactivate certain features.
\section{tic file}
Provided with the module is a tic file for VT100 emulation on a Wyse 60 terminal. This has some of the function keys defined correctly. You will need to define function strings if you want to use the 16 F keys. Page and some of the character keys are...
%%%% Body ends here
doc/html/node17.html view on Meta::CPAN
<H1><A NAME="SECTION00060000000000000000">
Application Preferences</A>
</H1>
Cmenu provides a facility to read a <I>preferences</I> file to configure a common look-and-feel for all your applications. Preferences can be setup for all users (using file <I>/etc/Cmenu/cmenurc</I>). individual users (using <I>/.cmenurc</I>) or by ...
<DL>
<DT><STRONG>colour</STRONG></DT>
<DD>the colours to be used in all screen renditions including special mono-chrome renderings. Cmenu allows a combination of explicit colours and terminal attributes like bold and dim.
</DD>
<DT><STRONG>keyboard</STRONG></DT>
<DD>cmenu is pre-configured to interpret a variety of key-sequences as specific cursor commands; these can be tailored, disabled or supplemented. This includes use of functions keys.
<BR>
Menu navigation uses normal cursor keys and page keys for larger movement; navigation can also behave like <I>lynx</I> where right and left move between menus - this can be disabled.
</DD>
<DT><STRONG>helpfiles</STRONG></DT>
<DD>help files can be stored in locations other than running directories
</DD>
<DT><STRONG>hacks</STRONG></DT>
<DD>when rendered on 25-line mono-screens, a large amount of screen space is taken up with superfluous cosmetic frippery; ultra-serious people can reclaim an extra-line.
</DD>
</DL>
A heavily commented sample preferences files is included with the distribution. The preferences file is strictly structured; not following the prescribed layout may corrupt display elements or deactivate certain features.
( run in 0.361 second using v1.01-cache-2.11-cpan-4d50c553e7e )