File Coverage

blib/lib/Term/Graille/Selector.pm
Criterion Covered Total %
statement 12 87 13.7
branch 0 34 0.0
condition 0 29 0.0
subroutine 4 19 21.0
pod 6 9 66.6
total 22 178 12.3


line stmt bran cond sub pod time code
1             package Term::Graille::Selector;
2              
3 1     1   970 use strict;use warnings;
  1     1   3  
  1         27  
  1         5  
  1         2  
  1         28  
4 1     1   5 use Term::Graille qw/colour printAt clearScreen border cursorAt/;
  1         2  
  1         50  
5 1     1   5 use utf8;
  1         2  
  1         5  
6              
7              
8             our $VERSION=0.10;
9              
10             =head3 Cnew(%params)>
11              
12             Creates a new $chooser; params are
13             C the possible options that may be selected
14             C This is a function to redraws the application screen.
15             The chooser may overwrite parts of the application screen, and this
16             function needs to be provided to restore the screen.
17             C The chooser does not call any functions, instead returns the
18             selected item(s). It is upto the main application to use this data (the
19             callback function supplied)
20             C Optional. The default position is [2,2], but setting this parameter allows
21             the chooser to be placed elsewhere
22             C Optional. The selected item is highlighted default "black on_white"
23             C Optional. The normal colour of menu items "white on_black"
24              
25              
26             =cut
27              
28              
29             sub new{
30 0     0 1   my ($class,%params) = @_;
31 0           my $self={};
32 0           bless $self,$class;
33 0 0         $self->{redraw}=$params{redraw} if (exists $params{redraw}); # function to redraw application
34 0 0         $self->{callback}=$params{callback} if (exists $params{callback}); # function to call after menu item selected
35 0   0       $self->{options}=$params{options}//[];
36 0   0       $self->{selected}=$params{selected}// "";
37 0   0       $self->{combo}=$params{combo}// 1; # combo mode...experimental
38 0   0       $self->{entry}=$params{selected}// "";
39 0           $self->{entryPos}=0;
40 0           $self->{pointer}=0;
41 0   0       $self->{param}=$params{param}//{}; # this hashref may be passed for persistent data
42 0   0       $self->{start}=$params{start}//0;
43 0   0       $self->{title}=$params{title}//"Chooser";
44 0   0       $self->{normalColour}=$params{titleColour}//"yellow";
45 0   0       $self->{multi}=$params{multi}//0;
46 0   0       $self->{pos}=$params{pos}//[2,2];
47 0   0       $self->{geometry}=$params{geometry}//[13,20];
48 0   0       $self->{highlightColour}=$params{highlightColour}//"black on_white";
49 0   0       $self->{normalColour}=$params{normalColour}//"white on_black";
50             $self->{keyAction}={
51 0     0     "[A" =>sub{$self->prevItem()},
52 0     0     "[B" =>sub{$self->nextItem()},
53 0     0     "[C" =>sub{$self->selectItem(1)}, # passes 1 if selected with right arrow
54 0     0     "enter"=>sub{$self->selectItem(2)}, # passes 2 if selected with enter (the entry box is queried)
55 0     0     "esc" =>sub{$self->{close}->()},
56 0     0     others =>sub{my ($obj,$pressed,$gV)=@_;$self->addChar($pressed)},
  0            
57 0           };
58 0           return $self;
59             }
60              
61             sub draw{
62 0     0 0   my ($self)=@_;
63             border($self->{pos}->[0],$self->{pos}->[1],
64             $self->{pos}->[0]+$self->{geometry}->[0],$self->{pos}->[1]+$self->{geometry}->[1],
65             "thick",$self->{focus}?$self->{focusColour}:$self->{blurColour},
66 0 0         $self->{title},$self->{titleColour});
67              
68 0           $self->{start}++ while ($self->{pointer}>$self->{start}+$self->{geometry}->[0]-4); # the -4 user entry space for combo mode
69 0           $self->{start}-- while ($self->{pointer}<$self->{start});
70 0           printAt($self->{pos}->[0]+1,$self->{pos}->[1]+1, $self->{entry}.(" "x($self->{geometry}->[1]-length $self->{entry}))); # combo mode input linethe
71 0           printAt($self->{pos}->[0]+2,$self->{pos}->[1]+1, "-"x$self->{geometry}->[1]); # lower border for user entry space for combo mode
72              
73 0           foreach ($self->{start}..$self->{start}+$self->{geometry}->[0]-3){
74 0 0         if ($_<@{$self->{options}}){
  0            
75 0 0         my $colour=colour(isSelected($self,$self->{options}->[$_])?"black on_white":"white");
76 0 0         $colour.=colour(($_==$self->{pointer})?"underline":"");
77             printAt($self->{pos}->[0]+$_+3-$self->{start},$self->{pos}->[1]+1, #+3 is for user entry space for combo mode
78 0           $colour.$self->{options}->[$_].colour("reset"));
79             }
80             }
81             }
82              
83             sub addChar{
84 0     0 0   my ($self,$ch)=@_;
85 0 0         $self->{entry}.=$ch if (length $ch ==1 );
86 0 0         chop $self->{entry}if ($ch =~/back/ );
87 0           $self->draw();
88            
89             }
90              
91              
92             =head3 C
93             makes an item highlighted in the selector...this is just as a
94             visual cue...the cursor is at the underlined item
95              
96             =cut
97              
98             sub setSelected{
99 0     0 1   my ($self,$item)=@_;
100 0           for my $o (0..$#{$self->{options}}){
  0            
101 0 0         if ($self->{options}->[$o] eq $item){
102 0 0         if ($self->{multi}==0){
103 0           $self->{selected}=[$o]
104             }
105             else{
106             # for multiselect
107             }
108             }
109             }
110             }
111              
112              
113             =head3 C
114              
115             Test if an item has been preselected (used internallY
116              
117             =cut
118              
119             sub isSelected{
120 0     0 1   my ($self,$item)=@_;
121 0 0         my $sel=ref($self->{selected})?$self->{selected}:[$self->{selected}];
122 0           for my $s (@{$sel}){
  0            
123 0 0         return 1 if ($s eq $item)
124             }
125 0           return 0
126             }
127              
128              
129             =head3 C<$selector->nextItem()/prevItem()/selectItem()>
130              
131             These are internal methods to choose the item from the list using keys asin $selector->{keyActions} above;
132              
133             =cut
134              
135              
136             sub nextItem{
137 0     0 1   my ($self)=@_;
138 0 0         $self->{pointer}++ unless ($self->{pointer} >=$#{$self->{options}});
  0            
139 0           $self->draw();
140 0           return $self->{options}->[$self->{pointer}];
141             }
142              
143             sub prevItem{
144 0     0 1   my ($self)=@_;
145 0 0         $self->{pointer}-- unless ($self->{pointer} <=0);
146 0           $self->draw();
147 0           return $self->{options}->[$self->{pointer}];
148             }
149              
150             sub selectItem{
151 0     0 1   my ($self,$submitMethod)=@_;
152 0 0         if ($self->{multi}==0){
153 0 0 0       $self->{selected}=($self->{entry} and ($submitMethod == 2))?$self->{entry}:$self->{options}->[$self->{pointer}];
154 0           $self->{redraw}->();
155 0 0         $self->{callback}->({selected=>$self->{selected},method=>$submitMethod,%{$self->{param}}}) if $self->{callback};
  0            
156 0           return $self->{options}->[$self->{pointer}];
157             }
158             else{
159             #for multiselect
160             }
161             }
162              
163             sub close{ # what needs to be done before Interact de-activates widget
164 0     0 0   my ($self)=@_;
165 0           $self->{redraw}->();
166             }
167              
168             1;