Add logo support to notifications.
[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, $logo) = @_[OBJECT, KERNEL, ARG0, ARG1];
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
46   if (defined $logo) {
47     $block->add($logo);
48     $logo->set('keep-aspect-ratio' => 1);
49     $logo->set('sync-size' => 1);
50     $logo->set_height($notification->get_height());
51
52     $logo->set_position(20, $self->{'stage'}->get_height() - $bg->get_height - 20);
53     $notification->set_width($bg->get_width() - $logo->get_width() - 20 - 20);
54     $notification->set_position(20 + $logo->get_width() + 20, $self->{'stage'}->get_height() - 20);
55   } else {
56     $notification->set_position(20, $self->{'stage'}->get_height() - 20);
57     $notification->set_width($bg->get_width() - 20);
58   }
59
60   my $expire = time() + $delay;
61
62   $self->{'blocks'}->insert( {
63     'expire' => $expire, 
64     'block'  => $block
65   });
66
67   $self->{'stage'}->add($block);
68   my $effect = Clutter::EffectTemplate->new_for_duration(1000, 'main::smoothstep_inc');
69   my $timeline = Clutter::Effect->fade($effect, $block, 255);
70       
71   $kernel->delay_add('notifications_expire', $delay);
72
73   $timeline->start();
74 }
75
76 sub expire {
77   my ($self) = @_[OBJECT];
78
79   for my $block ($self->{'blocks'}->members()) {
80     if ($block->{'expire'} <= time()) {
81       my $old_effect = Clutter::EffectTemplate->new_for_duration(1000, 'main::smoothstep_inc' );
82       my $old = Clutter::Effect->fade($old_effect, $block->{'block'}, 0, $self->can('post_fade_out'), $self);
83       $old->start();
84     }
85   }
86 }
87
88 sub post_fade_out {
89   my ($old_timeline, $self) = @_;
90
91   for my $block ($self->{'blocks'}->members()) {
92     if ($block->{'expire'} <= time()) {
93       $self->{'stage'}->remove($block->{'block'});
94       $self->{'blocks'}->remove($block);
95
96       $block->{'block'}->remove_all()
97     }
98   }
99 }
100
101 sub init {
102   my $self = shift;
103
104   $self->{'kernel'}->state('notifications_add', $self, 'add');
105   $self->{'kernel'}->state('notifications_expire', $self, 'expire');
106 }
107
108 1;