fix to use evas_object_color_set
[profile/tv/apps/native/air_mediahub.git] / src / layout / gallery.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <Elementary.h>
18 #include <media_content.h>
19 #include <app_debug.h>
20 #include <app_media.h>
21 #include <gridmgr.h>
22 #include <layoutmgr.h>
23 #include <viewmgr.h>
24
25 #include "define.h"
26 #include "view.h"
27 #include "data/mediadata.h"
28 #include "util/listmgr.h"
29 #include "util/util.h"
30
31 /*
32    FIXME
33 #define LIST_MEDIA_COND "media_type=0 OR \
34                         (media_type=1 AND copyright LIKE \"Unknown\")"
35 */
36 #define LIST_MEDIA_COND "(media_type=0 OR media_type=1) AND copyright LIKE \"Unknown\""
37
38 #define TEXT_NOCONTENT "No Photo & Video"
39
40 #define GRID_PADDING 6
41 #define GRID_ITEM_X (200 + GRID_PADDING)
42 #define GRID_ITEM_Y (200 + GRID_PADDING)
43 #define GRID_NUM_ITEM 3
44
45 #define BOX_PADDING (62 - GRID_PADDING)
46
47 #define IMAGE_FAVORITE_ALPHA 150
48
49 struct _priv {
50         Evas_Object *base;
51         Evas_Object *layout;
52         Evas_Object *menu_btn;
53
54         layoutmgr *lmgr;
55
56         struct listmgr *listmgr;
57         struct listmgr_data *ldata;
58
59         struct mediadata *md;
60         int cur_index;
61
62         Eina_List *media_list;
63 };
64
65 static char *_grid_text_get(void *data, Evas_Object *obj, const char *part)
66 {
67         app_media *am;
68         app_media_info *info;
69         char buf[32];
70
71         if (!data)
72                 return NULL;
73
74         am = data;
75         info = app_media_get_info(am);
76         if (!info) {
77                 _ERR("failed to get media info");
78                 return NULL;
79         }
80
81         if (info->media_type != MEDIA_CONTENT_TYPE_VIDEO)
82                 return NULL;
83
84         if (!strcmp(part, PART_ELM_TEXT_PLAYTIME)) {
85                 util_time_string(buf, sizeof(buf),
86                                         info->video->duration, false);
87
88                 return strdup(buf);
89         }
90
91         return NULL;
92 }
93
94 static Evas_Object *_grid_content_get(void *data,
95                         Evas_Object *obj, const char *part)
96 {
97         Evas_Object *image;
98         app_media *am;
99         app_media_info *info;
100
101         if (!data)
102                 return NULL;
103
104         am = data;
105         info = app_media_get_info(am);
106         if (!info) {
107                 _ERR("failed to get media info");
108                 return NULL;
109         }
110
111         image = NULL;
112         if (!strcmp(part, PART_ELM_SWALLOW_THUMBNAIL)) {
113                 image = util_add_image(obj, info->thumbnail_path);
114                 if (!image) {
115                         _ERR("failed to create image object");
116                         return NULL;
117                 }
118
119                 evas_object_show(image);
120         } else if (!strcmp(part, PART_ELM_SWALLOW_VIDEO)) {
121                 if (info->media_type == MEDIA_CONTENT_TYPE_VIDEO) {
122                         image = util_add_image(obj, IMAGE_THUMBNAIL_PLAY);
123                         if (!image) {
124                                 _ERR("failed to create image object");
125                                 return NULL;
126                         }
127
128                         evas_object_show(image);
129                 }
130         } else if (!strcmp(part, PART_ELM_SWALLOW_FAVORITE)) {
131                 if (!info->favorite)
132                         return NULL;
133
134                 image = util_add_image(obj, IMAGE_THUMBNAIL_FAVORITE);
135                 if (!image) {
136                         _ERR("failed to create image object");
137                         return NULL;
138                 }
139
140                 util_set_alpha_color(image, IMAGE_FAVORITE_ALPHA);
141
142                 evas_object_show(image);
143         }
144
145         return image;
146 }
147
148 static struct grid_class _gclass = {
149         .item_style = STYLE_GRID_GALLERY_ITEM,
150         .text_get = _grid_text_get,
151         .content_get = _grid_content_get
152 };
153
154 static void _grid_selected_cb(void *data, Elm_Object_Item *it)
155 {
156         app_media *am;
157         struct view_update_data vdata;
158         struct _priv *priv;
159
160         if (!data || !it) {
161                 _ERR("invalid argument");
162                 return;
163         }
164
165         priv = data;
166
167         am = elm_object_item_data_get(it);
168         if (!am) {
169                 _ERR("failed to get app media");
170                 return;
171         }
172
173         vdata.list = mediadata_get_medialist(priv->md);
174         vdata.index = util_get_media_index(vdata.list, am);
175         priv->cur_index = vdata.index;
176
177         viewmgr_update_view(VIEW_VIEWER, UPDATE_CONTENT, &vdata);
178         viewmgr_push_view(VIEW_VIEWER);
179 }
180
181 static struct listmgr_data *_create_listmgr_data(struct _priv *priv)
182 {
183         struct listmgr_data *data;
184         struct grid_ops *gops;
185
186         data = calloc(1, sizeof(*data));
187         if (!data)
188                 goto err;
189
190         data->menu_btn = priv->menu_btn;
191
192         data->grid_item_x = GRID_ITEM_X;
193         data->grid_item_y = GRID_ITEM_Y;
194         data->grid_num_item = GRID_NUM_ITEM;
195         data->box_padding = BOX_PADDING;
196
197         gops = calloc(1, sizeof(*gops));
198         if (!gops)
199                 goto err;
200
201         gops->gclass = &_gclass;
202         gops->selected_cb = _grid_selected_cb;
203         gops->ops_data = priv;
204
205         data->gops = gops;
206
207         return data;
208
209 err:
210         _ERR("failed to allocate memory");
211         return NULL;
212 }
213
214 static void _update_content_info(struct _priv *priv)
215 {
216         int photo, video;
217         char buf[128];
218
219         photo = mediadata_get_media_count(priv->md, E_MEDIA_PHOTO);
220         video = mediadata_get_media_count(priv->md, E_MEDIA_VIDEO);
221
222         if (photo < 0 || video < 0) {
223                 _ERR("failed to get media count");
224                 return;
225         }
226
227         snprintf(buf, sizeof(buf), "%d Photos, %d Videos", photo, video);
228
229         elm_object_part_text_set(priv->layout, PART_CONTENT_INFO, buf);
230 }
231
232 static void _update_content_list(struct _priv *priv)
233 {
234         Eina_List *list;
235
236         if (priv->media_list)
237                 return;
238
239         list = mediadata_get_list(priv->md, E_LIST_DATE);
240         if (!list) {
241                 elm_object_part_text_set(priv->layout,
242                                 PART_NOCONTENT, TEXT_NOCONTENT);
243                 return;
244         }
245
246         if (!listmgr_update_content_list(priv->listmgr, list))
247                 _ERR("failed to update list area");
248
249         priv->media_list = list;
250
251         _update_content_info(priv);
252 }
253
254 static bool _create(layoutmgr *lmgr, void *data)
255 {
256         struct listmgr *listmgr;
257         struct listmgr_data *ldata;
258         struct mediadata *md;
259         struct _priv *priv;
260         Evas_Object *base, *layout;
261
262         if (!lmgr) {
263                 _ERR("failed to get layoutmgr");
264                 return false;
265         }
266
267         if (!data) {
268                 _ERR("invalid argument");
269                 return false;
270         }
271
272         priv = calloc(1, sizeof(*priv));
273         if (!priv) {
274                 _ERR("failed to allocate priv");
275                 return false;
276         }
277
278         priv->menu_btn = (Evas_Object *)data;
279
280         base = layoutmgr_get_base(lmgr);
281         if (!base) {
282                 _ERR("failed to get base object");
283                 goto err;
284         }
285
286         layout = elm_layout_add(base);
287         if (!layout) {
288                 _ERR("failed to create layout");
289                 goto err;
290         }
291
292         if (!elm_layout_file_set(layout, EDJEFILE, GRP_GALLERY_LAYOUT)) {
293                 _ERR("failed to set layout file");
294                 goto err2;
295         }
296
297         ldata = _create_listmgr_data(priv);
298         if (!ldata) {
299                 _ERR("failed to create listmgr data");
300                 goto err2;
301         }
302
303         listmgr = listmgr_create(layout, (void *)ldata);
304         if (!listmgr) {
305                 _ERR("failed to create listmgr");
306                 goto err3;
307         }
308
309         md = mediadata_create(LIST_MEDIA_COND, E_SOURCE_ALL, E_SORT_DATE);
310         if (!md) {
311                 _ERR("failed to create mediadata");
312                 listmgr_destroy(listmgr);
313                 goto err3;
314         }
315
316         priv->base = base;
317         priv->layout = layout;
318         priv->lmgr = lmgr;
319         priv->listmgr = listmgr;
320         priv->ldata = ldata;
321         priv->md = md;
322
323         layoutmgr_set_layout_data(lmgr, LAYOUT_GALLERY, priv);
324
325         if (!listmgr_draw_list_area(listmgr)) {
326                 _ERR("failed to draw list area");
327                 mediadata_destroy(md);
328                 listmgr_destroy(listmgr);
329                 goto err3;
330         }
331
332         return true;
333
334 err3:
335         free(ldata);
336 err2:
337         evas_object_del(layout);
338 err:
339         free(priv);
340         return false;
341 }
342
343 static void _destroy(void *layout_data)
344 {
345         struct _priv *priv;
346
347         if (!layout_data) {
348                 _ERR("failed to get layout data");
349                 return;
350         }
351
352         priv = layout_data;
353
354         mediadata_free_list(priv->media_list);
355         mediadata_destroy(priv->md);
356
357         listmgr_destroy(priv->listmgr);
358         free(priv->ldata->gops);
359         free(priv->ldata);
360
361         evas_object_del(priv->layout);
362
363         free(priv);
364 }
365
366 static void _show(void *layout_data)
367 {
368         struct _priv *priv;
369
370         if (!layout_data) {
371                 _ERR("failed to layout data");
372                 return;
373         }
374
375         priv = layout_data;
376
377         evas_object_show(priv->layout);
378         elm_object_part_content_set(priv->base,
379                         PART_THUMBNAIL_AREA, priv->layout);
380 }
381
382 static void _hide(void *layout_data)
383 {
384         struct _priv *priv;
385
386         if (!layout_data) {
387                 _ERR("failed to get layout data");
388                 return;
389         }
390
391         priv = layout_data;
392
393         evas_object_hide(priv->layout);
394         elm_object_part_content_unset(priv->base, PART_THUMBNAIL_AREA);
395 }
396
397 static void _update(void *layout_data, int update_type, void *data)
398 {
399         struct view_update_data *vdata;
400         struct _priv *priv;
401         bool update;
402
403         if (!layout_data) {
404                 _ERR("failed to get layout data");
405                 return;
406         }
407
408         priv = layout_data;
409         vdata = data;
410
411         switch (update_type) {
412         case UPDATE_CONTENT:
413                 _update_content_list(priv);
414                 break;
415         case UPDATE_FOCUS:
416                 if (!vdata) {
417                         _ERR("invalid argument");
418                         return;
419                 }
420
421                 if (priv->cur_index != vdata->index)
422                         update = true;
423                 else
424                         update = false;
425
426                 listmgr_focus_content_list(priv->listmgr, vdata->index, update);
427
428                 break;
429         case UPDATE_RESUME:
430                 listmgr_focus_content_list(priv->listmgr,
431                                 priv->cur_index, false);
432                 break;
433         default:
434                 break;
435         }
436 }
437
438 static layout_class _lclass = {
439         .layout_id = LAYOUT_GALLERY,
440         .create = _create,
441         .show = _show,
442         .hide = _hide,
443         .destroy = _destroy,
444         .update = _update,
445 };
446
447 layout_class *layout_gallery_get_lclass(void)
448 {
449         return &_lclass;
450 }