Initial Import
[profile/ivi/clutter-toys.git] / attic / woohaa / wh-video-row-renderer.c
1 #include "wh-video-row-renderer.h"
2 #include "wh-video-model.h"
3 #include "wh-video-model-row.h"
4 #include "util.h"
5
6 G_DEFINE_TYPE (WHVideoRowRenderer, wh_video_row_renderer, CLUTTER_TYPE_ACTOR);
7
8 #define PAD 4
9
10 #define VIDEO_ROW_RENDERER_PRIVATE(o) \
11   (G_TYPE_INSTANCE_GET_PRIVATE ((o), WH_TYPE_VIDEO_ROW_RENDERER, WHVideoRowRendererPrivate))
12
13 typedef struct _WHVideoRowRendererPrivate WHVideoRowRendererPrivate;
14
15 struct _WHVideoRowRendererPrivate
16 {
17   WHVideoModelRow *row;
18   ClutterActor    *container;
19   ClutterActor    *thumbnail, *thumbnail_image;
20   ClutterActor    *title_label, *info_label, *date_label, *hr;
21   gint             width, height;
22   gboolean         active;
23 };
24
25 enum
26 {
27   PROP_0,
28   PROP_ROW
29 };
30
31 static void
32 sync_thumbnail (WHVideoRowRenderer *renderer)
33 {
34   GdkPixbuf                 *pixbuf; 
35   WHVideoRowRendererPrivate *priv;  
36
37   priv = VIDEO_ROW_RENDERER_PRIVATE(renderer);
38
39   pixbuf = wh_video_model_row_get_thumbnail (priv->row);
40
41   if (pixbuf)
42     {
43       ClutterEffectTemplate *effect;
44
45       if (priv->thumbnail_image)
46         g_object_unref (priv->thumbnail_image);
47
48       
49       priv->thumbnail_image = clutter_texture_new ();
50       if (priv->thumbnail_image == NULL)
51         return;
52
53       clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (priv->thumbnail_image),
54                                          gdk_pixbuf_get_pixels (pixbuf),
55                                          gdk_pixbuf_get_has_alpha (pixbuf),
56                                          gdk_pixbuf_get_width (pixbuf),
57                                          gdk_pixbuf_get_height (pixbuf),
58                                          gdk_pixbuf_get_rowstride (pixbuf),
59                                          gdk_pixbuf_get_n_channels (pixbuf), 
60                                          0,
61                                          NULL);
62
63       clutter_actor_set_position (priv->thumbnail_image, PAD + 2, PAD + 2);
64       clutter_actor_set_size (priv->thumbnail_image, 
65                               priv->height - (PAD*2) - 4, 
66                               priv->height - (PAD*2) - 4);
67       clutter_group_add(CLUTTER_GROUP(priv->container),
68                         priv->thumbnail_image);
69
70       effect
71         = clutter_effect_template_new (clutter_timeline_new (20, 60),
72                                        CLUTTER_ALPHA_SINE_INC);
73
74       clutter_actor_set_opacity (priv->thumbnail_image, 0);
75       clutter_actor_show (priv->thumbnail_image);
76       clutter_effect_fade (effect,
77                            priv->thumbnail_image,
78                            0xff,
79                            NULL,
80                            NULL);
81       g_object_unref (effect);
82     }
83 }
84
85 static void 
86 on_thumbnail_change (GObject        *object,
87                      GParamSpec     *pspec,
88                      WHVideoRowRenderer *renderer)
89 {
90   sync_thumbnail (renderer);
91 }
92
93 static void
94 wh_video_row_renderer_get_property (GObject *object, guint property_id,
95                                     GValue *value, GParamSpec *pspec)
96 {
97   WHVideoRowRenderer        *row = WH_VIDEO_ROW_RENDERER(object);
98   WHVideoRowRendererPrivate *priv;  
99   
100   priv = VIDEO_ROW_RENDERER_PRIVATE(row);
101
102   switch (property_id) 
103     {
104     case PROP_ROW:
105       g_value_set_object (value, priv->row);
106       break;
107     default:
108       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
109     }
110 }
111
112 static void
113 wh_video_row_renderer_set_property (GObject *object, guint property_id,
114                                     const GValue *value, GParamSpec *pspec)
115 {
116   WHVideoRowRenderer        *row = WH_VIDEO_ROW_RENDERER(object);
117   WHVideoRowRendererPrivate *priv;  
118   
119   priv = VIDEO_ROW_RENDERER_PRIVATE(row);
120
121   switch (property_id) 
122     {
123     case PROP_ROW:
124       if (priv->row)
125         g_object_unref(priv->row);
126       priv->row = g_value_get_object (value);
127       g_signal_connect (priv->row,
128                         "notify::thumbnail",
129                         G_CALLBACK (on_thumbnail_change),
130                         row);
131       g_object_ref(priv->row);
132       break;
133     default:
134       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
135     }
136 }
137
138 static void
139 wh_video_row_renderer_dispose (GObject *object)
140 {
141   if (G_OBJECT_CLASS (wh_video_row_renderer_parent_class)->dispose)
142     G_OBJECT_CLASS (wh_video_row_renderer_parent_class)->dispose (object);
143 }
144
145 static void
146 wh_video_row_renderer_finalize (GObject *object)
147 {
148   G_OBJECT_CLASS (wh_video_row_renderer_parent_class)->finalize (object);
149 }
150
151 static void
152 wh_video_row_renderer_allocate (ClutterActor    *self,
153                                 const ClutterActorBox *box,
154                                 gboolean absolute_origin_changed)
155 {
156   WHVideoRowRenderer        *row = WH_VIDEO_ROW_RENDERER(self);
157   WHVideoRowRendererPrivate *priv;  
158   ClutterActorBox            child_box;
159   ClutterUnit                container_width, container_height;
160   
161   priv = VIDEO_ROW_RENDERER_PRIVATE(row);
162
163   if ( (CLUTTER_UNITS_TO_INT(box->x2 - box->x1) != priv->width) 
164        || (CLUTTER_UNITS_TO_INT(box->y2 - box->y1) != priv->height))
165     {
166       ClutterColor color      = { 0xcc, 0xcc, 0xcc, 0xff };
167       ClutterColor info_color = { 0xde, 0xde, 0xde, 0xff };
168       gint  w,h;
169       gchar font_desc[32];
170       gchar *episode = NULL, *series = NULL, *info = NULL;
171       GDate *date;      
172       gchar  date_buf[32];
173
174       /* Keep a simple cache to avoid setting fonts up too much */
175       w = priv->width  = CLUTTER_UNITS_TO_INT(box->x2 - box->x1);
176       h = priv->height = CLUTTER_UNITS_TO_INT(box->y2 - box->y1);
177
178       clutter_actor_set_position (priv->thumbnail, PAD, PAD);
179       clutter_actor_set_size (priv->thumbnail, h-(PAD*2), h-(PAD*2));
180
181       g_snprintf(font_desc, 32, "Sans %ipx", (h*4)/8); 
182
183       clutter_label_set_text (CLUTTER_LABEL(priv->title_label),
184                               wh_video_model_row_get_title (priv->row));
185       clutter_label_set_font_name (CLUTTER_LABEL(priv->title_label), 
186                                    font_desc); 
187       clutter_label_set_color (CLUTTER_LABEL(priv->title_label), &color);
188       clutter_label_set_line_wrap (CLUTTER_LABEL(priv->title_label), FALSE);
189       clutter_label_set_ellipsize  (CLUTTER_LABEL(priv->title_label), 
190                                     PANGO_ELLIPSIZE_MIDDLE);
191
192       clutter_actor_set_width (priv->title_label, w - ((2*(h+PAD))));
193       clutter_actor_set_position (priv->title_label, h + PAD, PAD); 
194
195       g_snprintf(font_desc, 32, "Sans %ipx", (h*3)/12); 
196       wh_video_model_row_get_extended_info (priv->row, &series, &episode);
197
198       date = g_date_new();
199       
200       g_date_set_time_t (date, wh_video_model_row_get_age(priv->row)); 
201       g_date_strftime (date_buf, 32, "%x", date);
202       
203       info = g_strdup_printf("%s%s%s%s%s%s"
204                              "Added: %s",
205                              series != NULL  ? "Series: " : "",
206                              series != NULL  ?  series : "",
207                              series != NULL  ?  " " : "",
208                              episode != NULL ? "Episode: " : "",
209                              episode != NULL ?  episode : "",
210                              episode != NULL ?  " " : "",
211                              date_buf);
212       
213       clutter_label_set_text (CLUTTER_LABEL(priv->info_label), info);
214       clutter_label_set_font_name (CLUTTER_LABEL(priv->info_label), 
215                                    font_desc); 
216       clutter_label_set_color (CLUTTER_LABEL(priv->info_label), 
217                                &info_color);
218       clutter_label_set_line_wrap (CLUTTER_LABEL(priv->info_label), FALSE);
219       clutter_label_set_use_markup (CLUTTER_LABEL(priv->info_label), TRUE);
220       
221       clutter_actor_set_position (priv->info_label, 
222                                   h + PAD, 
223                                   PAD + clutter_actor_get_height(priv->title_label)); 
224       clutter_actor_set_width (priv->title_label, w - (2*h) + (2*PAD));
225       
226       g_free (info);
227       g_free (series);
228       g_free (episode);
229       g_date_free(date);
230
231       clutter_actor_set_size (priv->hr, w, 1);
232       clutter_actor_set_position (priv->hr, 0, h-1);
233
234       sync_thumbnail (row);
235
236       /* Force Update active look */
237       priv->active = ~priv->active;
238       wh_video_row_renderer_set_active (row, ~priv->active); 
239     }
240   
241   clutter_actor_get_sizeu (priv->container, 
242                            &container_width,
243                            &container_height);
244   child_box.x1 = 0;
245   child_box.y1 = 0;
246   child_box.x2 = container_width;
247   child_box.y2 = container_height;
248   clutter_actor_allocate (priv->container, 
249                           &child_box, 
250                           absolute_origin_changed);
251
252   CLUTTER_ACTOR_CLASS (wh_video_row_renderer_parent_class)->
253     allocate (self, box, absolute_origin_changed);
254 }
255
256 static void
257 wh_video_row_renderer_paint (ClutterActor *actor)
258 {
259   WHVideoRowRenderer        *row = WH_VIDEO_ROW_RENDERER(actor);
260   WHVideoRowRendererPrivate *priv;  
261   
262   priv = VIDEO_ROW_RENDERER_PRIVATE(row);
263
264   if (priv->width == 0 || priv->height ==0)
265     return;
266
267   clutter_actor_paint (CLUTTER_ACTOR(priv->container));
268 }
269
270 static void
271 wh_video_row_renderer_class_init (WHVideoRowRendererClass *klass)
272 {
273   GObjectClass        *object_class = G_OBJECT_CLASS (klass);
274   ClutterActorClass   *actor_class = CLUTTER_ACTOR_CLASS (klass);
275
276   g_type_class_add_private (klass, sizeof (WHVideoRowRendererPrivate));
277
278   object_class->get_property = wh_video_row_renderer_get_property;
279   object_class->set_property = wh_video_row_renderer_set_property;
280   object_class->dispose      = wh_video_row_renderer_dispose;
281   object_class->finalize     = wh_video_row_renderer_finalize;
282
283   actor_class->paint          = wh_video_row_renderer_paint;
284   actor_class->allocate = wh_video_row_renderer_allocate;
285   /* 
286    *  actor_class->realize    = wh_video_row_renderer__realize;
287    *  actor_class->unrealize  = parent_class->unrealize;
288   */  
289
290   g_object_class_install_property 
291     (object_class,
292      PROP_ROW,
293      g_param_spec_object ("row",
294                           "Row",
295                           "Row to render",
296                           WH_TYPE_VIDEO_MODEL_ROW,
297                           G_PARAM_CONSTRUCT|G_PARAM_READWRITE));
298 }
299
300 static void
301 wh_video_row_renderer_init (WHVideoRowRenderer *self)
302 {
303   ClutterColor color = { 0xcc, 0xcc, 0xcc, 0xff };
304   ClutterColor grey_col = { 0xde, 0xde, 0xde, 0xff };
305   WHVideoRowRendererPrivate *priv;  
306   
307   priv = VIDEO_ROW_RENDERER_PRIVATE(self);
308
309   priv->hr = clutter_rectangle_new_with_color (&grey_col);
310
311   priv->thumbnail = clutter_rectangle_new_with_color(&color);
312
313   priv->title_label = clutter_label_new();
314   priv->info_label = clutter_label_new();
315
316   priv->container = clutter_group_new();
317   clutter_actor_set_parent (priv->container, CLUTTER_ACTOR(self));
318
319   clutter_group_add_many (CLUTTER_GROUP(priv->container), 
320                           priv->hr,
321                           priv->thumbnail,
322                           priv->title_label,
323                           priv->info_label,
324                           NULL);
325
326   clutter_actor_show_all (priv->container);
327 }
328
329 void
330 wh_video_row_renderer_set_active (WHVideoRowRenderer *renderer, 
331                                   gboolean            setting)
332 {
333   /* FIXME: should be prop */
334   WHVideoRowRendererPrivate *priv = VIDEO_ROW_RENDERER_PRIVATE(renderer);
335
336   ClutterColor inactive_col = { 0xaa, 0xaa, 0xaa, 0xff };
337   ClutterColor   active_col = { 0xff, 0xff, 0xff, 0xff };
338   ClutterColor info_inactive_col = { 0xbb, 0xbb, 0xbb, 0xff };
339   ClutterColor info_active_col   = { 0xf3, 0xf3, 0xf3, 0xff };
340
341   if (priv->active == setting)
342     return;
343
344   priv->active = setting;
345
346   if (setting)
347     {
348       clutter_label_set_color (CLUTTER_LABEL(priv->title_label), 
349                                &active_col);
350       clutter_label_set_color (CLUTTER_LABEL(priv->info_label), 
351                                &info_active_col);
352       clutter_actor_set_opacity (CLUTTER_ACTOR(renderer), 0xff);
353
354     }
355   else
356     {
357       clutter_label_set_color (CLUTTER_LABEL(priv->title_label), 
358                                &inactive_col);
359       clutter_label_set_color (CLUTTER_LABEL(priv->info_label), 
360                                &info_inactive_col);
361       clutter_actor_set_opacity (CLUTTER_ACTOR(renderer), 0xff);
362     }
363
364
365
366 }
367
368 WHVideoRowRenderer*
369 wh_video_row_renderer_new (WHVideoModelRow *row)
370 {
371   return g_object_new (WH_TYPE_VIDEO_ROW_RENDERER, "row", row, NULL);
372 }
373