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