05dffa8328e631fc2c0615260616907b7f17e30f
[profile/tv/apps/native/air_home.git] / src / view / view_home.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.h"
25 #include "data_home.h"
26 #include "datamgr.h"
27 #include "utils.h"
28
29 struct _priv {
30         Evas_Object *win;
31         Evas_Object *base;
32         Eina_List *list;
33
34         struct datamgr *dm;
35         struct bar_item *foc;
36 };
37
38 struct bar_item {
39         Evas_Object *eo;
40
41         struct datamgr_item *di;
42         struct _priv *priv;
43 };
44
45 static bool _add_navigations(Evas_Object *base)
46 {
47         Evas_Object *ly;
48
49         if (!base) {
50                 _ERR("Invalid argument");
51                 return false;
52         }
53
54         ly = utils_add_layout(base, GRP_HOME_DOWN_ARROW, true,
55                         PART_HOME_DOWN_ARROW);
56         if (!ly) {
57                 _ERR("failed to add layout");
58                 return false;
59         }
60
61         return true;
62 }
63
64 static void _focused(int id, void *data, Evas_Object *obj,
65                 Elm_Object_Item *item)
66 {
67         struct _priv *priv;
68         struct bar_item *bi;
69
70         if (!data) {
71                 _ERR("Invalid argument");
72                 return;
73         }
74
75         bi = data;
76         priv = bi->priv;
77         priv->foc = bi;
78
79         elm_object_signal_emit(obj, SIG_FOCUS, SRC_PROG);
80 }
81
82 static void _unfocused(int id, void *data, Evas_Object *obj,
83                 Elm_Object_Item *item)
84 {
85         elm_object_signal_emit(obj, SIG_UNFOCUS, SRC_PROG);
86 }
87
88 static input_handler eo_handler = {
89         .focused = _focused,
90         .unfocused = _unfocused
91 };
92
93 static struct bar_item *_pack_bar_item(struct _priv *priv, Evas_Object *box,
94                 struct datamgr_item *di)
95 {
96         struct bar_item *bi;
97         Evas_Object *eo, *ic, *focus_ic, *lbl, *focus_lbl, *bg;
98
99         if (!priv || !box || !di) {
100                 _ERR("Invalid argument");
101                 return NULL;
102         }
103
104         bi = calloc(1, sizeof(*bi));
105         if (!bi) {
106                 _ERR("failed to calloc bar item");
107                 return NULL;
108         }
109
110         eo = utils_add_layout(box, GRP_HOME_ITEM, true, NULL);
111         if (!eo) {
112                 _ERR("failed to add layout");
113                 free(bi);
114                 return NULL;
115         }
116
117         ic = utils_add_icon(eo, di->icon, PART_BAR_ITEM_ICON);
118         if (!ic)
119                 goto err;
120
121         focus_ic = utils_add_icon(eo, di->focus_icon, PART_BAR_ITEM_ICON_FOCUS);
122         if (!focus_ic)
123                 goto err;
124
125         lbl = utils_add_label(eo, di->title, STYLE_LABEL_TITLE,
126                         PART_BAR_ITEM_TITLE);
127         if (!lbl)
128                 goto err;
129
130         focus_lbl = utils_add_label(eo, di->title, STYLE_LABEL_TITLE_FOCUS,
131                         PART_BAR_ITEM_TITLE_FOCUS);
132         if (!focus_lbl)
133                 goto err;
134
135         bg = utils_add_bg(eo, COLOR_DEFAULT_R, COLOR_DEFAULT_G, COLOR_DEFAULT_B,
136                         COLOR_DEFAULT_A, PART_BAR_ITEM_BG);
137         if (!bg)
138                 goto err;
139
140         inputmgr_add_callback(eo, 0, &eo_handler, bi);
141         elm_box_pack_end(box, eo);
142         evas_object_show(eo);
143
144         bi->priv = priv;
145         bi->eo = eo;
146         bi->di = di;
147
148         return bi;
149 err:
150         _ERR("failed to add home item");
151         evas_object_del(eo);
152         free(bi);
153
154         return NULL;
155 }
156
157 static bool _add_home_menu(struct _priv *priv, Evas_Object *base)
158 {
159         Eina_List *list, *l;
160         Evas_Object *scr, *box;
161         struct bar_item *bi;
162         struct datamgr_item *di;
163
164         if (!priv || !base) {
165                 _ERR("Invalid argument");
166                 return false;
167         }
168
169         scr = utils_add_scroller(base);
170         if (!scr) {
171                 _ERR("failed to add scroller");
172                 return false;
173         }
174
175         box = utils_add_box(scr, true);
176         if (!box) {
177                 _ERR("failed to add box");
178                 evas_object_del(scr);
179                 return false;
180         }
181         elm_object_content_set(scr, box);
182         elm_object_part_content_set(base, PART_HOME_MENU_BAR, scr);
183
184         list = datamgr_get_items(priv->dm);
185         if (!list) {
186                 _ERR("failed to load list");
187                 evas_object_del(scr);
188                 return false;
189         }
190
191         EINA_LIST_FOREACH(list, l, di) {
192                 bi = _pack_bar_item(priv, box, di);
193                 if (!bi)
194                         continue;
195
196                 priv->list = eina_list_append(priv->list, bi);
197         }
198
199         return true;
200 }
201
202 static bool _add_home(struct _priv *priv, Evas_Object *base)
203 {
204         if (!priv || !base) {
205                 _ERR("Invalid argument");
206                 return false;
207         }
208
209         if (!_add_navigations(base)) {
210                 _ERR("failed to add navigations");
211                 return false;
212         }
213
214         if (!_add_home_menu(priv, base)) {
215                 _ERR("failed to add menu");
216                 return false;
217         }
218
219         return true;
220 }
221
222 static void _key_down(int id, void *data, Evas *e, Evas_Object *obj,
223                 Evas_Event_Key_Down *ev)
224 {
225         struct _priv *priv;
226
227         if (!data) {
228                 _ERR("Invalid argument");
229                 return;
230         }
231
232         priv = data;
233
234         if (!strcmp(ev->keyname, KEY_DOWN)) {
235                 viewmgr_push_view(VIEW_RECENT);
236         } else if (!strcmp(ev->keyname, KEY_ENTER) ||
237                         !strcmp(ev->keyname, KEY_ENTER_REMOTE)) {
238                 datamgr_select_item(priv->dm, priv->foc->di);
239         } else if (!strcmp(ev->keyname, KEY_BACK) ||
240                         !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
241                 /* It should be implemented later */
242         }
243 }
244
245 static input_handler base_handler = {
246         .key_down = _key_down
247 };
248
249 static Evas_Object *_create(Evas_Object *win, void *data)
250 {
251         struct _priv *priv;
252         struct datamgr *dm;
253         Evas_Object *base;
254
255         if (!win) {
256                 _ERR("Invalid argument");
257                 return NULL;
258         }
259
260         priv = calloc(1, sizeof(*priv));
261         if (!priv) {
262                 _ERR("failed to calloc priv");
263                 return NULL;
264         }
265
266         dm = datamgr_init(datamgr_home_get_dclass(), VIEW_HOME);
267         if (!dm) {
268                 _ERR("failed to initialize datamgr");
269                 free(priv);
270                 return NULL;
271         }
272
273         base = utils_add_layout(win, GRP_HOME, false, NULL);
274         if (!base) {
275                 _ERR("failed to create base");
276                 datamgr_fini(dm);
277                 free(priv);
278                 return NULL;
279         }
280         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
281                         EVAS_HINT_EXPAND);
282         elm_win_resize_object_add(win, base);
283
284         priv->win = win;
285         priv->base = base;
286         priv->dm = dm;
287
288         if (!_add_home(priv, base)) {
289                 _ERR("failed to load home");
290                 datamgr_fini(dm);
291                 evas_object_del(base);
292                 free(priv);
293                 return NULL;
294         }
295
296         viewmgr_set_view_data(VIEW_HOME, priv);
297         inputmgr_add_callback(base, 0, &base_handler, priv);
298
299         return base;
300 }
301
302 static void _show(void *data)
303 {
304         struct _priv *priv;
305
306         if (!data) {
307                 _ERR("Invalid argument");
308                 return;
309         }
310
311         priv = data;
312
313         evas_object_show(priv->base);
314         elm_object_signal_emit(priv->base, SIG_SHOW_NAVIGATION, SRC_PROG);
315
316         if (!priv->foc)
317                 priv->foc = eina_list_data_get(priv->list);
318         elm_object_focus_set(priv->foc->eo, EINA_TRUE);
319 }
320
321 static void _hide(void *data)
322 {
323         struct _priv *priv;
324
325         if (!data) {
326                 _ERR("Invalid argument");
327                 return;
328         }
329
330         priv = data;
331
332         elm_object_signal_emit(priv->base, SIG_HIDE_NAVIGATION, SRC_PROG);
333         evas_object_hide(priv->base);
334 }
335
336 static void _destroy(void *data)
337 {
338         struct _priv *priv;
339         struct bar_item *bi;
340
341         if (!data) {
342                 _ERR("Invalid argument");
343                 return;
344         }
345
346         priv = data;
347
348         EINA_LIST_FREE(priv->list, bi) {
349                 inputmgr_remove_callback(bi->eo, &eo_handler);
350                 evas_object_del(bi->eo);
351                 free(bi);
352         }
353
354         datamgr_fini(priv->dm);
355         inputmgr_remove_callback(priv->base, &base_handler);
356         evas_object_del(priv->base);
357
358         priv->list = NULL;
359         free(priv);
360 }
361
362 static view_class vclass = {
363         .view_id = VIEW_HOME,
364         .create = _create,
365         .show = _show,
366         .hide = _hide,
367         .destroy = _destroy
368 };
369
370 view_class *view_home_get_vclass(void)
371 {
372         return &vclass;
373 }
374