source: extensions/pLoader/trunk/src/Uploader/GUI/wxImageListCtrl.pm

Last change on this file was 6707, checked in by ronosman, 14 years ago

use tranfer error messages in progress list. various bug fixes.

  • Property svn:eol-style set to LF
File size: 15.3 KB
Line 
1# +-----------------------------------------------------------------------+
2# | pLoader - a Perl photo uploader for Piwigo                            |
3# +-----------------------------------------------------------------------+
4# | Copyright(C) 2008-2010 Piwigo Team                  http://piwigo.org |
5# +-----------------------------------------------------------------------+
6# | This program is free software; you can redistribute it and/or modify  |
7# | it under the terms of the GNU General Public License as published by  |
8# | the Free Software Foundation                                          |
9# |                                                                       |
10# | This program is distributed in the hope that it will be useful, but   |
11# | WITHOUT ANY WARRANTY; without even the implied warranty of            |
12# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
13# | General Public License for more details.                              |
14# |                                                                       |
15# | You should have received a copy of the GNU General Public License     |
16# | along with this program; if not, write to the Free Software           |
17# | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
18# | USA.                                                                  |
19# +-----------------------------------------------------------------------+
20package Uploader::GUI::wxImageListCtrl;
21use strict;
22use Wx;
23use Wx::DND;
24use POSIX qw(ceil floor);
25use Wx::Locale qw/:default/;
26use Wx qw/
27             wxDefaultPosition
28             wxDefaultSize
29             wxLC_LIST
30             wxNO_BORDER
31             wxLC_EDIT_LABELS
32             wxLC_ICON
33             wxLC_REPORT
34             wxLC_SMALL_ICON
35             wxIMAGE_LIST_NORMAL
36             wxBITMAP_TYPE_JPEG
37             wxBITMAP_TYPE_PNG
38             wxBLACK
39             wxLC_REPORT
40             wxLIST_NEXT_ALL
41             wxLIST_STATE_SELECTED
42             wxLIST_STATE_DONTCARE
43             wxLIST_STATE_FOCUSED
44             wxIMAGE_LIST_SMALL
45             wxTheApp
46             wxVERTICAL
47             wxALIGN_CENTER
48             wxHORIZONTAL
49             wxALL
50             wxGROW
51             wxWHITE
52             wxSWISS
53             wxNORMAL
54             wxBOLD
55             wxBITMAP_TYPE_PNG
56         /;
57use Wx::Event qw/
58                    EVT_LIST_BEGIN_DRAG
59                    EVT_LIST_ITEM_SELECTED
60                    EVT_SIZE
61                /;
62         
63use base qw/Wx::ListCtrl Class::Accessor::Fast/;
64__PACKAGE__->mk_accessors( 
65    qw/
66          prevItemCount
67          imagenames
68          images
69          wx_imagelist
70          image_size
71          arrange_items
72          styles
73          insert_items
74          initialize
75          columns
76          display_mode_cbk
77          change_display_mode
78          wx_img
79          item_refresh
80          image_type
81      / 
82);
83use Data::Dumper;
84
85
86sub new {
87    my( $class, $params ) = @_;
88
89 
90    my( $self ) = $class->SUPER::new(
91        $params->{parentwnd},
92        -1,
93        wxDefaultPosition,
94        [ -1, -1],
95    );
96   
97    # for list mode
98    $self->wx_img(
99        Wx::ImageList->new( 16, 16, 1 )
100    );
101    $self->wx_img->Add(
102        Wx::Bitmap->new( wxTheApp->resource_path('image.png'), wxBITMAP_TYPE_PNG )   
103    );
104
105    $self->images(
106        $params->{images}
107    );
108
109    $self->image_size(
110        $params->{image_size}
111    );
112
113    $self->display_mode_cbk(
114        $params->{display_mode_cbk}
115    );
116
117    # bitmap container for photo selection
118    $self->wx_imagelist(
119        Wx::ImageList->new( 
120            $self->image_size, 
121            $self->image_size, 
122            1,
123            0
124        )
125    );
126
127    $self->load_images;
128
129    $self->columns(
130        $params->{columns}
131    );
132
133    $self->prevItemCount(-1);
134
135
136    EVT_LIST_BEGIN_DRAG( $self, $self, \&OnBeginDrag);
137
138    EVT_SIZE($self, sub {
139            my ( $this, $event ) = @_;
140   
141            $this->arrange_items(1);
142            $event->Skip();
143        }
144    );
145   
146    Wx::Event::EVT_IDLE(
147        $self,
148        sub {
149            my ($self, $event)=@_;
150
151            if($self->arrange_items){
152                $self->Refresh; 
153                $self->arrange_items(0);
154            }
155            if($self->change_display_mode){
156                my $disp_mode = $self->display_mode_cbk->();
157                $self->initialize->{$disp_mode}->($self) if exists $self->initialize->{$disp_mode};
158                $self->Refresh; 
159                $self->change_display_mode(0);
160            }
161            $event->Skip;
162        }
163    );
164
165    # manages empty panel position
166    Wx::Event::EVT_PAINT( $self, sub {
167            my ( $self, $event ) = @_;
168            if(exists $self->{_empty_panel}){
169                my ($w, $h) = $self->GetSizeWH;
170                my ($x, $y) = $self->GetPositionXY;
171                my ($wp, $hp) = $self->{_empty_panel}->GetSizeWH;
172                my $x_off = ($w-$wp)/3 > 0 ? ($w-$wp)/3 : 0;
173                my $y_off = ($h-$hp)/3 > 0 ? ($h-$hp)/3 : 0;
174                $self->{_empty_panel}->Move(
175                    [ $x+$x_off, $y+$y_off ]
176                );
177            }
178            $event->Skip;
179        }
180    );
181
182   
183    $self->initialize(
184        {
185
186            'Thumbnail' => sub {  my ( $self ) = @_;
187                                $self->Freeze;
188                                $self->ClearAll;
189                                $self->SetSingleStyle(wxLC_ICON);
190                                $self->SetSingleStyle(wxLC_EDIT_LABELS, 0);
191                                $self->SetImageList( $self->wx_imagelist, wxIMAGE_LIST_NORMAL ) ;
192                                $self->Thaw;
193                     },           
194            'Thumbnail and caption' => sub {  my ( $self ) = @_;
195                                $self->Freeze;
196                                $self->ClearAll;
197                                $self->SetSingleStyle(wxLC_ICON);
198                                $self->SetSingleStyle(wxLC_EDIT_LABELS);
199                                $self->SetImageList( $self->wx_imagelist, wxIMAGE_LIST_NORMAL ) ;
200                                $self->Thaw;
201                     },           
202             'Property list' => sub { my ( $self ) = @_;
203                                my $i=0;
204                               
205                                $self->Freeze;
206                                $self->ClearAll;
207                                $self->SetSingleStyle(wxLC_REPORT);
208                                $self->SetSingleStyle(wxLC_EDIT_LABELS);
209                                $self->SetImageList( $self->wx_img, wxIMAGE_LIST_SMALL ) ;
210                                map    {
211                                    $self->InsertColumn($i, $_->{label});
212                                    $i++;
213                                }@{$self->columns};                               
214                                $self->Thaw;
215                            },
216        }
217    );
218
219    $self->item_refresh(
220        {
221            'Thumbnail' => sub {},
222            'Thumbnail and caption' => sub { my ( $self, $index ) = @_;
223                                        my $image = $self->images->get_image($index);
224                                        $self->SetItem(
225                                            $index,
226                                            0,
227                                            $image->site_name,
228                                        ) if defined $image;
229                                    },
230            'Property list' => sub { my ( $self, $index ) = @_;
231                                my $col = 0;
232                                my $image = $self->images->get_image($index);
233                                map{
234                                    $self->SetItem(
235                                        $index,
236                                        $col,
237                                        $image->$_
238                                    ) if defined $image;
239                                    $self->SetColumnWidth($col, -1);
240                                    $col++;
241                                }
242                                qw/site_name site_comment site_author file create_date/;
243                            },
244        }
245    );
246   
247    $self->insert_items(
248        {
249            'Thumbnail' => sub { my ( $self, $index ) = @_; $self->InsertImageItem($index, $index);},
250            'Thumbnail and caption' => sub { my ( $self, $index ) = @_;
251                                           $self->InsertImageStringItem(
252                                               $index,
253                                               $self->images->get_image($index)->site_name,
254                                               $index,
255                                           ) if defined $self->images->get_image($index);
256                                     },
257            'Property list' => sub { my ( $self, $index ) = @_;
258                                       
259                                $self->InsertImageStringItem(
260                                    $index,
261                                    "",
262                                    0
263                                );
264                                $self->ItemRefresh($index);
265
266                            },
267        }
268    );
269
270    my $disp_mode = $self->display_mode_cbk->();
271    $self->initialize->{$disp_mode}->($self) if exists $self->initialize->{$disp_mode};
272
273    $self->init_empty_msg;
274
275    $self;
276}
277
278
279sub load_images {
280    my ( $self ) = @_;
281   
282    my $image_ids = $self->images->ordered_image_ids;
283    #print "load_images\n", Dumper $self->images->ordered_image_ids;
284    my $image_index = 0;
285    map {
286        my $image = $self->images->Image($_);
287
288        #print Dumper $image;
289        if(defined $image){
290            $self->load_image($image);
291        }
292        else{
293            # something went wrong
294            warn printf("Error loading image %s, %s\n", $image_index, $_);
295        }
296
297        $image_index++;
298    }
299    @$image_ids ;
300
301}
302
303
304sub load_image {
305    my ( $self, $image ) = @_;
306
307    my $wximagelist = $self->wx_imagelist;
308
309    unless( -e $image->wx_thumb_file ) {
310        $self->images->create_wx_thumbnail_cbk->($image)
311            if 'CODE' eq ref $self->images->create_wx_thumbnail_cbk;
312    }
313
314    $wximagelist->Add(
315        Wx::Bitmap->new( 
316            $image->wx_thumb_file, 
317            wxBITMAP_TYPE_JPEG,
318        )
319    );
320}
321
322sub ItemRefresh {
323    my ( $self, $index ) = @_;
324   
325    my $disp_mode = $self->display_mode_cbk->();
326    $self->item_refresh->{$disp_mode}->($self, $index) if exists $self->item_refresh->{$disp_mode};
327}
328
329sub OnBeginDrag {
330  my( $self, $event ) = @_;
331
332
333  my $data = Wx::TextDataObject->new( 
334      Dumper $self->selected_items
335  );
336  my $source = Wx::DropSource->new( $self );
337  $source->SetData( $data );
338
339  $source->DoDragDrop( 1 );
340}
341
342sub selected_items_count {
343    my ( $self ) = @_;   
344
345    scalar @{$self->selected_items};
346}
347
348
349sub selected_items {
350    my ( $self ) = @_;   
351
352  # find selected items
353  my $item = -1;
354  my $items = [];
355  while(1) {
356      $item = $self->GetNextItem(
357          $item,     
358          wxLIST_NEXT_ALL,
359          wxLIST_STATE_SELECTED
360      );
361      last if(-1 == $item);
362     
363      # item is selected   
364      push @$items, $item
365  }
366
367  $items;
368}
369
370sub all_items {
371    my ( $self ) = @_;   
372
373  # find selected items
374  my $item = -1;
375  my $items = [];
376  while(1) {
377      $item = $self->GetNextItem(
378          $item,     
379          wxLIST_NEXT_ALL,
380          wxLIST_STATE_DONTCARE
381      );
382      last if(-1 == $item);
383     
384      # item is selected   
385      push @$items, $item
386  }
387 
388  $items;
389   
390}
391
392
393sub add_image {
394    my ( $self, $wx_thumb_file ) = @_;
395
396
397    my $indx = $self->wx_imagelist->Add(
398        Wx::Bitmap->new( 
399            $wx_thumb_file,
400            wxBITMAP_TYPE_JPEG,
401        )
402    ) if defined $wx_thumb_file;
403
404   
405    $self->Refresh;
406}
407
408sub delete_image {
409    my ( $self, $indx ) = @_;
410
411    $self->wx_imagelist->Remove($indx);
412}
413
414
415sub Refresh {
416    my ( $self ) = @_;   
417
418   $self->Freeze();
419   $self->DeleteAllItems;
420   eval {
421       my $y0 = 0;
422       my $x0 = 0;
423
424       my $x_spacing = $self->image_size + 2;
425       my $y_spacing = $self->image_size + 2;
426       my $ipr = floor(($self->GetClientSize->GetWidth - 0.20*$x_spacing)/$x_spacing)||1;
427       for( my $i = 0 ; $i < $self->wx_imagelist->GetImageCount ; $i++){
428            # call the method corresponding to the display mode
429            my $disp_mode = $self->display_mode_cbk->();
430            my $indx = $self->insert_items->{$disp_mode}->($self, $i);
431            if( 'Thumbnail' eq $disp_mode){
432                my $row = floor($i/$ipr);
433                my $col = $i%$ipr;
434                $self->SetItemPosition(
435                    $i,
436                    Wx::Point->new(
437                        $x0 + $x_spacing*$col,
438                        $y0 + $y_spacing*$row,
439                    ),
440                );
441            }
442       }   
443   };
444
445   map{
446       $self->select_item(
447           $_
448       );
449       
450       $self->EnsureVisible($_);
451   } @{$self->images->selection||[]};
452
453   $self->Thaw();
454   $self->SetFocus;
455}
456
457sub select_item {
458    my ( $self, $index ) = @_;
459
460    $self->SetItemState(
461        $index,
462        wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED,
463        wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED
464    );   
465}
466
467sub OnEmpty {
468    my ( $self ) = @_;
469
470    $self->_OnEmptyLayout;
471
472}
473
474sub OnNotEmpty {
475    my ( $self ) = @_;
476
477    $self->{_empty_panel}->Show(0) if exists $self->{_empty_panel};
478}
479
480sub _OnEmptyLayout {
481
482    my( $self ) = @_;
483    $self->{_empty_panel}->Show(1);
484
485}
486
487sub add_button {
488    my ( $self ) = @_;
489
490    $self->{_add_bt};
491}
492
493sub init_empty_msg {
494
495    my ( $self ) = @_;
496    # add a panel
497    my $empty_panel = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize);
498    my( $item0 ) = Wx::BoxSizer->new( wxVERTICAL );
499   
500    my $fb = Wx::Font->new( 12, wxSWISS, wxNORMAL, wxBOLD );
501    my $fn = Wx::Font->new( 12, wxSWISS, wxNORMAL, wxNORMAL );
502
503    my( $item1 ) = Wx::StaticText->new( $empty_panel, -1, gettext("Drag photos here to get started"), wxDefaultPosition, wxDefaultSize, 0 );
504    $item1->SetFont($fb);
505    $item0->AddWindow( $item1, 0, wxALIGN_CENTER|wxALL, 5 );
506
507    my( $item2 ) = Wx::BoxSizer->new( wxHORIZONTAL );
508   
509    my( $item3 ) = Wx::StaticText->new( $empty_panel, -1, gettext("Or click"), wxDefaultPosition, wxDefaultSize, 0 );
510    $item3->SetFont($fn);
511    $item2->AddWindow( $item3, 0, wxALIGN_CENTER|wxALL, 5 );
512
513    my $icon1 = Wx::Icon->new();
514    eval {
515        $icon1->LoadFile(
516            wxTheApp->resource_path('tb_add.png'),
517            wxBITMAP_TYPE_PNG
518        );
519    };
520    my $bmp = Wx::Bitmap->new( $icon1 );
521
522    my( $item4 ) = Wx::BitmapButton->new( $empty_panel, -1, $bmp, wxDefaultPosition, wxDefaultSize );
523    $item2->AddWindow( $item4, 0, wxALIGN_CENTER|wxALL, 5 );
524
525    my( $item5 ) = Wx::StaticText->new( $empty_panel, -1, gettext("to choose files on your computer"), wxDefaultPosition, wxDefaultSize, 0 );
526    $item5->SetFont($fn);
527    $item2->AddWindow( $item5, 0, wxALIGN_CENTER|wxALL, 5 );
528
529    $item0->Add( $item2, 0, wxALIGN_CENTER|wxALL, 0 );
530
531    $empty_panel->SetSizer( $item0 );
532    $item0->SetSizeHints( $empty_panel );
533
534    $self->{_empty_panel} = $empty_panel;
535    $self->{_add_bt} = $item4;
536    $self->{_empty_panel}->SetBackgroundColour(wxWHITE);
537
538    my ($wp, $hp) = $self->{_empty_panel}->GetSizeWH;
539
540    $self->SetMinSize( [20+$wp, -1 ]);
541
542}
543
544
545sub is_empty {
546    my ( $self ) = @_;
547
548    !$self->GetItemCount;
549}
5501;
551
Note: See TracBrowser for help on using the repository browser.