Merge "musicplayer: add default thumbnail image" into tizen
[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 #define LIST_MEDIA_COND "media_type=0 OR \
32                         (media_type=1 AND copyright LIKE \"Unknown\")"
33
34 #define TEXT_NOCONTENT "No Photo & Video"
35
36 #define GRID_ITEM_X 206
37 #define GRID_ITEM_Y 206
38 #define GRID_NUM_ITEM 3
39
40 #define BOX_PADDING 62
41
42 struct _priv {
43         Evas_Object *base;
44         Evas_Object *layout;
45         Evas_Object *menu_btn;
46
47         layoutmgr *lmgr;
48
49         struct listmgr *listmgr;
50         struct listmgr_data *ldata;
51
52         struct mediadata *md;
53         int cur_index;
54
55         Eina_List *media_list;
56 };
57
58 static char *_grid_text_get(void *data, Evas_Object *obj, const char *part)
59 {
60         app_media *am;
61         app_media_info *info;
62         char buf[32];
63
64         if (!data)
65                 return NULL;
66
67         am = data;
68         info = app_media_get_info(am);
69         if (!info) {
70                 _ERR("failed to get media info");
71                 return NULL;
72         }
73
74         if (info->media_type != MEDIA_CONTENT_TYPE_VIDEO)
75                 return NULL;
76
77         if (!strcmp(part, PART_ELM_TEXT_PLAYTIME)) {
78                 util_time_string(buf, sizeof(buf),
79                                         info->video->duration, false);
80
81                 return strdup(buf);
82         }
83
84         return NULL;
85 }
86
87 static Evas_Object *_grid_content_get(void *data,
88                         Evas_Object *obj, const char *part)
89 {
90         Evas_Object *image;
91         app_media *am;
92         app_media_info *info;
93
94         if (!data)
95                 return NULL;
96
97         am = data;
98         info = app_media_get_info(am);
99         if (!info) {
100                 _ERR("failed to get media info");
101                 return NULL;
102         }
103
104         image = NULL;
105         if (!strcmp(part, PART_ELM_SWALLOW_THUMBNAIL)) {
106                 image = util_add_image(obj, info->thumbnail_path);
107                 if (!image) {
108                         _ERR("failed to create image object");
109                         return NULL;
110                 }
111
112                 evas_object_show(image);
113         } else if (!strcmp(part, PART_ELM_SWALLOW_VIDEO)) {
114                 if (info->media_type == MEDIA_CONTENT_TYPE_VIDEO) {
115                         image = util_add_image(obj, IMAGE_THUMBNAIL_PLAY);
116                         if (!image) {
117                                 _ERR("failed to create image object");
118                                 return NULL;
119                         }
120
121                         evas_object_show(image);
122                 }
123         }
124
125         return image;
126 }
127
128 static struct grid_class _gclass = {
129         .item_style = STYLE_GRID_GALLERY_ITEM,
130         .text_get = _grid_text_get,
131         .content_get = _grid_content_get
132 };
133
134 static void _grid_selected_cb(void *data, Elm_Object_Item *it)
135 {
136         app_media *am;
137         struct view_update_data vdata;
138         struct _priv *priv;
139
140         if (!data || !it) {
141                 _ERR("invalid argument");
142                 return;
143         }
144
145         priv = data;
146
147         am = elm_object_item_data_get(it);
148         if (!am) {
149                 _ERR("failed to get app media");
150                 return;
151         }
152
153         vdata.list = mediadata_get_medialist(priv->md);
154         vdata.index = util_get_media_index(vdata.list, am);
155         priv->cur_index = vdata.index;
156
157         viewmgr_update_view(VIEW_VIEWER, UPDATE_CONTENT, &vdata);
158         viewmgr_push_view(VIEW_VIEWER);
159 }
160
161 static struct listmgr_data *_create_listmgr_data(struct _priv *priv)
162 {
163         struct listmgr_data *data;
164         struct grid_ops *gops;
165
166         data = calloc(1, sizeof(*data));
167         if (!data)
168                 goto err;
169
170         data->menu_btn = priv->menu_btn;
171
172         data->grid_item_x = GRID_ITEM_X;
173         data->grid_item_y = GRID_ITEM_Y;
174         data->grid_num_item = GRID_NUM_ITEM;
175         data->box_padding = BOX_PADDING;
176
177         gops = calloc(1, sizeof(*gops));
178         if (!gops)
179                 goto err;
180
181         gops->gclass = &_gclass;
182         gops->selected_cb = _grid_selected_cb;
183         gops->ops_data = priv;
184
185         data->gops = gops;
186
187         return data;
188
189 err:
190         _ERR("failed to allocate memory");
191         return NULL;
192 }
193
194 static void _update_content_info(struct _priv *priv)
195 {
196         int photo, video;
197         char buf[128];
198
199         photo = mediadata_get_media_count(priv->md, E_MEDIA_PHOTO);
200         video = mediadata_get_media_count(priv->md, E_MEDIA_VIDEO);
201
202         if (photo < 0 || video < 0) {
203                 _ERR("failed to get media count");
204                 return;
205         }
206
207         snprintf(buf, sizeof(buf), "%d Photos, %d Videos", photo, video);
208
209         elm_object_part_text_set(priv->layout, PART_CONTENT_INFO, buf);
210 }
211
212 static void _update_content_list(struct _priv *priv)
213 {
214         Eina_List *list;
215
216         if (priv->media_list)
217                 return;
218
219         list = mediadata_get_list(priv->md, E_LIST_DATE);
220         if (!list) {
221                 elm_object_part_text_set(priv->layout,
222                                 PART_NOCONTENT, TEXT_NOCONTENT);
223                 return;
224         }
225
226         if (!listmgr_update_content_list(priv->listmgr, list))
227                 _ERR("failed to update list area");
228
229         priv->media_list = list;
230
231         _update_content_info(priv);
232 }
233
234 static bool _create(layoutmgr *lmgr, void *data)
235 {
236         struct listmgr *listmgr;
237         struct listmgr_data *ldata;
238         struct mediadata *md;
239         struct _priv *priv;
240         Evas_Object *base, *layout;
241
242         if (!lmgr) {
243                 _ERR("failed to get layoutmgr");
244                 return false;
245         }
246
247         if (!data) {
248                 _ERR("invalid argument");
249                 return false;
250         }
251
252         priv = calloc(1, sizeof(*priv));
253         if (!priv) {
254                 _ERR("failed to allocate priv");
255                 return false;
256         }
257
258         priv->menu_btn = (Evas_Object *)data;
259
260         base = layoutmgr_get_base(lmgr);
261         if (!base) {
262                 _ERR("failed to get base object");
263                 goto err;
264         }
265
266         layout = elm_layout_add(base);
267         if (!layout) {
268                 _ERR("failed to create layout");
269                 goto err;
270         }
271
272         if (!elm_layout_file_set(layout, EDJEFILE, GRP_GALLERY_LAYOUT)) {
273                 _ERR("failed to set layout file");
274                 goto err2;
275         }
276
277         ldata = _create_listmgr_data(priv);
278         if (!ldata) {
279                 _ERR("failed to create listmgr data");
280                 goto err2;
281         }
282
283         listmgr = listmgr_create(layout, (void *)ldata);
284         if (!listmgr) {
285                 _ERR("failed to create listmgr");
286                 goto err3;
287         }
288
289         md = mediadata_create(LIST_MEDIA_COND, E_SOURCE_ALL, E_SORT_DATE);
290         if (!md) {
291                 _ERR("failed to create mediadata");
292                 listmgr_destroy(listmgr);
293                 goto err3;
294         }
295
296         priv->base = base;
297         priv->layout = layout;
298         priv->lmgr = lmgr;
299         priv->listmgr = listmgr;
300         priv->ldata = ldata;
301         priv->md = md;
302
303         layoutmgr_set_layout_data(lmgr, LAYOUT_GALLERY, priv);
304
305         if (!listmgr_draw_list_area(listmgr)) {
306                 _ERR("failed to draw list area");
307                 mediadata_destroy(md);
308                 listmgr_destroy(listmgr);
309                 goto err3;
310         }
311
312         return true;
313
314 err3:
315         free(ldata);
316 err2:
317         evas_object_del(layout);
318 err:
319         free(priv);
320         return false;
321 }
322
323 static void _destroy(void *layout_data)
324 {
325         struct _priv *priv;
326
327         if (!layout_data) {
328                 _ERR("failed to get layout data");
329                 return;
330         }
331
332         priv = layout_data;
333
334         mediadata_free_list(priv->media_list);
335         mediadata_destroy(priv->md);
336
337         listmgr_destroy(priv->listmgr);
338         free(priv->ldata->gops);
339         free(priv->ldata);
340
341         evas_object_del(priv->layout);
342
343         free(priv);
344 }
345
346 static void _show(void *layout_data)
347 {
348         struct _priv *priv;
349
350         if (!layout_data) {
351                 _ERR("failed to layout data");
352                 return;
353         }
354
355         priv = layout_data;
356
357         evas_object_show(priv->layout);
358         elm_object_part_content_set(priv->base,
359                         PART_THUMBNAIL_AREA, priv->layout);
360 }
361
362 static void _hide(void *layout_data)
363 {
364         struct _priv *priv;
365
366         if (!layout_data) {
367                 _ERR("failed to get layout data");
368                 return;
369         }
370
371         priv = layout_data;
372
373         evas_object_hide(priv->layout);
374         elm_object_part_content_unset(priv->base, PART_THUMBNAIL_AREA);
375 }
376
377 static void _update(void *layout_data, int update_type, void *data)
378 {
379         struct _priv *priv;
380         int index;
381         bool update;
382
383         if (!layout_data) {
384                 _ERR("failed to get layout data");
385                 return;
386         }
387
388         priv = layout_data;
389
390         switch (update_type) {
391         case UPDATE_CONTENT:
392                 _update_content_list(priv);
393                 break;
394         case UPDATE_FOCUS:
395                 if (!data) {
396                         _ERR("invalid argument");
397                         return;
398                 }
399
400                 index = *(int *)data;
401
402                 if (priv->cur_index != index)
403                         update = true;
404                 else
405                         update = false;
406
407                 listmgr_update_focus_item(priv->listmgr, index, update);
408
409                 break;
410         default:
411                 break;
412         }
413 }
414
415 static layout_class _lclass = {
416         .layout_id = LAYOUT_GALLERY,
417         .create = _create,
418         .show = _show,
419         .hide = _hide,
420         .destroy = _destroy,
421         .update = _update,
422 };
423
424 layout_class *layout_gallery_get_lclass(void)
425 {
426         return &_lclass;
427 }