967dac943fcc585631fa606cffa9abcd8043affe
[picture-display.git] / lib / Display / Notifications.pm
1 package Display::Notifications;
2
3 use Clutter;
4 use POE::Session;
5 use Set::Object;
6 use strict;
7
8 my $delay = 5;
9
10 sub new {
11   my ($proto, $kernel, $session, $stage) = @_;
12   my $class = ref($proto) || $proto;
13
14   my $self = {
15     'kernel' => $kernel,
16     'session' => $session,
17     'stage' => $stage,
18   };
19
20   $self->{'blocks'} = Set::Object->new();
21
22   bless ($self, $class);
23   $self->init();
24   return $self;
25 }
26
27 sub add {
28   my ($self, $kernel, $notification) = @_[OBJECT, KERNEL, ARG0];
29
30   my $block = Clutter::Group->new();
31   $block->set_opacity(0);
32
33   my $bg = Clutter::Rectangle->new(Clutter::Color->parse('Black'));
34   $bg->set_width($self->{'stage'}->get_width() - 20);
35   $bg->set_opacity(100);
36
37   $block->add($bg);
38   $block->add($notification);
39
40   $bg->set_height($notification->get_height() + 10);
41   $bg->set_anchor_point(1, $bg->get_height());
42   $bg->set_position(10, $self->{'stage'}->get_height() - 10);
43
44   $notification->set_anchor_point(1, $notification->get_height());
45   $notification->set_position(20, $self->{'stage'}->get_height() - 20);
46   $notification->set_width($bg->get_width() - 20);
47
48   my $expire = time() + $delay;
49
50   $self->{'blocks'}->insert( {
51     'expire' => $expire, 
52     'block'  => $block
53   });
54
55   $self->{'stage'}->add($block);
56   my $effect = Clutter::EffectTemplate->new_for_duration(1000, 'main::smoothstep_inc');
57   my $timeline = Clutter::Effect->fade($effect, $block, 255);
58       
59   $kernel->delay_add('notifications_expire', $delay);
60
61   $timeline->start();
62 }
63
64 sub expire {
65   my ($self) = @_[OBJECT];
66
67   for my $block ($self->{'blocks'}->members()) {
68     if ($block->{'expire'} <= time()) {
69       my $old_effect = Clutter::EffectTemplate->new_for_duration(1000, 'main::smoothstep_inc' );
70       my $old = Clutter::Effect->fade($old_effect, $block->{'block'}, 0, $self->can('post_fade_out'), $self);
71       $old->start();
72     }
73   }
74 }
75
76 sub post_fade_out {
77   my ($old_timeline, $self) = @_;
78
79   for my $block ($self->{'blocks'}->members()) {
80     if ($block->{'expire'} <= time()) {
81       $self->{'stage'}->remove($block->{'block'});
82       $self->{'blocks'}->remove($block);
83
84       $block->{'block'}->remove_all()
85     }
86   }
87 }
88
89 sub init {
90   my $self = shift;
91
92   $self->{'kernel'}->state('notifications_add', $self, 'add');
93   $self->{'kernel'}->state('notifications_expire', $self, 'expire');
94 }
95
96 1;