-
Notifications
You must be signed in to change notification settings - Fork 0
The Menu
The Menu in Term::Graille::Menu is (probably) the simplest dropdown menu creation system possible on any platform. It mimics a standard drop down menu found in many GUI Apps, and is navigated simply by the arrow keys and Enter. It is a Term::Graille::Interact widget which means that is harnesses its key capture engine.
A menu object is created using something like:-
my $menu=new Term::Graille::Menu( # no object offered so id will be o0
menu=>[["File","New","Load","Insert","Save","Quit"],
["Edit",["Select","All","Start","End"],["Selection","Copy","Cut","Paste"],"Search","Replace"],
["Run","Logo","Perl","Python"],
"About"],
redraw=>\&refreshScreen, # this is the function that redraws the main window
dispatcher=>\&menuDispatch, # this is the function that dispatches actions based on menu item selected
);
You can see that the menu tree is created in a readable, intuitive manner. Each item of the menu is either a string or an arrayRef. A string represent a leaf in the menu tree and selecting a leak item immediately closes the menu, redraws the screen, calls the dispatcher with the leaf string and a breadcrumb ArrayRef. An ArrayRef contains first the Branch Name, then is followed by strings or ArrayRefs. so something like this:
my $menuTree=[["File","New","Load","Insert","Save","Quit"],
["Edit",["Select","All","Start","End"],["Selection","Copy","Cut","Paste"],"Search","Replace"],
["Run","Logo","Perl","Python"],
"About"];
produces a menu tree like:
File Edit Run Test About
New Select->All Logo Death
Load Start Perl Message
Insert End Python Input
Save Selection->Copy Selector
Quit Cut
Paste
Search
Replace
Because the tree is structured like this one can easily create dynamically changing menus: For instance if you want be able to select from list of sound cards available, you could use {"Select Card",<function_that_returns_available_cards()>]
The redraw function is a function defined in the main program that (naturally) redraws the main screen as the widget is drawn redrawn or removed
This is a function the Menu object calls after the user has selected a menu Item. Two items are passed to the dispatcher function: the string in the leaf and an ArrayRef that describes the bread crumb tgrail to the leaf (this is present to allow for multi[ple leafs with the same name).
There are many ways a dispatcher may work; all it has to to do is decide on the parameter supplied as the menu item is selected what action to perform.
One way, for example is to use a number of if
statements. Another is to use a for
statement structured like a switch :-
sub menuDispatch{
my ($action,$breadCrumds)=@_;
for ($action){
/Save/ and do { saveCurrentFile();last;}
/Load/ and do { loadNewFile(); last;}
#...etc
# behaviour for as-yet undefined actions can go here
}
}
Another way is to have dispatcher use a separate hashRef of subroutines;
my $menuActions={
Save => sub{ saveCurrentFile();},
Load => sub( loadNewFile(); },
}
sub menuDispatcher{
my ($action,$breadCrumbs)=@_;
if (exists $menuActions->{$action}){
$menuActions->{$action}->();
}
else {
printAt (2,60,$action);
}
}