File Coverage

lib/Wx/Perl/EntryList/VirtualListCtrlView.pm
Criterion Covered Total %
statement 6 6 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1             package Wx::Perl::EntryList::VirtualListCtrlView;
2              
3             =head1 NAME
4              
5             Wx::Perl::EntryList::VirtualListCtrlView - display an entry list
6              
7             =head1 DESCRIPTION
8              
9             Uses a C to display an entry list and
10             automatically refreshes the appropriate part of the display when the
11             underlying entry list changes.
12              
13             =head1 METHODS
14              
15             =cut
16              
17 1     1   1338 use strict;
  1         2  
  1         79  
18             # FIXME hack!
19 1     1   6 use base qw(Wx::Perl::ListView Wx::Perl::ListCtrl Class::Accessor::Fast);
  1         1  
  1         850  
20              
21             use Wx qw(:listctrl);
22             use Wx::Event qw(EVT_LIST_BEGIN_DRAG EVT_LEFT_UP);
23              
24             __PACKAGE__->mk_accessors( qw(list) );
25              
26             =head2 new
27              
28             my $view = Wx::Perl::EntryList::VirtualListCtrlView->new
29             ( $entrylist, $model, $parent, $style );
30              
31             Creates a new view for the given entry list. C<$model> must be an
32             implementation of C, C<$parent> a parent
33             window for the control and C<$style> any style appropriate for
34             C.
35              
36             =cut
37              
38             sub new {
39             my( $class, $entrylist, $model, $parent, $style ) = @_;
40             my $self = $class->SUPER::new( $model, $parent, -1, [-1, -1], [-1, -1],
41             $style );
42             $self->list( $entrylist );
43             $entrylist->add_subscriber( '*', $self, '_list_changed' )
44             if $entrylist;
45              
46             return $self;
47             }
48              
49             sub DESTROY {
50             my( $self ) = @_;
51              
52             $self->list->delete_subscriber( '*', $self ) if $self->list;
53             }
54              
55             =head2 support_dnd
56              
57             $view->support_dnd;
58              
59             Enables items of the list to be moved by using drag and drop.
60              
61             =cut
62              
63             sub support_dnd {
64             my( $self ) = @_;
65              
66             EVT_LIST_BEGIN_DRAG( $self, $self, \&_begin_drag );
67             }
68              
69             sub _begin_drag {
70             my( $self, $event ) = @_;
71             $self->{_entrylist_dragging} = 1;
72             $self->{_entrylist_drag_index} = $event->GetIndex;
73             EVT_LEFT_UP( $self, \&_end_drag );
74             }
75              
76             sub _end_drag {
77             my( $self, $event ) = @_;
78             EVT_LEFT_UP( $self, undef );
79              
80             return unless $self->{_entrylist_dragging};
81             $self->{_entrylist_dragging} = 0;
82             my $to = $self->_entry( $event->GetX, $event->GetY );
83             return if $to < 0;
84              
85             $self->list->move_entry( $self->{_entrylist_drag_index}, $to );
86             }
87              
88             sub _entry {
89             my( $self, $x, $y ) = @_;
90             my( $item, $flags ) = $self->HitTest( [$x, $y] );
91              
92             if( $item < 0 || $flags & wxLIST_HITTEST_NOWHERE ) {
93             return $self->GetItemCount;
94             } elsif( $flags & wxLIST_HITTEST_ONITEM ) {
95             return $item;
96             } else {
97             return -1;
98             }
99             }
100              
101             sub _list_changed {
102             my( $self, $list, $event, %args ) = @_;
103              
104             my( $from, $to );
105             if( $event eq 'delete_entries' ) {
106             $self->refresh;
107             return;
108             } elsif( $event eq 'add_entries' ) {
109             ( $from, $to ) = ( $args{index}, $self->GetItemCount );
110             } elsif( $event eq 'move_entries' ) {
111             ( $from, $to ) = ( $args{from}, $args{to} );
112             }
113             my $items = $self->GetItemCount ? $self->GetItemCount - 1 : 0;
114             ( $from, $to ) = sort { $a <=> $b }
115             map $_ < 0 ? 0 :
116             $_ > $items ? $items :
117             $_, ( $from, $to );
118             $self->refresh( $from, $to );
119             }
120              
121             1;