listmgr: focus to recently played content when viewer view is popped
[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
46         layoutmgr *lmgr;
47
48         struct listmgr *listmgr;
49         struct listmgr_data *ldata;
50
51         struct mediadata *md;
52
53         Eina_List *media_list;
54 };
55
56 static Evas_Object *_grid_content_get(void *data,
57                         Evas_Object *obj, const char *part)
58 {
59         Evas_Object *image;
60         app_media *am;
61         app_media_info *info;
62
63         if (!data)
64                 return NULL;
65
66         am = data;
67         info = app_media_get_info(am);
68         if (!info) {
69                 _ERR("failed to get media info");
70                 return NULL;
71         }
72
73         image = NULL;
74         if (!strcmp(part, PART_ELM_SWALLOW_THUMBNAIL)) {
75                 image = util_add_image(obj, info->thumbnail_path);
76                 if (!image) {
77                         _ERR("failed to create image object");
78                         return NULL;
79                 }
80
81                 evas_object_show(image);
82         } else if (!strcmp(part, PART_ELM_SWALLOW_VIDEO)) {
83                 if (info->media_type == MEDIA_CONTENT_TYPE_VIDEO) {
84                         image = util_add_image(obj, IMAGE_THUMBNAIL_PLAY);
85                         if (!image) {
86                                 _ERR("failed to create image object");
87                                 return NULL;
88                         }
89
90                         evas_object_show(image);
91                 }
92         }
93
94         return image;
95 }
96
97 static struct grid_class _gclass = {
98         .item_style = STYLE_GRID_GALLERY_ITEM,
99         .content_get = _grid_content_get
100 };
101
102 static void _grid_selected_cb(void *data, Elm_Object_Item *it)
103 {
104         app_media *am;
105         struct view_update_data vdata;
106         struct _priv *priv;
107
108         if (!data || !it) {
109                 _ERR("invalid argument");
110                 return;
111         }
112
113         priv = data;
114
115         am = elm_object_item_data_get(it);
116         if (!am) {
117                 _ERR("failed to get app media");
118                 return;
119         }
120
121         vdata.list = mediadata_get_medialist(priv->md);
122         vdata.index = util_get_media_index(vdata.list, am);
123
124         viewmgr_update_view(VIEW_VIEWER, UPDATE_CONTENT, &vdata);
125         viewmgr_push_view(VIEW_VIEWER);
126 }
127
128 static struct listmgr_data *_create_listmgr_data(struct _priv *priv)
129 {
130         struct listmgr_data *data;
131         struct grid_ops *gops;
132
133         data = calloc(1, sizeof(*data));
134         if (!data)
135                 goto err;
136
137         data->grid_item_x = GRID_ITEM_X;
138         data->grid_item_y = GRID_ITEM_Y;
139         data->grid_num_item = GRID_NUM_ITEM;
140         data->box_padding = BOX_PADDING;
141
142         gops = calloc(1, sizeof(*gops));
143         if (!gops)
144                 goto err;
145
146         gops->gclass = &_gclass;
147         gops->selected_cb = _grid_selected_cb;
148         gops->ops_data = priv;
149
150         data->gops = gops;
151
152         return data;
153
154 err:
155         _ERR("failed to allocate memory");
156         return NULL;
157 }
158
159 static void _update_list_area(struct _priv *priv)
160 {
161         Eina_List *list;
162
163         if (priv->media_list)
164                 return;
165
166         list = mediadata_get_list(priv->md, E_LIST_DATE);
167         if (!list) {
168                 elm_object_part_text_set(priv->layout,
169                                 PART_NOCONTENT, TEXT_NOCONTENT);
170                 return;
171         }
172
173         if (!listmgr_update_content_list(priv->listmgr, list))
174                 _ERR("failed to update list area");
175
176         priv->media_list = list;
177 }
178
179 static bool _create(layoutmgr *lmgr, void *data)
180 {
181         struct listmgr *listmgr;
182         struct listmgr_data *ldata;
183         struct mediadata *md;
184         struct _priv *priv;
185         Evas_Object *base, *layout;
186
187         if (!lmgr) {
188                 _ERR("failed to get layoutmgr");
189                 return false;
190         }
191
192         priv = calloc(1, sizeof(*priv));
193         if (!priv) {
194                 _ERR("failed to allocate priv");
195                 return false;
196         }
197
198         base = layoutmgr_get_base(lmgr);
199         if (!base) {
200                 _ERR("failed to get base object");
201                 goto err;
202         }
203
204         layout = elm_layout_add(base);
205         if (!layout) {
206                 _ERR("failed to create layout");
207                 goto err;
208         }
209
210         if (!elm_layout_file_set(layout, EDJEFILE, GRP_GALLERY_LAYOUT)) {
211                 _ERR("failed to set layout file");
212                 goto err2;
213         }
214
215         ldata = _create_listmgr_data(priv);
216         if (!ldata) {
217                 _ERR("failed to create listmgr data");
218                 goto err2;
219         }
220
221         listmgr = listmgr_create(layout, (void *)ldata);
222         if (!listmgr) {
223                 _ERR("failed to create listmgr");
224                 goto err3;
225         }
226
227         md = mediadata_create(LIST_MEDIA_COND, E_SOURCE_ALL, E_SORT_DATE);
228         if (!md) {
229                 _ERR("failed to create mediadata");
230                 listmgr_destroy(listmgr);
231                 goto err3;
232         }
233
234         priv->base = base;
235         priv->layout = layout;
236         priv->lmgr = lmgr;
237         priv->listmgr = listmgr;
238         priv->ldata = ldata;
239         priv->md = md;
240
241         layoutmgr_set_layout_data(lmgr, LAYOUT_GALLERY, priv);
242
243         if (!listmgr_draw_list_area(listmgr)) {
244                 _ERR("failed to draw list area");
245                 mediadata_destroy(md);
246                 listmgr_destroy(listmgr);
247                 goto err3;
248         }
249
250         return true;
251
252 err3:
253         free(ldata);
254 err2:
255         evas_object_del(layout);
256 err:
257         free(priv);
258         return false;
259 }
260
261 static void _destroy(void *layout_data)
262 {
263         struct _priv *priv;
264
265         if (!layout_data) {
266                 _ERR("failed to get layout data");
267                 return;
268         }
269
270         priv = layout_data;
271
272         mediadata_free_list(priv->media_list);
273         mediadata_destroy(priv->md);
274
275         listmgr_destroy(priv->listmgr);
276         free(priv->ldata->gops);
277         free(priv->ldata);
278
279         evas_object_del(priv->layout);
280
281         free(priv);
282 }
283
284 static void _show(void *layout_data)
285 {
286         struct _priv *priv;
287
288         if (!layout_data) {
289                 _ERR("failed to layout data");
290                 return;
291         }
292
293         priv = layout_data;
294
295         evas_object_show(priv->layout);
296         elm_object_part_content_set(priv->base,
297                         PART_THUMBNAIL_AREA, priv->layout);
298 }
299
300 static void _hide(void *layout_data)
301 {
302         struct _priv *priv;
303
304         if (!layout_data) {
305                 _ERR("failed to get layout data");
306                 return;
307         }
308
309         priv = layout_data;
310
311         evas_object_hide(priv->layout);
312         elm_object_part_content_unset(priv->base, PART_THUMBNAIL_AREA);
313 }
314
315 static void _update(void *layout_data, int update_type, void *data)
316 {
317         struct _priv *priv;
318         int index;
319
320         if (!layout_data) {
321                 _ERR("failed to get layout data");
322                 return;
323         }
324
325         priv = layout_data;
326
327         switch (update_type) {
328         case UPDATE_CONTENT:
329                 _update_list_area(priv);
330                 break;
331         case UPDATE_FOCUS:
332                 if (!data) {
333                         _ERR("invalid argument");
334                         return;
335                 }
336
337                 index = *(int *)data;
338                 listmgr_update_focus_item(priv->listmgr, index);
339
340                 break;
341         default:
342                 break;
343         }
344 }
345
346 static layout_class _lclass = {
347         .layout_id = LAYOUT_GALLERY,
348         .create = _create,
349         .show = _show,
350         .hide = _hide,
351         .destroy = _destroy,
352         .update = _update,
353 };
354
355 layout_class *layout_gallery_get_lclass(void)
356 {
357         return &_lclass;
358 }