base: manage current focused menu button
[profile/tv/apps/native/air_mediahub.git] / src / view / base.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 <app_debug.h>
19 #include <inputmgr.h>
20 #include <viewmgr.h>
21 #include <layoutmgr.h>
22
23 #include "define.h"
24 #include "layout.h"
25
26 #define TITLE_TEXT "Media Hub"
27
28 #define MENU_BTN_SIZE 3
29
30 struct _priv {
31         Evas_Object *win;
32         Evas_Object *base;
33         Evas_Object *btn[MENU_BTN_SIZE];
34         Evas_Object *focused_btn;
35
36         layoutmgr *lmgr;
37
38         int current_layout;
39 };
40
41 struct _menu_item {
42         const char *name;
43         const char *layout_id;
44 };
45
46 static struct _menu_item g_menu_item[MENU_BTN_SIZE] = {
47         {
48                 "Movie",
49                 LAYOUT_MOVIE
50         },
51         {
52                 "Gallery",
53                 LAYOUT_GALLERY
54         },
55         {
56                 "Music",
57                 LAYOUT_MUSIC
58         }
59 };
60
61 static void _mouse_move_cb(int id, void *data, Evas *e,
62                         Evas_Object *obj, Evas_Event_Mouse_Move *ev)
63 {
64         if (!elm_object_focus_get(obj))
65                 elm_object_focus_set(obj, EINA_TRUE);
66 }
67
68 static void _focused_cb(int id, void *data, Evas_Object *obj,
69                         Elm_Object_Item *it)
70 {
71         struct _priv *priv;
72         int i;
73
74         if (!data) {
75                 _ERR("failed to get data");
76                 return;
77         }
78
79         priv = data;
80
81         if (priv->focused_btn == obj)
82                 return;
83
84         for (i = 0; i < MENU_BTN_SIZE; i++) {
85                 if (priv->btn[i] == obj)
86                         break;
87         }
88
89         if (i == MENU_BTN_SIZE)
90                 return;
91
92         layoutmgr_hide_layout(priv->lmgr,
93                         g_menu_item[priv->current_layout].layout_id);
94         layoutmgr_show_layout(priv->lmgr, g_menu_item[i].layout_id);
95         layoutmgr_update_layout(priv->lmgr, g_menu_item[i].layout_id, 0, NULL);
96
97         priv->focused_btn = obj;
98         priv->current_layout = i;
99 }
100
101 static input_handler handler = {
102         .mouse_move = _mouse_move_cb,
103         .focused = _focused_cb
104 };
105
106 static bool _draw_title(struct _priv *priv)
107 {
108         if (!priv)
109                 return false;
110
111         elm_object_part_text_set(priv->base, PART_TITLE, TITLE_TEXT);
112
113         return true;
114 }
115
116 static bool _draw_menu_btn(struct _priv *priv)
117 {
118         Evas_Object *box, *btn;
119         int i;
120
121         if (!priv)
122                 return false;
123
124         box = elm_box_add(priv->base);
125         if (!box) {
126                 _ERR("failed to create box object");
127                 return false;
128         }
129
130         elm_box_horizontal_set(box, EINA_TRUE);
131
132         evas_object_size_hint_weight_set(box,
133                         EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
134         evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
135
136         for (i = 0; i < MENU_BTN_SIZE; i++) {
137                 btn = elm_button_add(box);
138                 if (!btn) {
139                         _ERR("failed to create button object");
140                         return false;
141                 }
142
143                 elm_object_style_set(btn, STYLE_MENU_BTN);
144                 elm_object_text_set(btn, g_menu_item[i].name);
145
146                 elm_box_pack_end(box, btn);
147
148                 evas_object_show(btn);
149
150                 inputmgr_add_callback(btn, 0, &handler, priv);
151
152                 priv->btn[i] = btn;
153         }
154
155         evas_object_show(box);
156
157         elm_object_part_content_set(priv->base, PART_MENU_AREA, box);
158
159         elm_object_focus_set(priv->btn[0], EINA_TRUE);
160
161         elm_object_focus_next_object_set(priv->btn[MENU_BTN_SIZE - 1],
162                                 priv->btn[0], ELM_FOCUS_RIGHT);
163         elm_object_focus_next_object_set(priv->btn[0],
164                                 priv->btn[MENU_BTN_SIZE - 1], ELM_FOCUS_LEFT);
165
166         return true;
167 }
168
169 static bool _draw_items(struct _priv *priv)
170 {
171         if (!priv)
172                 return false;
173
174         if (!_draw_title(priv))
175                 return false;
176
177         if (!_draw_menu_btn(priv))
178                 return false;
179
180         return true;
181 }
182
183 static Evas_Object *_create(Evas_Object *win, void *data)
184 {
185         struct _priv *priv;
186         Evas_Object *base;
187         layoutmgr *lmgr;
188
189         if (!win) {
190                 _ERR("failed to get win object");
191                 return NULL;
192         }
193
194         priv = calloc(1, sizeof(*priv));
195         if (!priv) {
196                 _ERR("failed to allocate priv");
197                 return NULL;
198         }
199
200         base = elm_layout_add(win);
201         if (!base) {
202                 _ERR("failed to create base object");
203                 free(priv);
204                 return NULL;
205         }
206
207         elm_layout_file_set(base, EDJEFILE, GRP_BASE_VIEW);
208
209         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
210         elm_win_resize_object_add(win, base);
211
212         lmgr = layoutmgr_create(base);
213         layoutmgr_add_layout(lmgr, layout_movie_get_lclass(), NULL);
214         layoutmgr_add_layout(lmgr, layout_gallery_get_lclass(), NULL);
215         layoutmgr_add_layout(lmgr, layout_music_get_lclass(), NULL);
216
217         priv->win = win;
218         priv->base = base;
219         priv->lmgr = lmgr;
220
221         if (!_draw_items(priv)) {
222                 _ERR("failed to draw items");
223                 free(priv);
224                 return NULL;
225         }
226
227         viewmgr_set_view_data(VIEW_BASE, priv);
228
229         return base;
230 }
231
232 static void _show(void *view_data)
233 {
234         struct _priv *priv;
235
236         if (!view_data) {
237                 _ERR("failed to get view data");
238                 return;
239         }
240
241         priv = view_data;
242
243         evas_object_show(priv->base);
244 }
245
246 static void _hide(void *view_data)
247 {
248         struct _priv *priv;
249
250         if (!view_data) {
251                 _ERR("failed to get view data");
252                 return;
253         }
254
255         priv = view_data;
256
257         evas_object_hide(priv->base);
258 }
259
260 static void _destroy(void *view_data)
261 {
262         struct _priv *priv;
263         int i;
264
265         if (!view_data) {
266                 _ERR("failed to get view data");
267                 return;
268         }
269
270         priv = view_data;
271
272         for (i = 0; i < MENU_BTN_SIZE; i++)
273                 inputmgr_remove_callback(priv->btn[i], &handler);
274
275         layoutmgr_remove_layout(priv->lmgr, LAYOUT_MOVIE);
276         layoutmgr_remove_layout(priv->lmgr, LAYOUT_GALLERY);
277         layoutmgr_remove_layout(priv->lmgr, LAYOUT_MUSIC);
278
279         layoutmgr_destroy(priv->lmgr);
280
281         evas_object_del(priv->base);
282
283         free(priv);
284 }
285
286 static view_class _vclass = {
287         .view_id = VIEW_BASE,
288         .create = _create,
289         .show = _show,
290         .hide = _hide,
291         .destroy = _destroy,
292 };
293
294 view_class *view_base_get_vclass(void)
295 {
296         return &_vclass;
297 }