modify to show only thumbnail of photo
[profile/tv/apps/native/air_home.git] / src / view / view_photo.c
1 /*
2
3  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an AS IS BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <Elementary.h>
19 #include <app_debug.h>
20 #include <viewmgr.h>
21 #include <inputmgr.h>
22
23 #include "defs.h"
24 #include "view_photo.h"
25 #include "data_photo.h"
26 #include "utils.h"
27
28 #define GENGRID_ITEM_SIZE 200
29
30 struct _priv {
31         Evas_Object *win;
32         Evas_Object *base;
33         Evas_Object *grid;
34         Evas_Object *ly;
35         Evas_Object *popup;
36         Elm_Gengrid_Item_Class *grid_ic;
37         Eina_List *plist;
38         Elm_Object_Item *cur;
39
40         struct datamgr *dm;
41 };
42
43 static void _cancel_key_down(int id, void *data, Evas *e, Evas_Object *obj,
44                 Evas_Event_Key_Down *ev);
45
46 static void _done_key_down(int id, void *data, Evas *e, Evas_Object *obj,
47                 Evas_Event_Key_Down *ev);
48
49 static Evas_Object *_create(Evas_Object *win, void *data)
50 {
51         struct _priv *priv;
52         struct datamgr *dm;
53         Evas_Object *base;
54
55         if (!win) {
56                 _ERR("Invalid argument");
57                 return NULL;
58         }
59
60         priv = calloc(1, sizeof(*priv));
61         if (!priv) {
62                 _ERR("failed to calloc priv");
63                 return NULL;
64         }
65
66         dm = datamgr_init(datamgr_photo_get_dclass(), VIEW_PHOTO);
67         if (!dm) {
68                 _ERR("failed to initialize datamgr");
69                 free(priv);
70                 return NULL;
71         }
72
73         base = utils_add_layout(win, GRP_PHOTO, false, NULL);
74         if (!base) {
75                 _ERR("failed to create base");
76                 datamgr_fini(dm);
77                 free(priv);
78                 return NULL;
79         }
80         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
81                         EVAS_HINT_EXPAND);
82         elm_win_resize_object_add(win, base);
83
84         priv->win = win;
85         priv->base = base;
86         priv->dm = dm;
87
88         viewmgr_set_view_data(VIEW_PHOTO, priv);
89
90         return base;
91 }
92
93 static void _ly_key_down(int id, void *data, Evas *e, Evas_Object *obj,
94                 Evas_Event_Key_Down *ev)
95 {
96         if (!strcmp(ev->keyname, KEY_BACK)) {
97                 viewmgr_pop_view();
98         }
99 }
100
101 static input_handler ly_handler = {
102         .key_down = _ly_key_down
103 };
104
105 static void _load_no_content(struct _priv *priv)
106 {
107         Evas_Object *ly;
108
109         ly = utils_add_layout(priv->base, GRP_PHOTO_NO_CONTENT, true,
110                         PART_PHOTO_LIST);
111         if (!ly) {
112                 _ERR("failed to create layout");
113                 return;
114         }
115         evas_object_show(ly);
116         inputmgr_add_callback(ly, 0, &ly_handler, NULL);
117
118         priv->ly = ly;
119 }
120 static void _grid_key_down(int id, void *data, Evas *e, Evas_Object *obj,
121                 Evas_Event_Key_Down *ev)
122 {
123         if (!strcmp(ev->keyname, KEY_BACK)) {
124                 viewmgr_pop_view();
125         }
126 }
127
128 static input_handler grid_handler = {
129         .key_down = _grid_key_down
130 };
131
132 static Evas_Object *_add_photo_grid(struct _priv *priv)
133 {
134         Evas_Object *grid;
135
136         grid = elm_gengrid_add(priv->base);
137         if (!grid) {
138                 _ERR("failed to add gend grid");
139                 return NULL;
140         }
141         evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND,
142                         EVAS_HINT_EXPAND);
143         elm_object_part_content_set(priv->base, PART_PHOTO_LIST, grid);
144         elm_gengrid_select_mode_set(grid, ELM_OBJECT_SELECT_MODE_ALWAYS);
145         elm_gengrid_multi_select_set(grid, EINA_FALSE);
146         elm_gengrid_item_size_set(grid,
147                         GENGRID_ITEM_SIZE * elm_config_scale_get(),
148                         GENGRID_ITEM_SIZE * elm_config_scale_get());
149         elm_gengrid_horizontal_set(grid, EINA_TRUE);
150         elm_scroller_policy_set(grid, ELM_SCROLLER_POLICY_OFF,
151                         ELM_SCROLLER_POLICY_OFF);
152         elm_gengrid_align_set(grid, 0.0, 0.5);
153         evas_object_show(grid);
154
155         inputmgr_add_callback(grid, 0, &grid_handler, priv);
156
157         return grid;
158 }
159
160 static Evas_Object *_get_grid_content(void *data, Evas_Object *obj,
161                 const char *part)
162 {
163         Evas_Object *img = NULL;
164
165         if (!strcmp(part, PART_SWALLOW_ICON)) {
166                 img = utils_add_icon(obj, data, NULL);
167                 if (!img) {
168                         _ERR("failed to add image");
169                         return NULL;
170                 }
171                 elm_image_fill_outside_set(img, EINA_TRUE);
172         }
173
174         return img;
175 }
176
177 static void _delete_popup(struct _priv *priv, input_handler *handler,
178                 Evas_Object *obj)
179 {
180         inputmgr_remove_callback(obj, handler);
181         evas_object_del(priv->popup);
182         priv->popup = NULL;
183 }
184
185 static input_handler cancel_handler = {
186         .key_down = _cancel_key_down
187 };
188
189 static void _cancel_key_down(int id, void *data, Evas *e, Evas_Object *obj,
190                 Evas_Event_Key_Down *ev)
191 {
192         struct _priv *priv = data;
193
194         if (!strcmp(ev->keyname, KEY_ENTER) ||
195                         !strcmp(ev->keyname, KEY_ENTER_REMOTE) ||
196                         !strcmp(ev->keyname, KEY_BACK) ||
197                         !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
198                 _delete_popup(priv, &cancel_handler, obj);
199                 elm_object_focus_allow_set(priv->grid, EINA_TRUE);
200                 elm_object_focus_set(priv->grid, EINA_TRUE);
201         }
202 }
203
204 static input_handler done_handler = {
205         .key_down = _done_key_down
206 };
207
208 static void _done_key_down(int id, void *data, Evas *e, Evas_Object *obj,
209                 Evas_Event_Key_Down *ev)
210 {
211         struct _priv *priv = data;
212
213         if (!strcmp(ev->keyname, KEY_ENTER) ||
214                         !strcmp(ev->keyname, KEY_ENTER_REMOTE)) {
215                 _delete_popup(priv, &done_handler, obj);
216                 elm_object_focus_allow_set(priv->grid, EINA_TRUE);
217                 elm_object_focus_set(priv->grid, EINA_TRUE);
218         } else if (!strcmp(ev->keyname, KEY_BACK) ||
219                         !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
220                 _delete_popup(priv, &done_handler, obj);
221                 elm_object_focus_allow_set(priv->grid, EINA_TRUE);
222                 elm_object_focus_set(priv->grid, EINA_TRUE);
223         }
224 }
225
226 static void _add_viewer_popup(struct _priv *priv, char *file)
227 {
228         Evas_Object *popup, *ly, *cancel_btn, *done_btn, *img;
229
230         popup = utils_add_popup(priv->base, NULL, NULL);
231         if (!popup) {
232                 _ERR("failed to add popup");
233                 return;
234         }
235
236         ly = utils_add_layout(popup, GRP_PHOTO_VIEWER, false,
237                         PART_SWALLOW_CONTENT);
238         if (!ly) {
239                 _ERR("failed to add layout");
240                 evas_object_del(popup);
241                 return;
242         }
243
244         cancel_btn = utils_add_button(ly, MESSAGE_CANCEL,
245                         PART_PHOTO_VIEWER_CANCEL);
246         if (!cancel_btn) {
247                 _ERR("failed to add cancel button");
248                 evas_object_del(popup);
249                 return;
250         }
251         inputmgr_add_callback(cancel_btn, 0, &cancel_handler, priv);
252
253         done_btn = utils_add_button(ly, MESSAGE_DONE, PART_PHOTO_VIEWER_DONE);
254         if (!done_btn) {
255                 _ERR("failed to add done button");
256                 evas_object_del(popup);
257                 return;
258         }
259         inputmgr_add_callback(done_btn, 0, &done_handler, priv);
260
261         elm_object_focus_set(cancel_btn, EINA_TRUE);
262
263         img = utils_add_icon(ly, file, PART_PHOTO_VIEWER);
264         if (!img) {
265                 _ERR("failed to add icon");
266                 evas_object_del(popup);
267                 return;
268         }
269         elm_image_fill_outside_set(img, EINA_TRUE);
270
271         elm_object_focus_set(cancel_btn, EINA_TRUE);
272         priv->popup = popup;
273 }
274
275 static void _select_item(void *data, Evas_Object *obj, void *ei)
276 {
277         struct _priv *priv = data;
278         char *thumb;
279
280         thumb = elm_object_item_data_get(ei);
281         if (!thumb) {
282                 _ERR("failed to get data");
283                 return;
284         }
285
286         elm_object_focus_allow_set(priv->grid, EINA_FALSE);
287         _add_viewer_popup(priv, thumb);
288
289         priv->cur = ei;
290 }
291
292 static bool _add_photo_item(struct _priv *priv, Evas_Object *grid,
293                 Eina_List *dlist)
294 {
295         Elm_Gengrid_Item_Class *ic;
296         Elm_Object_Item *item;
297         Eina_List *l;
298         char *thumb;
299
300         elm_gengrid_clear(grid);
301
302         ic = elm_gengrid_item_class_new();
303         if (!ic) {
304                 _ERR("failed to add gengrid item class");
305                 return false;
306         }
307
308         ic->item_style = STYLE_GENGRID_ITEM;
309         ic->func.text_get = NULL;
310         ic->func.content_get = _get_grid_content;
311         ic->func.state_get = NULL;
312         ic->func.del = NULL;
313
314         EINA_LIST_FOREACH(dlist, l, thumb) {
315                 item = elm_gengrid_item_append(grid, ic, thumb,
316                                 _select_item, priv);
317                 if (!item)
318                         continue;
319
320                 elm_object_item_data_set(item, thumb);
321                 priv->plist = eina_list_append(priv->plist, item);
322         }
323
324         priv->cur = elm_gengrid_first_item_get(grid);
325         priv->grid_ic = ic;
326
327         return true;
328 }
329
330 static void _load_photo(struct _priv *priv)
331 {
332         Eina_List *dlist;
333         Evas_Object *grid;
334
335         dlist = datamgr_get_items(priv->dm);
336         if (!dlist) {
337                 _load_no_content(priv);
338                 return;
339         }
340
341         grid = _add_photo_grid(priv);
342         if (!grid) {
343                 _ERR("failed to add grid");
344                 return;
345         }
346
347         if (!_add_photo_item(priv, grid, dlist)) {
348                 _ERR("failed to add photo item");
349                 evas_object_del(grid);
350                 _load_no_content(priv);
351                 return;
352         }
353
354         elm_win_focus_highlight_enabled_set(priv->win, EINA_TRUE);
355         priv->grid = grid;
356 }
357
358 static void _show(void *data)
359 {
360         struct _priv *priv;
361
362         if (!data) {
363                 _ERR("Invalid argument");
364                 return;
365         }
366
367         priv = data;
368
369         evas_object_show(priv->base);
370
371         _load_photo(priv);
372
373         if (priv->ly)
374                 elm_object_focus_set(priv->ly, EINA_TRUE);
375         else
376                 elm_object_focus_set(priv->grid, EINA_TRUE);
377 }
378
379 static void _hide(void *data)
380 {
381         struct _priv *priv;
382
383         if (!data) {
384                 _ERR("Invalid argument");
385                 return;
386         }
387
388         priv = data;
389         if (priv->ly) {
390                 inputmgr_remove_callback(priv->ly, &ly_handler);
391                 evas_object_del(priv->ly);
392                 priv->ly = NULL;
393         } else {
394                 elm_gengrid_item_class_free(priv->grid_ic);
395                 inputmgr_remove_callback(priv->grid, &grid_handler);
396                 evas_object_del(priv->grid);
397                 priv->grid = NULL;
398         }
399
400         evas_object_hide(priv->base);
401         elm_win_focus_highlight_enabled_set(priv->win, EINA_FALSE);
402 }
403
404 static void _destroy(void *data)
405 {
406         struct _priv *priv;
407
408         if (!data) {
409                 _ERR("Invalid argument");
410                 return;
411         }
412
413         priv = data;
414
415         evas_object_del(priv->base);
416         free(priv);
417 }
418
419 static view_class vclass = {
420         .view_id = VIEW_PHOTO,
421         .create = _create,
422         .show = _show,
423         .hide = _hide,
424         .destroy = _destroy
425 };
426
427 view_class *view_photo_get_vclass(void)
428 {
429         return &vclass;
430 }