| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
############################################################################# |
|
2
|
|
|
|
|
|
|
## Name: lib/Wx/DemoModules/wxTreeCtrl.pm |
|
3
|
|
|
|
|
|
|
## Purpose: wxPerl demo helper for Wx::TreeCtrl |
|
4
|
|
|
|
|
|
|
## Author: Mattia Barbon |
|
5
|
|
|
|
|
|
|
## Modified by: |
|
6
|
|
|
|
|
|
|
## Created: 17/02/2001 |
|
7
|
|
|
|
|
|
|
## RCS-ID: $Id: wxTreeCtrl.pm 3324 2012-08-09 01:21:55Z mdootson $ |
|
8
|
|
|
|
|
|
|
## Copyright: (c) 2001, 2004, 2006 Mattia Barbon |
|
9
|
|
|
|
|
|
|
## Licence: This program is free software; you can redistribute it and/or |
|
10
|
|
|
|
|
|
|
## modify it under the same terms as Perl itself |
|
11
|
|
|
|
|
|
|
############################################################################# |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
package Wx::DemoModules::wxTreeCtrl; |
|
14
|
|
|
|
|
|
|
|
|
15
|
1
|
|
|
1
|
|
1330
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
35
|
|
|
16
|
1
|
|
|
1
|
|
4
|
use base qw(Wx::TreeCtrl); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
696
|
|
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use Wx qw(:treectrl :window wxDefaultPosition wxDefaultSize |
|
19
|
|
|
|
|
|
|
wxMOD_ALT wxMOD_SHIFT wxMOD_META wxMOD_CONTROL); |
|
20
|
|
|
|
|
|
|
use Wx::Event qw(EVT_TREE_BEGIN_DRAG EVT_TREE_END_DRAG |
|
21
|
|
|
|
|
|
|
EVT_TREE_SEL_CHANGED EVT_MENU |
|
22
|
|
|
|
|
|
|
EVT_TREE_KEY_DOWN); |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
use Wx::DemoModules::lib::Utility; |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub new { |
|
27
|
|
|
|
|
|
|
my( $class, $parent ) = @_; |
|
28
|
|
|
|
|
|
|
my $self = $class->SUPER::new |
|
29
|
|
|
|
|
|
|
( $parent, -1, wxDefaultPosition, wxDefaultSize, |
|
30
|
|
|
|
|
|
|
wxTR_HAS_BUTTONS|wxTR_EDIT_LABELS|wxSUNKEN_BORDER ); |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my $imagelist = Wx::ImageList->new( 16, 16, 1 ); |
|
33
|
|
|
|
|
|
|
$imagelist->Add( Wx::GetWxPerlIcon( 1 ) ); |
|
34
|
|
|
|
|
|
|
$imagelist->Add |
|
35
|
|
|
|
|
|
|
( resize_to( Wx::wxTheApp()->GetStdIcon( Wx::wxICON_EXCLAMATION() ), |
|
36
|
|
|
|
|
|
|
16 ) ); |
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
$self->AssignImageList( $imagelist ); |
|
39
|
|
|
|
|
|
|
$self->PopulateTree( 2, 3 ); |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
EVT_TREE_BEGIN_DRAG( $self, $self, \&OnBeginDrag ); |
|
42
|
|
|
|
|
|
|
EVT_TREE_END_DRAG( $self, $self, \&OnEndDrag ); |
|
43
|
|
|
|
|
|
|
EVT_TREE_SEL_CHANGED( $self, $self, \&OnSelChange ); |
|
44
|
|
|
|
|
|
|
EVT_TREE_KEY_DOWN( $self, $self, \&OnTreeKeyDown ); |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# drop down menus |
|
47
|
|
|
|
|
|
|
my $top = Wx::GetTopLevelParent( $self ); |
|
48
|
|
|
|
|
|
|
my $treemenu = Wx::Menu->new; |
|
49
|
|
|
|
|
|
|
EVT_MENU( $top, $treemenu->Append( -1, "Traverse" ), |
|
50
|
|
|
|
|
|
|
sub { $self->on_traverse } ); |
|
51
|
|
|
|
|
|
|
my $itemmenu = Wx::Menu->new; |
|
52
|
|
|
|
|
|
|
EVT_MENU( $top, $itemmenu->Append( -1, "Rename" ), |
|
53
|
|
|
|
|
|
|
sub { $self->on_rename } ); |
|
54
|
|
|
|
|
|
|
EVT_MENU( $top, $itemmenu->Append( -1, "Sort childs ascending" ), |
|
55
|
|
|
|
|
|
|
sub { $self->on_sort( 1 ) } ); |
|
56
|
|
|
|
|
|
|
EVT_MENU( $top, $itemmenu->Append( -1, "Sort childs descending" ), |
|
57
|
|
|
|
|
|
|
sub { $self->on_sort( 0 ) } ); |
|
58
|
|
|
|
|
|
|
$itemmenu->AppendSeparator; |
|
59
|
|
|
|
|
|
|
EVT_MENU( $top, $itemmenu->Append( -1, "Deselect All" ), |
|
60
|
|
|
|
|
|
|
sub { $self->UnselectAll } ); |
|
61
|
|
|
|
|
|
|
$self->{menu} = [ '&Tree Control', $treemenu, |
|
62
|
|
|
|
|
|
|
'&Items', $itemmenu ]; |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
return $self; |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub on_sort { |
|
68
|
|
|
|
|
|
|
my( $self, $ascending ) = @_; |
|
69
|
|
|
|
|
|
|
my $item = $self->GetSelection; |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
if( !$item->IsOk ) { |
|
72
|
|
|
|
|
|
|
Wx::MessageBox( "Must select an item, first!" ); |
|
73
|
|
|
|
|
|
|
return; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
$self->DoSortChildren( $item, $ascending ); |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub on_rename { |
|
79
|
|
|
|
|
|
|
my( $self ) = @_; |
|
80
|
|
|
|
|
|
|
my $item = $self->GetSelection; |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
if( !$item->IsOk ) { |
|
83
|
|
|
|
|
|
|
Wx::MessageBox( "Must select an item, first!" ); |
|
84
|
|
|
|
|
|
|
return; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
$self->EditLabel( $item ); |
|
87
|
|
|
|
|
|
|
} |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub on_traverse { |
|
90
|
|
|
|
|
|
|
my( $self ) = @_; |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
$self->DoTraverse( $self->GetRootItem, -1 ); |
|
93
|
|
|
|
|
|
|
} |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub DoTraverse { |
|
96
|
|
|
|
|
|
|
my( $self, $parent ) = @_; |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# non-leaf: display now |
|
99
|
|
|
|
|
|
|
Wx::LogMessage( "%s", $self->GetItemText( $parent ) ); |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
my( $id, $cookie ) = $self->GetFirstChild( $parent ); |
|
102
|
|
|
|
|
|
|
while( $id->IsOk ) { |
|
103
|
|
|
|
|
|
|
# traverse childs first |
|
104
|
|
|
|
|
|
|
if( $self->ItemHasChildren( $id ) ) { |
|
105
|
|
|
|
|
|
|
$self->DoTraverse( $id, -1 ); |
|
106
|
|
|
|
|
|
|
} else { |
|
107
|
|
|
|
|
|
|
# display leaf |
|
108
|
|
|
|
|
|
|
Wx::LogMessage( "%s", $self->GetItemText( $id ) ); |
|
109
|
|
|
|
|
|
|
} |
|
110
|
|
|
|
|
|
|
( $id, $cookie ) = $self->GetNextChild( $parent, $cookie ); |
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub PopulateTree { |
|
115
|
|
|
|
|
|
|
my( $self, $childs, $depth ) = @_; |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
my $root = $self->AddRoot( 'Root', -1, -1, |
|
118
|
|
|
|
|
|
|
Wx::TreeItemData->new( 'Data' ) ); |
|
119
|
|
|
|
|
|
|
$self->PopulateRecursively( $root, $childs, $depth ); |
|
120
|
|
|
|
|
|
|
} |
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
sub PopulateRecursively { |
|
123
|
|
|
|
|
|
|
my( $self, $parent, $childs, $depth ) = @_; |
|
124
|
|
|
|
|
|
|
my( $text, $item ); |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
use Wx qw(wxITALIC_FONT wxRED wxBLUE); |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
foreach my $i ( 1 .. $childs ) { |
|
129
|
|
|
|
|
|
|
my $text = ( $depth > 0 ) ? "Node $i/$childs" : "Leaf $i/$childs"; |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
$item = $self->AppendItem( $parent, $text, 0, 1, |
|
132
|
|
|
|
|
|
|
Wx::TreeItemData->new( $text ) ); |
|
133
|
|
|
|
|
|
|
$self->SetItemFont( $item, wxITALIC_FONT ) if $depth == 0; |
|
134
|
|
|
|
|
|
|
$self->SetItemBackgroundColour( $item, wxBLUE ) if $depth == 1; |
|
135
|
|
|
|
|
|
|
$self->SetItemTextColour( $item, wxRED ) if $depth == 2; |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
if( $i == 2 ) { |
|
138
|
|
|
|
|
|
|
my $t = Wx::TreeItemData->new; $t->SetData( "Foo $i" ); |
|
139
|
|
|
|
|
|
|
$self->SetItemData( $item, $t ); |
|
140
|
|
|
|
|
|
|
} |
|
141
|
|
|
|
|
|
|
$self->SetPlData( $item, "Bar $i" ) |
|
142
|
|
|
|
|
|
|
if $i == 3; |
|
143
|
|
|
|
|
|
|
$self->GetItemData( $item )->SetData( "A" ) |
|
144
|
|
|
|
|
|
|
if $i == 4; |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
$self->PopulateRecursively( $item, $childs + 1, $depth - 1 ) |
|
147
|
|
|
|
|
|
|
if $depth >= 1; |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
} |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
sub DoSortChildren { |
|
152
|
|
|
|
|
|
|
my( $self, $item, $ascending ) = @_; |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
$self->{reverse_sort} = !$ascending; |
|
155
|
|
|
|
|
|
|
$self->SortChildren( $item ); |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub OnCompareItems { |
|
159
|
|
|
|
|
|
|
my( $self, $item1, $item2 ) = @_; |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
if( $self->{reverse_sort} ) { |
|
162
|
|
|
|
|
|
|
return $self->SUPER::OnCompareItems( $item2, $item1 ); |
|
163
|
|
|
|
|
|
|
} else { |
|
164
|
|
|
|
|
|
|
return $self->SUPER::OnCompareItems( $item1, $item2 ); |
|
165
|
|
|
|
|
|
|
} |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub OnBeginDrag { |
|
169
|
|
|
|
|
|
|
my( $self, $event ) = @_; |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
if( $event->GetItem != $self->GetRootItem ) { |
|
172
|
|
|
|
|
|
|
$self->{dragged_item} = $event->GetItem; |
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Wx::LogMessage( "Dragging %s", |
|
175
|
|
|
|
|
|
|
$self->GetItemText( $self->{dragged_item} ) ); |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
$event->Allow; |
|
178
|
|
|
|
|
|
|
} else { |
|
179
|
|
|
|
|
|
|
Wx::LogMessage( "This item can't be dragged" ); |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
# this is only a test: a real implementation probably will |
|
184
|
|
|
|
|
|
|
# move ( mot copy ) a node, and probably the node childrens, too |
|
185
|
|
|
|
|
|
|
# and drop the item at the right place ( not just append it ) |
|
186
|
|
|
|
|
|
|
sub OnEndDrag { |
|
187
|
|
|
|
|
|
|
my( $self, $event ) = @_; |
|
188
|
|
|
|
|
|
|
my( $src, $dst ) = ( $self->{dragged_item}, $event->GetItem ); |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
if( $dst->IsOk && !$self->ItemHasChildren( $dst ) ) { |
|
191
|
|
|
|
|
|
|
# copy to parent |
|
192
|
|
|
|
|
|
|
$dst = $self->GetParent( $dst ); |
|
193
|
|
|
|
|
|
|
} |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
if( !$dst->IsOk ) { |
|
196
|
|
|
|
|
|
|
Wx::LogMessage( "Can't drop here" ); |
|
197
|
|
|
|
|
|
|
return; |
|
198
|
|
|
|
|
|
|
} |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
my $text = $self->GetItemText( $src ); |
|
201
|
|
|
|
|
|
|
Wx::LogMessage( "'%s' copied to '%s'", $text, $self->GetItemText( $dst ) ); |
|
202
|
|
|
|
|
|
|
$self->AppendItem( $dst, $text, -1 ); |
|
203
|
|
|
|
|
|
|
} |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
sub OnSelChange { |
|
206
|
|
|
|
|
|
|
my( $self, $event ) = @_; |
|
207
|
|
|
|
|
|
|
my $item = $event->GetItem; |
|
208
|
|
|
|
|
|
|
my $data; |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
Wx::LogMessage( 'Text: %s', $self->GetItemText( $item ) ); |
|
211
|
|
|
|
|
|
|
if( $data = $self->GetItemData( $item ) ) { |
|
212
|
|
|
|
|
|
|
Wx::LogMessage( 'Data: %s', $data->GetData ); |
|
213
|
|
|
|
|
|
|
} |
|
214
|
|
|
|
|
|
|
Wx::LogMessage( 'Perl data: %s', $self->GetPlData( $item ) ); |
|
215
|
|
|
|
|
|
|
} |
|
216
|
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub OnTreeKeyDown { |
|
218
|
|
|
|
|
|
|
my( $self, $event ) = @_; |
|
219
|
|
|
|
|
|
|
my $keycode = $event->GetKeyCode; |
|
220
|
|
|
|
|
|
|
my $output = qq(KEYCODE: $keycode); |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# Wx >= 0.9911 |
|
223
|
|
|
|
|
|
|
if( defined( &Wx::TreeEvent::GetKeyEvent ) ) { |
|
224
|
|
|
|
|
|
|
my $modifiers = $event->GetKeyEvent->GetModifiers; |
|
225
|
|
|
|
|
|
|
$output .= qq( MODIFIERS:); |
|
226
|
|
|
|
|
|
|
if( $modifiers & wxMOD_ALT ) { |
|
227
|
|
|
|
|
|
|
$output .= qq( Alt); |
|
228
|
|
|
|
|
|
|
} |
|
229
|
|
|
|
|
|
|
if( $modifiers & wxMOD_SHIFT ) { |
|
230
|
|
|
|
|
|
|
$output .= qq( Shift); |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
if( $modifiers & wxMOD_CONTROL ) { |
|
233
|
|
|
|
|
|
|
$output .= qq( Control); |
|
234
|
|
|
|
|
|
|
} |
|
235
|
|
|
|
|
|
|
if( $modifiers & wxMOD_META ) { |
|
236
|
|
|
|
|
|
|
$output .= qq( Meta); |
|
237
|
|
|
|
|
|
|
} |
|
238
|
|
|
|
|
|
|
} |
|
239
|
|
|
|
|
|
|
Wx::LogMessage( qq(Keys $output) ); |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
} |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub menu { @{$_[0]->{menu}} } |
|
245
|
|
|
|
|
|
|
sub add_to_tags { qw(controls) } |
|
246
|
|
|
|
|
|
|
sub title { 'wxTreeCtrl' } |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
1; |