8664785c72921aab4a41fc2a1d74dfd197e18a33
[picture-display.git] / lib / Display / Plugins / FSpot.pm
1 package Display::Plugins::FSpot;
2
3 use base ('Display::Plugin');
4 use Clutter;
5 use POE;
6 use POE::Component::EasyDBI;
7 use strict;
8
9 my $default_f_spot_db = "$ENV{HOME}/.gnome2/f-spot/photos.db";
10 my $delay = 10;
11
12 sub new {
13   my $proto = shift;
14   my $class = ref($proto) || $proto;
15
16   my $self = $class->SUPER::new(@_);
17
18   $self->{'last_file'} = '';
19
20   bless ($self, $class);
21   $self->init_delay($delay, 'fspot_display');
22   $self->init();
23   return $self;
24 }
25
26 sub display_photo {
27   my ($self, $kernel, $args) = @_[OBJECT, KERNEL, ARG0];
28   my $file = $args->{'result'};
29   $file =~ s|^file://||;
30
31   # Keep on looking until we find a file that exists.
32   if (! -f $file || $file eq $self->{'last_file'}) {
33     $kernel->yield('fspot_display');
34     return;
35   } 
36   
37   #warn "Loading $file\n";
38   $self->{'new'}->set_opacity(0);
39   $self->{'new'}->set_size(-1, -1);
40   $self->{'new'}->set_from_file($file);
41   $self->{'new'}->set_opacity(0);
42   $self->{'new'}->set_height($self->{'stage'}->get_height());
43   $self->{'new'}->set_anchor_point(
44     $self->{'new'}->get_width / 2,
45     $self->{'new'}->get_height / 2
46   );
47   $self->{'new'}->set_position(
48     $self->{'stage'}->get_width / 2,
49     $self->{'stage'}->get_height / 2
50   );
51   #$self->{'stage'}->add($self->{'new'});
52
53 #warn "Going to show $file\n";
54   if ($self->{'last_file'} eq '') {
55     fade_in(undef, $self);
56   } else {
57     $self->fade_out();
58   }
59
60   $self->{'last_file'} = $file;
61   $self->delay();
62 }
63
64 sub fade_in {
65   my ($old_timeline, $self) = @_;
66
67   my $new_effect = Clutter::EffectTemplate->new_for_duration(1000, 'main::smoothstep_inc');
68   my $new = Clutter::Effect->fade($new_effect, $self->{'new'}, 255, $self->can('post_fade_in'), $self);
69   $new->start();
70
71 #  my $timeline = Clutter::Timeline->new_for_duration(1000);
72 #  $timeline->signal_connect('completed', $self->can('post_fade_in'), $self);
73 #  my $alpha    = Clutter::Alpha->new($timeline, 'main::smoothstep_inc');
74 #  my $opacity  = Clutter::Behaviour::Opacity->new($alpha, 0, 255);
75 #  $opacity->apply($self->{'new'});
76 #warn "Setup timeline, time to start it.\n";
77 #  $timeline->start();
78 }
79
80 sub post_fade_in {
81   my ($old_timeline, $self) = @_;
82
83   my $temp = $self->{'old'};
84   $self->{'old'} = $self->{'new'};
85   $self->{'new'} = $temp;
86 }
87
88 sub fade_out {
89   my ($self) = @_;
90
91   my $old_effect = Clutter::EffectTemplate->new_for_duration(1000, 'main::smoothstep_inc' );
92   my $old = Clutter::Effect->fade($old_effect, $self->{'old'}, 0, $self->can('fade_in'), $self);
93   $old->start();
94
95 #  my $timeline = Clutter::Timeline->new_for_duration(1000);
96 #  $timeline->signal_connect('completed', \&fade_in, $self);
97 #  my $alpha    = Clutter::Alpha->new($timeline, 'main::smoothstep_dec');
98 #  my $opacity  = Clutter::Behaviour::Opacity->new($alpha, 255, 0);
99 #  $opacity->apply($self->{'old'});
100 #  $timeline->start();
101 }
102
103
104 sub display {
105   my $self = shift;
106
107   $self->{'kernel'}->post('FSpotDB',
108     single => { sql => $self->{'sql'}, event => 'fspot_display_photo' }
109   );
110 }
111
112 sub init {
113   my $self = shift;
114
115   $self->{'kernel'}->state('fspot_display', $self, 'display');
116   $self->{'kernel'}->state('fspot_display_photo', $self, 'display_photo');
117
118   POE::Component::EasyDBI->spawn(
119     alias => 'FSpotDB',
120     dsn   => "dbi:SQLite:dbname=" . ($self->{'config'}{'_config'}{'plugins'}{'DB'} || $default_f_spot_db),
121     username => '',
122     password => '',
123   );
124
125   $self->{'sql'} = "
126 SELECT uri
127 FROM photos, photo_tags, tags
128   WHERE photos.id = photo_tags.photo_id
129   AND photo_tags.tag_id = tags.id
130   AND tags.name = 'Brooke'
131 ORDER BY random()
132 LIMIT 1
133 ";
134
135   for my $age ('new', 'old') {
136     $self->{$age} = Clutter::Texture->new();
137     $self->{$age}->set('request_mode' => 'width-for-height');
138     $self->{$age}->set('keep-aspect-ratio' => 1);
139     $self->{$age}->set('sync-size' => 1);
140     $self->{$age}->set_opacity(0);
141
142     $self->{'stage'}->add($self->{$age});
143   }
144
145 warn "Going to yield\n";
146   $self->{'kernel'}->yield('fspot_display');
147 }
148
149 1;