Initial Import
[profile/ivi/clutter-toys.git] / attic / astro-desktop / applications / contacts / astro-reflection.c
1 /*
2  * Copyright (C) 2007 OpenedHand Limited
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Author: Neil Jagdish Patel <njp@o-hand.com>
20  */
21
22
23 #include "astro-reflection.h"
24
25 #include <libastro-desktop/astro-defines.h>
26 #include <libastro-desktop/astro-utils.h>
27
28 #include "clutter-reflect-texture.h"
29
30 G_DEFINE_TYPE (AstroReflection, astro_reflection, CLUTTER_TYPE_GROUP);
31
32 #define ASTRO_REFLECTION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
33         ASTRO_TYPE_REFLECTION, AstroReflectionPrivate))
34
35 static GdkPixbuf *disc_bg = NULL;
36
37 struct _AstroReflectionPrivate
38 {
39   ClutterActor *songs;
40   ClutterActor *songs_reflect;
41   ClutterActor *texture;
42   ClutterActor *reflect;
43   GdkPixbuf    *pixbuf;
44
45   ClutterEffectTemplate *songs_temp;
46   ClutterTimeline       *songs_time;
47 };
48
49 enum
50 {
51   PROP_0,
52
53   PROP_PIXBUF
54 };
55
56 static void
57 fix_clip (ClutterTimeline *timeline,
58           gint             frame_num,
59           AstroReflection *reflection)
60 {
61   AstroReflectionPrivate *priv;
62   gint size;
63    
64   g_return_if_fail (ASTRO_IS_REFLECTION (reflection));
65   priv = reflection->priv;
66
67   size = clutter_actor_get_width (priv->songs);
68
69   astro_utils_set_clip (priv->songs_reflect,
70                         size - clutter_actor_get_x (priv->songs_reflect),
71                         0, size, size);
72 }
73
74 void
75 astro_reflection_set_active (AstroReflection *reflection,
76                              gboolean         active)
77 {
78   AstroReflectionPrivate *priv;
79   static ClutterTimeline *fade_time = NULL;
80   gint x = 0;
81   gint fade = 0;
82    
83   g_return_if_fail (ASTRO_IS_REFLECTION (reflection));
84   priv = reflection->priv;
85
86   if (active)
87   {
88     x = clutter_actor_get_width (priv->texture); 
89     fade = 100;
90   }
91   
92   clutter_effect_move (priv->songs_temp,
93                        priv->songs,
94                        x, clutter_actor_get_y (priv->songs),
95                        NULL, NULL);
96   clutter_effect_move (priv->songs_temp,
97                        priv->songs_reflect,
98                        x, clutter_actor_get_y (priv->songs_reflect),
99                        NULL, NULL);
100
101   fade_time = clutter_effect_fade (priv->songs_temp,
102                                    priv->songs_reflect,
103                                    fade,
104                                    NULL, NULL);
105   g_signal_connect (fade_time, "new-frame",
106                     G_CALLBACK (fix_clip), reflection);
107
108 }
109
110 void
111 astro_reflection_set_pixbuf (AstroReflection *reflection,
112                              GdkPixbuf       *pixbuf)
113 {
114   AstroReflectionPrivate *priv;
115   gint height;
116   
117   g_return_if_fail (ASTRO_IS_REFLECTION (reflection));
118   priv = reflection->priv;
119
120   if (CLUTTER_IS_ACTOR (priv->texture))
121     clutter_actor_destroy (priv->texture);
122   
123   if (CLUTTER_IS_ACTOR (priv->reflect))
124     clutter_actor_destroy (priv->reflect);
125
126   height = gdk_pixbuf_get_height (pixbuf);
127
128   /* Songs widget */
129   if (!disc_bg)
130     {
131       disc_bg = gdk_pixbuf_new_from_file_at_size (PKGDATADIR"/disc_bg.svg",
132                                                   height, height, NULL);
133     }
134   priv->songs = clutter_texture_new_from_pixbuf (disc_bg);
135   clutter_container_add_actor (CLUTTER_CONTAINER (reflection), priv->songs);
136   clutter_actor_set_size (priv->songs, height, height);
137   clutter_actor_set_position (priv->songs, 0, 0);
138
139   priv->songs_reflect = clutter_reflect_texture_new (CLUTTER_TEXTURE (priv->songs),
140                                                height * 0.7);
141   clutter_actor_set_opacity (priv->songs_reflect, 0);
142   clutter_container_add_actor (CLUTTER_CONTAINER (reflection), 
143                                priv->songs_reflect);
144   clutter_actor_set_position (priv->songs_reflect, 0, height+1);
145      
146   /* Album cover */
147   priv->texture = g_object_new (CLUTTER_TYPE_TEXTURE,
148                                 "pixbuf", pixbuf,
149                                 "tiled", FALSE,
150                                 NULL);
151
152   clutter_container_add_actor (CLUTTER_CONTAINER (reflection),
153                                priv->texture);
154   clutter_actor_set_position (priv->texture, 0, 0);
155   
156   priv->reflect = clutter_reflect_texture_new (CLUTTER_TEXTURE (priv->texture),
157                                                height * 0.7);
158   clutter_actor_set_opacity (priv->reflect, 100);
159   clutter_container_add_actor (CLUTTER_CONTAINER (reflection), 
160                                priv->reflect);
161   clutter_actor_set_position (priv->reflect, 0, height+1);
162   
163   clutter_actor_set_anchor_point (CLUTTER_ACTOR (reflection),
164                                   clutter_actor_get_width (priv->texture)/2,
165                                   height/2);
166
167   clutter_actor_show_all (CLUTTER_ACTOR (reflection));
168 }
169
170 /* GObject stuff */
171 static void
172 astro_reflection_set_property (GObject      *object, 
173                           guint         prop_id,
174                           const GValue *value,
175                           GParamSpec   *pspec)
176 {
177   AstroReflectionPrivate *priv;
178   
179   g_return_if_fail (ASTRO_IS_REFLECTION (object));
180   priv = ASTRO_REFLECTION (object)->priv;
181
182   switch (prop_id)
183   {
184     case PROP_PIXBUF:
185       astro_reflection_set_pixbuf (ASTRO_REFLECTION (object),
186                                    GDK_PIXBUF (g_value_get_object (value)));
187       break;
188     default:
189       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
190       break;
191   }
192 }
193
194 static void
195 astro_reflection_get_property (GObject    *object, 
196                                guint       prop_id,
197                                GValue     *value,
198                                GParamSpec *pspec)
199 {
200   AstroReflectionPrivate *priv;
201   
202   g_return_if_fail (ASTRO_IS_REFLECTION (object));
203   priv = ASTRO_REFLECTION (object)->priv;
204
205   switch (prop_id)
206   {
207     case PROP_PIXBUF:
208       g_value_set_object (value, G_OBJECT (priv->pixbuf));
209       break;
210     default:
211       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
212       break;
213   }
214 }
215
216 static void
217 astro_reflection_class_init (AstroReflectionClass *klass)
218 {
219   GObjectClass        *gobject_class = G_OBJECT_CLASS (klass);
220
221   gobject_class->set_property = astro_reflection_set_property;
222   gobject_class->get_property = astro_reflection_get_property;
223
224   g_object_class_install_property (
225     gobject_class,
226     PROP_PIXBUF,
227     g_param_spec_object ("pixbuf",
228                          "Pixbuf",
229                          "A pixbuf",
230                          GDK_TYPE_PIXBUF,
231                          G_PARAM_READWRITE));
232
233   g_type_class_add_private (gobject_class, sizeof (AstroReflectionPrivate));
234 }
235
236 static void
237 astro_reflection_init (AstroReflection *reflection)
238 {
239   AstroReflectionPrivate *priv;
240   priv = reflection->priv = ASTRO_REFLECTION_GET_PRIVATE (reflection);
241
242   priv->texture = NULL;
243   priv->reflect = NULL;
244
245   priv->songs_time = clutter_timeline_new_for_duration (600);
246   priv->songs_temp = clutter_effect_template_new (priv->songs_time, 
247                                                   clutter_sine_inc_func);
248 }
249
250 ClutterActor *
251 astro_reflection_new (GdkPixbuf *pixbuf)
252 {
253   ClutterActor *reflection =  g_object_new (ASTRO_TYPE_REFLECTION,
254                                             "pixbuf", pixbuf,
255                                             NULL);
256   return CLUTTER_ACTOR (reflection);
257 }
258