| 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; |