File Coverage

blib/lib/Curses/UI/Checkbox.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Curses::UI::Checkbox;
2              
3 1     1   649 use strict;
  1         1  
  1         32  
4 1     1   552 use Curses;
  0            
  0            
5             use Curses::UI::Label;
6             use Curses::UI::Widget;
7             use Curses::UI::Common;
8              
9             use vars qw( $VERSION @ISA );
10              
11             @ISA = qw( Curses::UI::ContainerWidget );
12              
13             =head1 NAME
14              
15             Curses::UI::Checkbox - Create and manipulate checkbox widgets
16              
17              
18             =head1 VERSION
19              
20             Version 1.11
21              
22             =cut
23              
24             $VERSION = '1.11';
25              
26             =head1 CLASS HIERARCHY
27              
28             Curses::UI::Widget
29             |
30             +----Curses::UI::Container
31             |
32             +----Curses::UI::Checkbox
33              
34              
35             =head1 SYNOPSIS
36              
37             use Curses::UI;
38             my $cui = new Curses::UI;
39             my $win = $cui->add('window_id', 'Window');
40              
41             my $checkbox = $win->add(
42             'mycheckbox', 'Checkbox',
43             -label => 'Say hello to the world',
44             -checked => 1,
45             );
46              
47             $checkbox->focus();
48             my $checked = $checkbox->get();
49              
50              
51             =head1 DESCRIPTION
52              
53             Curses::UI::Checkbox provides a checkbox widget.
54              
55             A checkbox is a control for a boolean value (an on/off toggle). It
56             consists of a box which will either be empty (indicating B or
57             B) or contain an C (indicating B or B). Following
58             this is a text label which described the value being controlled.
59              
60             [X] This checkbox is on/true/checked/selected
61             [ ] This checkbox is off/false/unchecked/deselected
62              
63             See exampes/demo-Curses::UI::Checkbox in the distribution for a short
64             demo.
65              
66             =cut
67              
68             my %routines = ( 'loose-focus' => \&loose_focus,
69             'uncheck' => \&uncheck,
70             'check' => \&check,
71             'toggle' => \&toggle,
72             'mouse-button1' => \&mouse_button1,
73             );
74              
75             my %bindings = ( KEY_ENTER() => 'loose-focus',
76             CUI_TAB() => 'loose-focus',
77             KEY_BTAB() => 'loose-focus',
78             CUI_SPACE() => 'toggle',
79             '0' => 'uncheck',
80             'n' => 'uncheck',
81             '1' => 'check',
82             'y' => 'check',
83             );
84              
85             =head1 STANDARD OPTIONS
86              
87             -x -y -width -height
88             -pad -padleft -padright -padtop -padbottom
89             -ipad -ipadleft -ipadright -ipadtop -ipadbottom
90             -title -titlefullwidth -titlereverse
91             -onfocus -onblur
92             -parent
93              
94             See L for an explanation of
95             these.
96              
97              
98             =head1 WIDGET-SPECIFIC OPTIONS
99              
100             =head2 -label
101              
102             Sets the initial label for the checkbox widget to the passed string or
103             value.
104              
105             =head2 -checked
106              
107             Takes a boolean argument. Determines if the widget's initial state is
108             checked or unchecked. The default is false (unchecked).
109              
110             =head2 -onchange
111              
112             Expects a coderef and sets it as a callback for the widget. When the
113             checkbox's state is changed, the given code will be executed.
114              
115             =cut
116              
117             sub new () {
118             my $class = shift;
119              
120             my %userargs = @_;
121             keys_to_lowercase(\%userargs);
122              
123             my %args = ( -parent => undef, # the parent window
124             -width => undef, # the width of the checkbox
125             -x => 0, # the horizontal pos. rel. to parent
126             -y => 0, # the vertical pos. rel. to parent
127             -checked => 0, # checked or not?
128             -label => '', # the label text
129             -onchange => undef, # event handler
130             -bg => -1,
131             -fg => -1,
132             %userargs,
133             -bindings => {%bindings},
134             -routines => {%routines},
135              
136             -focus => 0, # value init
137             -nocursor => 0, # this widget uses a cursor
138             );
139              
140             # The windowscr height should be 1.
141             $args{-height} = height_by_windowscrheight(1, %args);
142              
143             # No width given? Then make the width the same size as the label +
144             # checkbox.
145             $args{-width} = width_by_windowscrwidth(4 + length($args{-label}),%args)
146             unless defined $args{-width};
147              
148             my $this = $class->SUPER::new( %args );
149              
150             # Create the label on the widget.
151             $this->add( 'label', 'Label',
152             -text => $this->{-label},
153             -x => 4,
154             -y => 0,
155             -intellidraw => 0,
156             -bg => $this->{-bg},
157             -fg => $this->{-fg},
158             ) if $this->{-label};
159              
160             $this->layout;
161              
162             $this->set_mouse_binding('mouse-button1', BUTTON1_CLICKED())
163             if ($Curses::UI::ncurses_mouse);
164              
165             return $this;
166             }
167              
168              
169             =head1 STANDARD METHODS
170              
171             layout draw intellidraw
172             focus onFocus onBlur
173              
174             See L for an explanation of
175             these.
176              
177             =cut
178              
179             sub event_onblur() {
180             my $this = shift;
181             $this->SUPER::event_onblur;
182              
183             $this->{-focus} = 0;
184             $this->draw();
185              
186             return $this;
187             }
188              
189             sub layout() {
190             my $this = shift;
191              
192             my $label = $this->getobj('label');
193             if (defined $label) {
194             my $lh = $label->{-height};
195             $lh = 1 if $lh <= 0;
196             $this->{-height} = $lh;
197             }
198              
199             $this->SUPER::layout or return;
200             return $this;
201             }
202              
203             sub draw(;$) {
204             my $this = shift;
205             my $no_doupdate = shift || 0;
206              
207             # Draw the widget.
208             $this->SUPER::draw(1) or return $this;
209              
210             # Draw the checkbox.
211             if ($Curses::UI::color_support) {
212             my $co = $Curses::UI::color_object;
213             my $pair = $co->get_color_pair(
214             $this->{-fg},
215             $this->{-bg});
216             $this->{-canvasscr}->attron(COLOR_PAIR($pair));
217             }
218              
219             $this->{-canvasscr}->attron(A_BOLD) if $this->{-focus};
220             $this->{-canvasscr}->addstr(0, 0, '[ ]');
221             $this->{-canvasscr}->addstr(0, 1, 'X') if $this->{-checked};
222             $this->{-canvasscr}->attroff(A_BOLD) if $this->{-focus};
223              
224             $this->{-canvasscr}->move(0,1);
225             $this->{-canvasscr}->noutrefresh();
226             doupdate() unless $no_doupdate;
227              
228             return $this;
229             }
230              
231              
232             =head1 WIDGET-SPECIFIC METHODS
233              
234             =head2 get
235              
236             Returns the current state of the checkbox (0 == unchecked, 1 ==
237             checked).
238              
239             =cut
240              
241             sub get() {
242             my $this = shift;
243             return $this->{-checked};
244             }
245              
246             =head2 check
247              
248             Sets the checkbox to "checked".
249              
250             =cut
251              
252             sub check() {
253             my $this = shift;
254             my $changed = ($this->{-checked} ? 0 : 1);
255             $this->{-checked} = 1;
256             if ($changed) {
257             $this->run_event('-onchange');
258             $this->schedule_draw(1);
259             }
260             return $this;
261             }
262              
263             =head2 uncheck
264              
265             Sets the checkbox to "unchecked".
266              
267             =cut
268              
269             sub uncheck() {
270             my $this = shift;
271             my $changed = ($this->{-checked} ? 1 : 0);
272             $this->{-checked} = 0;
273             if ($changed) {
274             $this->run_event('-onchange');
275             $this->schedule_draw(1);
276             }
277             return $this;
278             }
279              
280             =head2 toggle
281              
282             Flip-flops the checkbox to its "other" state. If the checkbox is
283             unchecked then it will become checked, and vice versa.
284              
285             =cut
286              
287             sub toggle() {
288             my $this = shift;
289             $this->{-checked} = ($this->{-checked} ? 0 : 1);
290             $this->run_event('-onchange');
291             $this->schedule_draw(1);
292             }
293              
294             =head2 onChange
295              
296             This method can be used to set the C<-onchange> event handler (see
297             above) after initialization of the checkbox. It expects a coderef as
298             its argument.
299              
300             =cut
301              
302             sub onChange(;$) { shift()->set_event('-onchange', shift()) }
303              
304             sub mouse_button1($$$$;) {
305             my $this = shift;
306             my $event = shift;
307             my $x = shift;
308             my $y = shift;
309              
310             $this->focus();
311             $this->toggle();
312              
313             return $this;
314             }
315              
316             =head1 DEFAULT BINDINGS
317              
318             =over
319              
320             =item C<[TAB]>, C<[ENTER}>
321              
322             Call the 'loose-focus' routine, causing the widget to lose focus.
323              
324             =item C<[SPACE]>
325              
326             Call the L method.
327              
328             =item C<0>, C
329              
330             Call the L method.
331              
332             =item C<1>, C
333              
334             Call the L method.
335              
336             =back
337              
338              
339             =head1 SEE ALSO
340              
341             L,
342             L,
343             L
344              
345             =head1 AUTHOR
346              
347             Shawn Boyette C<< >>
348              
349             =head1 COPYRIGHT & LICENSE
350              
351             Copyright 2001-2002 Maurice Makaay; 2003-2006 Marcus Thiesen; 2007
352             Shawn Boyette. All Rights Reserved.
353              
354             This program is free software; you can redistribute it and/or modify
355             it under the same terms as Perl itself.
356              
357             This package is free software and is provided "as is" without express
358             or implied warranty. It may be used, redistributed and/or modified
359             under the same terms as perl itself.
360              
361             =cut
362              
363             1; # end of Curses::UI::Checkbox