File Coverage

blib/lib/Wx/Perl/TreeChecker.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             #############################################################################
2             ## Name: Wx::Perl::TreeChecker
3             ## Purpose: Tree Control with checkbox functionality
4             ## Author: Simon Flack
5             ## Modified by: $Author: simonflack $ on $Date: 2005/03/25 13:44:30 $
6             ## Created: 28/11/2002
7             ## RCS-ID: $Id: TreeChecker.pm,v 1.13 2005/03/25 13:44:30 simonflack Exp $
8             #############################################################################
9              
10             package Wx::Perl::TreeChecker;
11 1     1   845 use strict;
  1         3  
  1         34  
12 1     1   4 use vars qw(@ISA $VERSION @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         69  
13 1     1   367 use Wx ':treectrl', 'wxTR_MULTIPLE', 'WXK_SPACE';
  0            
  0            
14             use Wx::Event qw[EVT_LEFT_DOWN EVT_LEFT_DCLICK EVT_KEY_DOWN];
15             use Exporter;
16             use Carp;
17              
18             @ISA = ('Wx::TreeCtrl', 'Exporter');
19             $VERSION = sprintf'%d.%02d', q$Revision: 1.13 $ =~ /: (\d+)\.(\d+)/;
20             @EXPORT_OK = qw(TC_SELECTED TC_PART_SELECTED TC_SEL_COMPACT TC_SEL_FULL
21             TC_IMG_ROOT TC_IMG_C_NORMAL TC_NORMAL);
22             %EXPORT_TAGS = (status => [qw(TC_SELECTED TC_PART_SELECTED TC_SEL_COMPACT
23             TC_SEL_FULL)],
24             icons => [qw(TC_IMG_ROOT TC_IMG_C_NORMAL TC_IMG_NORMAL)]);
25              
26             use constant TC_SELECTED => 1; # tree item that is selected
27             use constant TC_PART_SELECTED => 2; # non-terminal tree item that has
28             # some children selected
29              
30             use constant TC_SEL_FULL => 0; # get all (part)?selected treeitems
31             use constant TC_SEL_COMPACT => 1; # get a compact list
32              
33             # Name the Wx::ImageList indices
34             use constant TC_IMG_ROOT => 0; # root icon
35             use constant TC_IMG_ROOT_SELECTED => 1; # ^ selected
36             use constant TC_IMG_ROOT_PART_SELECTED => 2; # ^ selected
37             use constant TC_IMG_C_NORMAL => 3; # container icon
38             use constant TC_IMG_C_SELECTED => 4; # ^ selected
39             use constant TC_IMG_C_PART_SELECTED => 5; # partially selected icon
40             use constant TC_IMG_NORMAL => 6; # normal icon
41             use constant TC_IMG_SELECTED => 7; # ^ selected
42              
43             my (%_multiple, %_images, %_containers_only, %_items_only, %_no_recurse);
44              
45             sub new {
46             my $class = shift;
47             my $opts = pop @_ if ref $_[-1] eq 'HASH';
48             my $self = $class -> SUPER::new (@_);
49              
50             $self -> _init ($opts || {});
51             bless $self, $class;
52             return $self;
53             }
54              
55             sub Convert {
56             my $class = shift;
57             my ($treectrl, $opts) = @_;
58             croak q[object isn't a Wx::TreeCtrl]
59             unless ref $treectrl && UNIVERSAL::isa($treectrl, 'Wx::TreeCtrl');
60             $treectrl = bless $treectrl, $class;
61              
62             $treectrl -> _init ($opts || {});
63             return $treectrl;
64             }
65              
66             sub _init {
67             my $self = shift;
68             my $opts = shift;
69              
70             # Wx::Perl::TreeCheckers should be wxTR_SINGLE only
71             my $flag = $self->GetWindowStyleFlag();
72             $flag &=~ wxTR_MULTIPLE;
73             $self->SetWindowStyleFlag($flag);
74              
75             $opts -> {allow_multiple} = 1 unless defined $opts -> {allow_multiple};
76             $self -> allow_multiple ($opts -> {allow_multiple});
77             EVT_LEFT_DOWN ($self, \&OnSelectCheckBox);
78             EVT_LEFT_DCLICK ($self, \&OnSelectCheckBox);
79             EVT_KEY_DOWN ($self, \&OnSelectCheckBox);
80              
81             $self -> image_list($opts -> {image_list} || $self -> _default_images());
82             $self -> containers_only ($opts -> {containers_only});
83             $self -> items_only ($opts -> {items_only});
84             $self -> no_recurse ($opts -> {no_recurse});
85             }
86              
87             sub DESTROY {
88             my $self = shift;
89             delete $_multiple {$self};
90             delete $_images {$self};
91             delete $_containers_only {$self};
92             delete $_items_only {$self};
93             delete $_no_recurse {$self};
94             }
95             ##############################################################################
96             # Accessors
97              
98             sub allow_multiple {
99             my $self = shift;
100             return $_multiple {$self} unless defined $_[0];
101             $_multiple {$self} = $_[0];
102             }
103              
104             sub image_list {
105             my $self = shift;
106             return $_images {$self} unless defined $_[0];
107             croak "USAGE: imagelist( Wx::ImageList)" unless
108             ref $_[0] && UNIVERSAL::isa($_[0], 'Wx::ImageList');
109             my $image_list = shift;
110             $self -> SUPER::SetImageList ($image_list);
111             $_images {$self} = $image_list;
112             }
113              
114             sub containers_only {
115             my $self = shift;
116             return $_containers_only {$self} unless defined $_[0];
117             croak q[ERROR: 'items_only' and 'containers_only' are mutually exclusive]
118             if $_[0] && $self -> items_only;
119             $_containers_only {$self} = $_[0];
120             }
121              
122             sub items_only {
123             my $self = shift;
124             return $_items_only {$self} unless defined $_[0];
125             croak q[ERROR: 'items_only' and 'containers_only' are mutually exclusive]
126             if $_[0] && $self -> containers_only;
127             $_items_only {$self} = $_[0];
128             }
129              
130             sub no_recurse {
131             my $self = shift;
132             return $_no_recurse {$self} unless defined $_[0];
133             $_no_recurse {$self} = $_[0];
134             }
135              
136             ##############################################################################
137             # Extras
138              
139              
140             sub IsContainer {
141             my $self = shift;
142             my $item = shift;
143             croak "USAGE: IsContainer(Wx::TreeItemId)" unless defined $item
144             && ref $item && UNIVERSAL::isa($item, 'Wx::TreeItemId');
145             my $data = $self -> Wx::TreeCtrl::GetPlData ($item);
146             return $data -> {container} || $self -> ItemHasChildren ($item)
147             }
148              
149             sub UnselectAll {
150             my $self = shift;
151             my $root = $self -> GetRootItem();
152             my $data = $self -> SUPER::GetPlData($root);
153             $data -> {selected} = 0;
154             $self -> SUPER::SetPlData($root, $data);
155             $self -> SetItemImage($root, TC_IMG_ROOT);
156             $self -> SetItemImage($root, TC_IMG_ROOT, wxTreeItemIcon_Selected);
157             $self -> _update_children($root, 0);
158             }
159              
160             ##############################################################################
161             # Overriden Wx::TreeCtrl Methods
162              
163             sub AddRoot {
164             my $self = shift;
165             my ($text, $data) = (@_)[0,-1];
166             my $_data = $self -> _makedata($data, 1);
167             $self -> SUPER::AddRoot($text, TC_IMG_ROOT, TC_IMG_ROOT, $_data);
168             }
169              
170             sub AppendItem {
171             my $self = shift;
172             my ($parent, $text, $data) = (@_)[0,1,-1];
173             my $_data = $self -> _makedata($data);
174             $self -> SUPER::AppendItem($parent, $text, TC_IMG_NORMAL, TC_IMG_NORMAL,
175             $_data);
176             }
177              
178             sub AppendContainer {
179             # This isn't a std Wx::TreeCtrl method - It's the same as AddItem() but
180             # adds a 'container'
181             my $self = shift;
182             my ($parent, $text, $data) = (@_)[0,1,-1];
183             my $_data = $self -> _makedata($data, 1);
184             $self -> SUPER::AppendItem($parent, $text, TC_IMG_C_NORMAL,
185             TC_IMG_C_NORMAL, $_data);
186             }
187              
188             sub PrependItem {
189             my $self = shift;
190             my ($parent, $text, $data) = (@_)[0,1,-1];
191             my $_data = $self -> _makedata($data);
192             $self -> SUPER::PrependItem($parent, $text, TC_IMG_NORMAL, TC_IMG_NORMAL,
193             $_data);
194             }
195              
196             sub PrependContainer {
197             my $self = shift;
198             my ($parent, $text, $data) = (@_)[0,1,-1];
199             my $_data = $self -> _makedata($data, 1);
200             $self -> SUPER::PrependItem($parent, $text, TC_IMG_C_NORMAL,
201             TC_IMG_C_NORMAL, $_data);
202             }
203              
204             sub InsertItem {
205             my $self = shift;
206             my ($parent, $previous, $text, $data) = (@_)[0,1,2,-1];
207             my $_data = $self -> _makedata($data);
208             $self -> SUPER::InsertItem($parent, $previous, $text, TC_IMG_NORMAL,
209             TC_IMG_NORMAL, $_data);
210             }
211              
212             sub InsertContainer {
213             my $self = shift;
214             my ($parent, $previous, $text, $data) = (@_)[0,1,2,-1];
215             my $_data = $self -> _makedata($data, 1);
216             $self -> SUPER::InsertItem($parent, $previous, $text, TC_IMG_C_NORMAL,
217             TC_IMG_C_NORMAL, $_data);
218             }
219              
220             BEGIN {
221             *InsertItemPrev = \&InsertItem;
222             *InsertItemBef = \&InsertItem;
223             *InsertConatinerPrev = \&InsertContainer;
224             *InsertContainerBef = \&InsertContainer;
225             };
226              
227             sub GetPlData {
228             my $self = shift;
229             my $item = shift;
230             my $_data = $self -> SUPER::GetPlData ($item);
231             return ref $_data ? $_data -> {_USERDATA} : $_data;
232             }
233              
234             sub SetPlData {
235             my $self = shift;
236             my ($item, $data) = @_;
237             my $_data = $self -> SUPER::GetPlData($item);
238             $_data -> {_USERDATA} = $data;
239             $self -> SUPER::SetPlData ($item, $_data);
240             }
241              
242             sub GetItemData {
243             my $self = shift;
244             my $item = shift;
245             return new Wx::TreeItemData($self -> GetPlData ($item));
246             }
247              
248             sub SetItemData {
249             my $self = shift;
250             my ($item, $data) = @_;
251             $self -> SetPlData ($item, $data -> GetData);
252             }
253              
254             sub IsSelected {
255             my $self = shift;
256             my $item = shift;
257             croak "USAGE: IsSelected(Wx::TreeItemId)" unless defined $item
258             && ref $item && UNIVERSAL::isa($item, 'Wx::TreeItemId');
259             my $data = $self -> SUPER::GetPlData ($item);
260             return $data -> {selected};
261             }
262              
263             sub SelectItem {
264             my $self = shift;
265             my $item = shift;
266             croak "USAGE: SelectItem(Wx::TreeItemId)" unless defined $item
267             && ref $item && UNIVERSAL::isa($item, 'Wx::TreeItemId');
268             if ($self -> allow_multiple) {
269             $self -> on_select_multiple ($item, 1)
270             } else {
271             $self -> on_select_single ($item, 1)
272             }
273             return 1 if $self -> IsSelected ($item);
274             }
275              
276             sub UnSelectItem {
277             my $self = shift;
278             my $item = shift;
279             croak "USAGE: UnSelectItem(Wx::TreeItemId)" unless defined $item
280             && ref $item && UNIVERSAL::isa($item, 'Wx::TreeItemId');
281             if ($self -> allow_multiple) {
282             $self -> on_select_multiple ($item, 0)
283             } else {
284             $self -> on_select_single ($item, 0)
285             }
286             return 1 if ! $self -> IsSelected ($item);
287             }
288              
289             sub GetImageList {
290             # Default method removes the list from memory
291             my $self = shift;
292             return $self -> image_list;
293             }
294              
295             sub SetImageList {
296             my $self = shift;
297             $self -> image_list(shift);
298             }
299              
300             sub GetSelection {
301             my $self = shift;
302             return $self -> _get_selected(@_);
303             }
304              
305             sub GetSelections {
306             my $self = shift;
307             return $self -> _get_selected(@_);
308             }
309              
310             ##############################################################################
311             # Event Handlers
312              
313             sub OnSelectCheckBox {
314             my ($self, $event) = @_;
315              
316             my $item;
317             if ($event->isa('Wx::KeyEvent')) {
318             return $event -> Skip (1) unless $event -> GetKeyCode() == WXK_SPACE;
319             $item = $self -> SUPER::GetSelection;
320             } else {
321             my $flags;
322             my $pos = $event -> GetPosition;
323             ($item, $flags) = $self -> HitTest ($pos);
324             return $event -> Skip (1) unless $flags & wxTREE_HITTEST_ONITEMICON;
325             $event -> Skip (0) if $event -> ButtonDClick;
326             }
327              
328             if ($self -> allow_multiple) {
329             $self -> on_select_multiple ($item)
330             } else {
331             $self -> on_select_single ($item)
332             }
333             }
334              
335             sub on_select_multiple {
336             my $self = shift;
337             my ($item, $_sel) = @_;
338              
339             my $data = $self -> SUPER::GetPlData($item);
340             $data->{selected} = $_sel || !$data -> {selected};
341             $self -> SUPER::SetPlData( $item, $data );
342              
343             my $container = $self -> IsContainer($item);
344             return if (!$container && $self -> containers_only());
345             return if ($container && $self -> items_only());
346              
347             my $imagename;
348             if ($container) {
349             $imagename = $data -> {selected} ? TC_IMG_C_SELECTED : TC_IMG_C_NORMAL;
350             if ($self -> no_recurse) {
351             $self -> _update_children($item, 0)
352             } else {
353             $self -> _update_children($item, $data -> {selected})
354             }
355             } else {
356             $imagename = $data -> {selected} ? TC_IMG_SELECTED : TC_IMG_NORMAL;
357             }
358              
359             my $treeroot = $self -> GetRootItem;
360             $imagename = $treeroot == $item ? $data->{selected} ? TC_IMG_ROOT_SELECTED
361             : TC_IMG_ROOT : $imagename;
362              
363             $self -> SetItemImage($item, $imagename);
364             $self -> SetItemImage($item, $imagename, wxTreeItemIcon_Selected);
365             $self -> _update_parents ($item);
366             }
367              
368             sub on_select_single {
369             my $self = shift;
370             my ($item, $_sel) = @_;
371              
372             my $data = $self -> SUPER::GetPlData($item);
373             my $container = $self -> IsContainer ($item);
374              
375             return if (!$container && $self -> containers_only());
376             return if ($container && $self -> items_only());
377              
378             $self -> UnselectAll();
379              
380             $data -> {selected} = $_sel || !$data -> {selected};
381             $self -> SUPER::SetPlData( $item, $data );
382              
383             my $imagename;
384             if ($data -> {container} || $self -> ItemHasChildren ($item)) {
385             $imagename = $data -> {selected} ? TC_IMG_C_SELECTED : TC_IMG_C_NORMAL;
386             $self -> _update_children($item, $data -> {selected})
387             unless $self -> no_recurse;
388             } else {
389             $imagename = $data -> {selected} ? TC_IMG_SELECTED : TC_IMG_NORMAL;
390             }
391              
392             my $treeroot = $self -> GetRootItem;
393             $imagename = $treeroot == $item ? $data->{selected} ? TC_IMG_ROOT_SELECTED
394             : TC_IMG_ROOT : $imagename;
395              
396             $self -> SetItemImage($item, $imagename);
397             $self -> SetItemImage($item, $imagename, wxTreeItemIcon_Selected);
398             }
399              
400             ##############################################################################
401             # Private methods
402              
403              
404             sub _update_children {
405             my ($self, $item, $selected) = @_;
406              
407             return unless $self -> ItemHasChildren ($item);
408             my $i_children = $self -> GetChildrenCount ($item, 0);
409              
410             my (@children, $num_sel, $cookie);
411             for ( 1 .. $i_children ) {
412             my $child_id;
413             if ($_ == 1) {
414             ($child_id, $cookie) = $self -> GetFirstChild ($item);
415             } else {
416             ($child_id, $cookie) = $self -> GetNextChild ($item, $cookie);
417             }
418             push @children, $child_id;
419             }
420              
421             foreach my $child_id ( @children ) {
422             my $data = $self -> SUPER::GetPlData ($child_id);
423             $data -> {selected} = $selected;
424             $self -> SUPER::SetPlData ($child_id, $data);
425              
426             my $imagename;
427             if ($data -> {container} || $self -> ItemHasChildren ($child_id)) {
428             $imagename = $data -> {selected} ? TC_IMG_C_SELECTED : TC_IMG_C_NORMAL;
429             $self -> _update_children($child_id, $selected);
430             } else {
431             $imagename = $data -> {selected} ? TC_IMG_SELECTED : TC_IMG_NORMAL;
432             }
433              
434             $self -> SetItemImage($child_id, $imagename);
435             $self -> SetItemImage($child_id, $imagename, wxTreeItemIcon_Selected);
436             }
437              
438             }
439              
440              
441             sub _update_parents {
442             my ($self, $item) = @_;
443              
444             my $parent = $self -> GetItemParent ($item);
445             return unless $parent;
446             my $parent_data = $self -> SUPER::GetPlData ($parent);
447              
448             # check if all of the children are selected:
449             return unless $self -> ItemHasChildren ($parent);
450             my $i_children = $self -> GetChildrenCount ($parent, 0);
451              
452             my $cookie = int rand 1000;
453             my (@children, $num_sel);
454              
455             for ( 1 .. $i_children ) {
456             my $child_id;
457             if ($_ == 1) {
458             ($child_id, $cookie) = $self -> GetFirstChild ($parent);
459             } else {
460             ($child_id, $cookie) = $self -> GetNextChild ($parent, $cookie);
461             }
462             push @children, $child_id;
463             }
464              
465             my @selected = map { $self -> SUPER::GetPlData($_)->{selected} } @children;
466             $num_sel = scalar grep $_ >= 1, @selected;
467             my $fully_selected = scalar grep $_ == 1, @selected;
468              
469             my $imagename;
470             my $_isroot = $self -> GetRootItem() == $parent;
471             if ($num_sel == 0) {
472             $imagename = $_isroot ? TC_IMG_ROOT : TC_IMG_C_NORMAL;
473             $parent_data->{selected} = 0;
474             } elsif ($num_sel == $i_children && $fully_selected == $num_sel) {
475             $imagename = $_isroot ? TC_IMG_ROOT_SELECTED : TC_IMG_C_SELECTED;
476             $parent_data->{selected} = TC_SELECTED;
477             } else {
478             $imagename = $_isroot ? TC_IMG_ROOT_PART_SELECTED
479             : TC_IMG_C_PART_SELECTED;
480             $parent_data->{selected} = TC_PART_SELECTED;
481             }
482              
483             $self -> SUPER::SetPlData( $parent, $parent_data );
484             $self -> SetItemImage($parent, $imagename);
485             $self -> SetItemImage($parent, $imagename, wxTreeItemIcon_Selected);
486              
487             $self -> _update_parents ($parent);
488             }
489              
490             sub _get_selected{
491             my $self = shift;
492             my ($style, $item) = @_;
493              
494             $style ||= TC_SEL_FULL;
495             $item ||= $self -> GetRootItem();
496              
497             my @_selected;
498             my $data = $self -> SUPER::GetPlData( $item );
499             my $container = $data -> {container} || $self -> ItemHasChildren ($item);
500              
501             if ($container && $data -> {selected}) {
502             if ($style == TC_SEL_COMPACT && $data -> {selected} == TC_SELECTED) {
503             return $item;
504             } elsif ($style == TC_SEL_FULL) {
505             if ($data -> {selected} == TC_SELECTED) {
506             return $item if $self -> no_recurse;
507             }
508             push @_selected, $item;
509             }
510             } elsif ($container) {
511             # if allow_multiple is true and the container isn't selected, then none
512             # of its children are
513             return () if $self -> allow_multiple;
514             } else {
515             return $data -> {selected} ? $item : ();
516             }
517              
518             # Now we recurse for all our children...
519             my $i_children = $self -> GetChildrenCount ($item, 0);
520              
521             my ($cookie);
522             for ( 1 .. $i_children ) {
523             my $child_id;
524             if ($_ == 1) {
525             ($child_id, $cookie) = $self -> GetFirstChild ($item);
526             } else {
527             ($child_id, $cookie) = $self -> GetNextChild ($item, $cookie);
528             }
529             my @c_selected = $self -> _get_selected ($style, $child_id);
530             push @_selected, @c_selected if @c_selected;
531             }
532             return @_selected;
533             }
534              
535              
536             sub _makedata {
537             my $self = shift;
538             my ($data, $container) = @_;
539              
540             if (ref $data && UNIVERSAL::isa($data, 'Wx::TreeItemData')) {
541             $data = $data -> GetData;
542             }
543              
544             $container = 0 unless defined $container;
545             my $_data = {
546             container => $container,
547             selected => 0,
548             _USERDATA => $data,
549             };
550             return new Wx::TreeItemData($_data);
551             }
552              
553             ##############################################################################
554             # Default Icons - XPM
555              
556             sub std_icons {
557             Wx::Image::AddHandler( new Wx::XPMHandler() );
558             my @icons;
559             push @icons, Wx::Icon->newFromXPM (_empty_checkbox());
560             push @icons, Wx::Icon->newFromXPM (_ticked_checkbox());
561             push @icons, Wx::Icon->newFromXPM (_grey_checkbox());
562              
563             return @icons;
564             }
565              
566             sub _default_images {
567             my $self = shift;
568              
569             my ($_empty_xpm, $_ticked_xpm, $_part_xpm) = $self -> std_icons();
570             my $_images = new Wx::ImageList (16, 16, 1);
571              
572             $_images -> Add( $_empty_xpm );
573             $_images -> Add( $_ticked_xpm );
574             $_images -> Add( $_part_xpm );
575             $_images -> Add( $_empty_xpm );
576             $_images -> Add( $_ticked_xpm );
577             $_images -> Add( $_part_xpm );
578             $_images -> Add( $_empty_xpm );
579             $_images -> Add( $_ticked_xpm );
580             $_images -> Add( $_part_xpm );
581             return $_images;
582             }
583              
584              
585             sub _empty_checkbox {
586             my $icon = [ map { m/^"(.*)"/ ? ( $1 ) : () } split /\n/, <<'EOT_E' ];
587             /* XPM */
588             static char * emptycheckbox_xpm[] = {
589             "16 16 2 1",
590             " c None",
591             ". c Black",
592             " ",
593             " .............. ",
594             " . . ",
595             " . . ",
596             " . . ",
597             " . . ",
598             " . . ",
599             " . . ",
600             " . . ",
601             " . . ",
602             " . . ",
603             " . . ",
604             " . . ",
605             " . . ",
606             " .............. ",
607             " "};
608             EOT_E
609             return $icon
610             }
611              
612             sub _ticked_checkbox {
613             my $icon = [ map { m/^"(.*)"/ ? ( $1 ) : () } split /\n/, <<'EOT_P' ];
614             /* XPM */
615             static char * tickedcheckbox_xpm[] = {
616             "16 16 3 1",
617             " c None",
618             ". c Black",
619             "o c Gray20",
620             " ",
621             " .............. ",
622             " .oooooooooooo. ",
623             " .oooooooooooo. ",
624             " .oooooooooooo. ",
625             " .oooooooooooo. ",
626             " .oooooooooooo. ",
627             " .oooooooooooo. ",
628             " .oooooooooooo. ",
629             " .oooooooooooo. ",
630             " .oooooooooooo. ",
631             " .oooooooooooo. ",
632             " .oooooooooooo. ",
633             " .oooooooooooo. ",
634             " .............. ",
635             " "};
636             EOT_P
637             return $icon
638              
639             }
640              
641             sub _grey_checkbox {
642             my $self = shift;
643             my @checkbox = @{_ticked_checkbox()};
644             $checkbox[3] = 'o c Gray60';
645             return \@checkbox
646             }
647              
648              
649             1;
650              
651             =pod
652              
653             =head1 NAME
654              
655             Wx::Perl::TreeChecker - Tree Control with checkbox functionality
656              
657             =head1 SYNOPSIS
658              
659             use Wx::Perl::TreeChecker;
660             my $tree = new Wx::Perl::TreeChecker( ... );
661             $tree -> allow_multiple(0);
662             $tree -> items_only(1);
663             # use tree like a normal treectrl
664              
665             my $tree = new Wx::TreeCtrl();
666             Wx::Perl::TreeChecker->Convert($tree, $options)
667              
668             my @selection = $tree->GetSelection();
669              
670             =head1 DESCRIPTION
671              
672             Wx::Perl::TreeChecker is a tree control with check boxes so users can select parts of the tree.
673              
674             A typical use would be a file-selector for backup / archive.
675              
676             =head1 EXPORTS
677              
678             Exports C and C which correspond to the status
679             returned by
680              
681             $tree -> IsSelected($item)
682              
683             C and C are also exported. See
684             L<"GetSelection(STYLE)"> for more information.
685              
686             You can export these constants with the ':status' import tag:
687              
688             use Wx::Perl::TreeChecker ':status';
689              
690             =head1 METHODS
691              
692             The methods listed here are only where there are syntactic differences to
693             C
694              
695             =over 4
696              
697             =item new (@std_args, \%treechecker)
698              
699             Where C<@std_args> are the regular arguments that you would pass to
700             Cnew()>.
701              
702             C<%treechecker> is an optional hash of options that customise the way that
703             C behaves. Valid keys:
704              
705             allow_multiple # can multiple selections be made (default: TRUE)
706             containers_only # user can only select containers (default: FALSE)
707             items_only # user can only select items (default: FALSE)
708             no_recurse # no recursion when user selects node (default: FALSE)
709             image_list # Wx::ImageList to use for checkbox icons
710             # (default provided)
711              
712             =item Convert (Wx::TreeCtrl, HASHREF)
713              
714             Converts a standard C into a C
715              
716             The first argument is a C. The seconds argument is an optional
717             hashref as C.
718              
719             =item AddRoot ($text, $data)
720              
721             Add a root to the control. Returns root id.
722              
723             As C, but image indices are removed
724              
725             =item AppendItem ($parent, $text, $data)
726              
727             Add an item to the control as the last child of C<$parent>. Returns item id.
728              
729             As C, but image indices are removed
730              
731             =item AppendContainer ($parent, $text, $data)
732              
733             Add a container to the control as the last child of C<$parent>. This does the
734             same as C but marks the node as a container.
735              
736             =item PrependItem ($parent, $text, $data)
737              
738             Add an item to the control as the first child of C<$parent>. Returns item id.
739              
740             =item PrependContainer ($parent, $text, $data)
741              
742             Add a container to the control as the first child of C<$parent>.
743              
744             =item InsertItem ($parent, $before | $previous, $text, $data)
745              
746             Inserts an item after a given one (previous) or before one identified by
747             its position (before).
748              
749             =item InsertContainer ($parent, $before | $previous, $text, $data)
750              
751             See InsertItem().
752              
753             =item GetSelection(STYLE)
754              
755             Returns a list of selected Cs. The behaviour can be controlled by the C