File Coverage

blib/lib/UI/Dialog/Screen/Menu.pm
Criterion Covered Total %
statement 25 75 33.3
branch 12 48 25.0
condition 1 21 4.7
subroutine 8 16 50.0
pod 9 9 100.0
total 55 169 32.5


line stmt bran cond sub pod time code
1             package UI::Dialog::Screen::Menu;
2             ###############################################################################
3             # Copyright (C) 2004-2016 Kevin C. Krinke
4             #
5             # This library is free software; you can redistribute it and/or
6             # modify it under the terms of the GNU Lesser General Public
7             # License as published by the Free Software Foundation; either
8             # version 2.1 of the License, or (at your option) any later version.
9             #
10             # This library is distributed in the hope that it will be useful,
11             # but WITHOUT ANY WARRANTY; without even the implied warranty of
12             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13             # Lesser General Public License for more details.
14             #
15             # You should have received a copy of the GNU Lesser General Public
16             # License along with this library; if not, write to the Free Software
17             # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18             ###############################################################################
19 1     1   13472 use 5.006;
  1         2  
20 1     1   3 use strict;
  1         1  
  1         16  
21 1     1   2 use warnings;
  1         1  
  1         27  
22 1     1   2 use constant { TRUE => 1, FALSE => 0 };
  1         1  
  1         79  
23              
24             BEGIN {
25 1     1   4 use vars qw($VERSION);
  1         1  
  1         40  
26 1     1   16 $VERSION = '1.21';
27             }
28              
29 1     1   330 use UI::Dialog;
  1         2  
  1         549  
30              
31             # Example Usage
32             #
33             # my $screen = new UI::Dialog::Screen::Menu ( dialog => $d );
34             # $screen->add_menu_item( "Label", \&func );
35             # $screen->loop();
36             #
37              
38             sub new {
39 2     2 1 419 my ($class, %args) = @_;
40 2         3 $args{__loop_active} = FALSE;
41 2 50       7 unless (exists $args{dialog}) {
42             $args{dialog} = new UI::Dialog
43             (
44             title => (defined $args{title}) ? $args{title} : '',
45             backtitle => (defined $args{backtitle}) ? $args{backtitle} : '',
46             height => (defined $args{height}) ? $args{height} : 20,
47             width => (defined $args{width}) ? $args{width} : 65,
48             listheight => (defined $args{listheight}) ? $args{listheight} : 5,
49             order => (defined $args{order}) ? $args{order} : undef,
50             PATH => (defined $args{PATH}) ? $args{PATH} : undef,
51             beepbefore => (defined $args{beepbefore}) ? $args{beepbefore} : undef,
52             beepafter => (defined $args{beepafter}) ? $args{beepafter} : undef,
53 2 50 33     36 'trust-input' => (defined $args{'trust-input'} && $args{'trust-input'} == 1) ? 1 : 0,
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
54             );
55             }
56 2 50       5 unless (exists $args{menu}) {
57 2         3 $args{menu} = [];
58             }
59 2         12 return bless { %args }, $class;
60             }
61              
62             #: $screen->add_menu_item( "Label", \&func );
63             #: Add an item to the menu with a label and a callback func
64             #
65             sub add_menu_item {
66 0     0 1   my ($self,$label,$func) = @_;
67 0           push(@{$self->{menu}},{label=>$label,func=>$func});
  0            
68 0           return @{$self->{menu}} - 1;
  0            
69             }
70              
71             #: @list_of_menu_items = $screen->get_menu_items();
72             #: Return a list of all the menu items in order. Each item is a hash
73             #: with a label and a func reference.
74             #
75             sub get_menu_items {
76 0     0 1   my ($self) = @_;
77 0           return @{$self->{menu}};
  0            
78             }
79              
80             #: %item = $screen->del_menu_item( $index );
81             #: Remove a menu item and return it. The item will no longer show in the
82             #: list of avaliable menu items.
83             #
84             sub del_menu_item {
85 0     0 1   my ($self,$index) = @_;
86 0 0 0       if (defined $index && $index >= 0 && $index < @{$self->{menu}}) {
  0   0        
87 0           return splice(@{$self->{menu}}, $index, 1);
  0            
88             }
89 0           return undef;
90             }
91              
92             #: $screen->set_menu_item( $index, $label||undef, $func||undef );
93             #: Update a menu item's properties. If a field is "undef", no action
94             #: is performed on that item's field. Returns the menu_item before
95             #: modification.
96             #: Note: $index starts from 0.
97             #
98             sub set_menu_item {
99 0     0 1   my ($self,$index,$label,$func) = @_;
100 0 0 0       if (defined $index && $index >= 0 && $index < @{$self->{menu}}) {
  0   0        
101 0           my $item = $self->{menu}->[$index];
102 0           my $orig = { label => $item->{label}, func => $item->{func} };
103 0 0         $self->{menu}->[$index]->{label} = $label if defined $label;
104 0 0         $self->{menu}->[$index]->{func} = $func if defined $func;
105 0           return $orig;
106             }
107 0           return undef;
108             }
109              
110              
111             #: $screen->run();
112             #: Blocking call, display the menu and react once. Returns 0 if cancelled,
113             #: returns 1 if an item was selected and the function called.
114             #
115             sub run {
116 0     0 1   my ($self) = @_;
117 0           my @menu_list = ();
118 0           my $c = 1;
119 0           foreach my $data (@{$self->{menu}}) {
  0            
120 0           push(@menu_list,$c,$data->{label});
121 0           $c++;
122             }
123             my $sel = $self->{dialog}->menu
124             (
125             title => (defined $self->{title}) ? $self->{title} : '',
126 0 0         text => (defined $self->{text}) ? $self->{text} : '',
    0          
127             list => \@menu_list
128             );
129 0 0         if ($self->{dialog}->state() eq "OK") {
130 0           my $data = $self->{menu}->[$sel-1];
131 0           my $func = $data->{func};
132 0 0 0       &{$func}($self,$self->{dialog},$sel-1) if defined $func and ref($func) eq "CODE";
  0            
133 0           return 1;
134             } else {
135 0 0         if (exists $self->{cancel}) {
136 0           my $func = $self->{cancel};
137 0 0 0       &{$func}($self,$self->{dialog},-1) if defined $func and ref($func) eq "CODE";
  0            
138             }
139             }
140 0           return 0;
141             }
142              
143             #: $screen->loop();
144             #: Blocking call, execute $screen->run() indefinitely. If run() was cancelled,
145             #: the loop will break.
146             sub loop {
147 0     0 1   my ($self) = @_;
148 0           $self->{__loop_active} = TRUE;
149 0           while ($self->{__loop_active}) {
150 0 0         last unless $self->run();
151             }
152             }
153              
154             #: $screen->break_loop();
155             #: Notify loop() to break instead of re-iterate regardless of user input.
156             #
157             sub break_loop {
158 0     0 1   my ($self) = @_;
159 0           $self->{__loop_active} = FALSE;
160             }
161              
162             #: $screen->is_looping();
163             #: Returns TRUE if currently looping, FALSE otherwise
164             #
165             sub is_looping {
166 0     0 1   my ($self) = @_;
167 0 0         return ($self->{__loop_active}) ? TRUE : FALSE;
168             }
169              
170             1; # END OF UI::Dialog::Screen::Menu