a73aefe74279a80eb2c8b27e5c820492475d28a4
[profile/tv/apps/native/source.git] / src / view / nearby_layout.cpp
1 /*
2  * Copyright (c) 2014 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.h>
19 #include "aul.h"
20 #include "def.h"
21 #include "dbg.h"
22
23 #include "AppCommon.h"
24 #include "BaseView.h"
25 #include "ViewMgr.h"
26 #include "BaseLayout.h"
27 #include "LayoutMgr.h"
28 #include "InputHandler.h"
29 #include "source_mgr.h"
30 #include "menu_view.h"
31 #include "util.h"
32 #include "allsource_view.h"
33 #include "nearby_layout.h"
34
35 #define PRIV "priv"
36 #define NEARBY_DATA "nearby_data"
37
38 #define SET_UP_NETWORK "Set up network"
39 #define NET_WORK_SET "Network Setting"
40
41 #define NO_SRC_TEXT_LINE1 "No nearby source"
42 #define NO_SRC_TEXT_LINE2 "Add any nearby sources, set up network configuration"
43 #define NO_SRC_TEXT_LINE3 "Wi-Fi ON  |  Wi-Fi Direct ON"
44
45 #define PADDING_13 13
46 #define PADDING_30 30
47 #define SETTING_APP "org.tizen.settings-tv-ref"
48 #define SETTING_ITEM "settings-item"
49 #define SETTING_NETWORK "network-settings"
50
51 enum EObjectType {
52         NEARBY_GRID = 0,
53         NEARBY_BTN_TOP,
54         NEARBY_BTN_LAYOUT
55 };
56
57 struct SSigCallbackPair {
58         void (*cb)(void *cookie, int sig);
59         void *cookie;
60 };
61
62 struct SNearbyLayout {
63         Evas_Object *base;
64         Evas_Object *grid;
65         Evas_Object *utility_pb;
66         Evas_Object *utility_btn;
67         Elm_Object_Item *focus_it;
68         Elm_Object_Item *del_it;
69         CSourceMgr *srcmgr;
70         CViewMgr *vmgr;
71         int list_count;
72
73         SSigCallbackPair *SigCb;
74
75         SNearbyLayout() {
76                 memset(this, 0, sizeof(SNearbyLayout));
77         }
78 };
79
80 void CNearbyLayout::m_LaunchSettingApp(void)
81 {
82         bundle *b;
83         int err;
84
85         b = bundle_create();
86         if (!b) {
87                 _ERR("create bundle failed.");
88                 return;
89         }
90
91         err = bundle_add(b, SETTING_ITEM, SETTING_NETWORK);
92         if (err) {
93                 _ERR("add bundle failed.");
94                 bundle_free(b);
95                 return;
96         }
97
98         err = aul_launch_app(SETTING_APP, b);
99         if (err) {
100                 _ERR("launch settings failed.");
101                 bundle_free(b);
102                 return;
103         }
104
105         bundle_free(b);
106 }
107
108 void CNearbyLayout::m_AddSetNetworkButton(void)
109 {
110         Evas_Object *btn;
111
112         btn = util_add_btn(Layout(), BTN_STYLE_SET_UP_NETWORK);
113         if (!btn) {
114                 _ERR("Add network button failed");
115                 return;
116         }
117
118         elm_object_text_set(btn, _(SET_UP_NETWORK));
119         elm_object_part_content_set(Layout(), PART_BUTTON, btn);
120
121         Connect(btn, NEARBY_BTN_LAYOUT, TYPE_KEY_DOWN | TYPE_MOUSE_MOVE | TYPE_FOCUSED);
122 }
123
124 void CNearbyLayout::m_AddNoSrcUtility(void)
125 {
126         Evas_Object *pb, *btn;
127
128         if (m->utility_btn)
129                 return;
130
131         pb = elm_progressbar_add(m->base);
132         if (!pb)
133                 return;
134
135         elm_object_style_set(pb, PB_STYLE_SRC_LOAD);
136         elm_object_part_content_set(m->base, PART_UTILITY_LOADING, pb);
137         elm_progressbar_pulse(m->utility_pb, EINA_TRUE);
138         evas_object_show(m->utility_pb);
139
140         /*TODO:to add utility button*/
141         btn = util_add_btn(m->base, BTN_STYLE_NETWORK_SET);
142         if (!btn) {
143                 evas_object_del(pb);
144                 return;
145         }
146         elm_object_text_set(btn, _(NET_WORK_SET));
147         elm_object_part_content_set(m->base, PART_UTILITY_BUTTON, btn);
148
149         Connect(btn, NEARBY_BTN_TOP, TYPE_KEY_DOWN | TYPE_MOUSE_MOVE | TYPE_FOCUSED);
150
151         m->utility_pb = pb;
152         m->utility_btn = btn;
153 }
154
155 void CNearbyLayout::m_DelNoSrcUtility(void)
156 {
157         if (m->utility_btn) {
158                 evas_object_del(m->utility_btn);
159                 m->utility_btn = NULL;
160         }
161
162         if (m->utility_pb) {
163                 evas_object_del(m->utility_pb);
164                 m->utility_pb = NULL;
165         }
166 }
167
168 void CNearbyLayout::m_DrawNoSrcUtility(void)
169 {
170         if (m->list_count > 0)
171                 m_DelNoSrcUtility();
172         else
173                 m_AddNoSrcUtility();
174 }
175
176 void CNearbyLayout::m_DrawNoContentArea(void)
177 {
178         elm_object_part_text_set(Layout(), PART_NO_SRC_TEXT_LINE1,
179                                 _(NO_SRC_TEXT_LINE1));
180         elm_object_part_text_set(Layout(), PART_NO_SRC_TEXT_LINE2,
181                                 _(NO_SRC_TEXT_LINE2));
182         elm_object_part_text_set(Layout(), PART_NO_SRC_TEXT_LINE3,
183                                 _(NO_SRC_TEXT_LINE3));
184
185         elm_object_part_content_unset(Layout(), PART_CONTENT_CONTENT);
186         evas_object_hide(m->grid);
187
188         m_AddSetNetworkButton();
189
190         m->SigCb->cb(m->SigCb->cookie, E_RETURN);
191 }
192
193 void CNearbyLayout::m_DrawContentArea(void)
194 {
195         elm_object_part_text_set(Layout(), PART_NO_SRC_TEXT_LINE1, "");
196         elm_object_part_text_set(Layout(), PART_NO_SRC_TEXT_LINE2, "");
197         elm_object_part_text_set(Layout(), PART_NO_SRC_TEXT_LINE3, "");
198         elm_object_part_content_unset(Layout(), PART_BUTTON);
199
200         elm_object_part_content_set(Layout(), PART_CONTENT_CONTENT, m->grid);
201         evas_object_show(m->grid);
202 }
203
204 Evas_Object *CNearbyLayout::m_DrawGengrid(Evas_Object *layout)
205 {
206         Evas_Object *grid;
207
208         grid = util_add_grid(layout, ITEM_W, ITEM_H);
209         if (!grid)
210                 return NULL;
211
212         Connect(grid, NEARBY_GRID, TYPE_KEY_DOWN | TYPE_MOUSE_MOVE | TYPE_FOCUSED);
213
214         return grid;
215 }
216
217 bool CNearbyLayout::SetSendSigCallback(void (*cb)(void *cookie, int sig), void *cookie)
218 {
219         ASSERT(m);
220
221         SSigCallbackPair *rcb = new SSigCallbackPair;
222         if (!rcb)
223                 return false;
224
225         rcb->cb = cb;
226         rcb->cookie = cookie;
227
228         m->SigCb = rcb;
229
230         return true;
231 }
232
233 bool CNearbyLayout::Create(CLayoutMgr *lmgr, void *data)
234 {
235         ASSERT(!m);
236
237         Evas_Object *layout;
238         CViewMgr *vmgr;
239         CSourceMgr *srcmgr;
240
241         if (!lmgr)
242                 return false;
243
244         m = new SNearbyLayout;
245         if (!m)
246                 return false;
247
248         m->base = lmgr->Base();
249         if (!m->base) {
250                 delete m;
251                 m = NULL;
252                 return false;
253         }
254
255         layout = util_add_layout(m->base, GRP_NEARBY_CONTENT);
256         if (!layout) {
257                 _ERR("Add layout failed");
258                 delete m;
259                 m = NULL;
260                 return false;
261         }
262
263         m->grid = m_DrawGengrid(layout);
264         if (!m->grid) {
265                 _ERR("Add gengrid failed");
266                 delete m;
267                 m = NULL;
268                 evas_object_del(layout);
269                 return false;
270         }
271
272         vmgr = CViewMgr::GetInstance();
273         srcmgr = CSourceMgr::GetInstance();
274
275         m->srcmgr = srcmgr;
276         m->vmgr = vmgr;
277
278         evas_object_data_set(m->base, NEARBY_DATA, m);
279
280         elm_object_part_content_set(layout, PART_CONTENT_CONTENT, m->grid);
281
282         CBaseLayout::Create(layout);
283
284         return true;
285 }
286
287 void CNearbyLayout::t_OnShow(void)
288 {
289         ASSERT(m);
290
291         CBaseLayout::t_OnShow();
292
293         elm_object_part_content_set(m->base, PART_CONTENT, Layout());
294
295         m_DrawNoSrcUtility();
296 }
297
298 void CNearbyLayout::t_OnHide(void)
299 {
300         ASSERT(m);
301
302         CBaseLayout::t_OnHide();
303
304         elm_object_part_content_unset(m->base, PART_CONTENT);
305
306         m_DelNoSrcUtility();
307 }
308
309 void CNearbyLayout::Destroy(void)
310 {
311         ASSERT(m);
312
313         evas_object_del(Layout());
314
315         CBaseLayout::Destroy();
316
317         delete m;
318         m = NULL;
319 }
320
321 Eina_Bool CNearbyLayout::sm_CbTimerDelItem(void *data)
322 {
323         CNearbyLayout *root = (CNearbyLayout *)data;
324         if (!root)
325                 return EINA_FALSE;
326
327         root->m_TimerDelItem();
328
329         return EINA_FALSE;
330 }
331
332 void CNearbyLayout::m_TimerDelItem(void)
333 {
334         Elm_Object_Item *prev;
335         Elm_Object_Item *next;
336
337         if (!m->del_it)
338                 return;
339
340         prev = elm_gengrid_item_prev_get(m->del_it);
341         next = elm_gengrid_item_prev_get(m->del_it);
342
343         elm_object_item_data_set(m->del_it, NULL);
344         elm_object_item_del(m->del_it);
345
346         if (!prev && !next)
347                 m_DrawNoContentArea();
348         else if (m->del_it == m->focus_it) {
349                 if (prev)
350                         m->focus_it = prev;
351                 else
352                         m->focus_it = next;
353
354                 elm_object_item_focus_set(m->focus_it, EINA_TRUE);
355         }
356
357         m->del_it = NULL;
358 }
359
360 void CNearbyLayout::Update(void *data, enum update_ui type)
361 {
362         ASSERT(m);
363
364         Eina_List *list, *l;
365         Ecore_Timer *timer;
366         CSourceMgr *srcmgr;
367         CSourceInfo *si;
368         CSourceInfo *si_data;
369         void *obj;
370
371         srcmgr = m->srcmgr;
372
373         /*TODO:there is only nearby connected source list*/
374         list = srcmgr->NearbyConnList();
375         m->list_count = eina_list_count(list);
376
377         if (type == SRC_PLUG_ADD_ONE) {
378                 si_data = (CSourceInfo *)data;
379                 util_add_item(m->grid, si_data);
380
381                 if (m->list_count >= 1)
382                         m_DrawContentArea();
383         } else if (type == SRC_PLUG_DEL_ONE) {
384                 si_data = (CSourceInfo *)data;
385                 m->del_it = (Elm_Object_Item*)si_data->Data();
386                 si_data->SetData(NULL);
387
388                 timer = ecore_timer_add(DEL_IT_TIME, sm_CbTimerDelItem, m);
389                 elm_object_item_data_set(m->del_it, timer);
390                 util_dim_item(m->del_it);
391         } else if (type == SRC_UPDATE_ALL) {
392                 if (m->list_count == 0) {
393                         m_DrawNoContentArea();
394                         return;
395                 } else
396                         m_DrawContentArea();
397
398                 elm_gengrid_clear(m->grid);
399
400                 EINA_LIST_FOREACH(list, l, obj) {
401                         si = (CSourceInfo *)obj;
402                         util_add_item(m->grid, si);
403                 }
404         }
405 }
406
407 void CNearbyLayout::OnKeyDown(int id, Evas *e, Evas_Object *obj, Evas_Event_Key_Down *ev)
408 {
409         switch (id) {
410         case NEARBY_GRID:
411                 CSourceInfo *si;
412
413                 si = m->srcmgr->SourceInfoByData(m->focus_it);
414                 if (!si)
415                         return;
416
417                 if (!strcmp(ev->keyname, KEY_MENU)
418                         || !strcmp(ev->keyname, KEY_MENU_REMOTE))
419                         m->vmgr->PushView(MENU_VIEW, si);
420
421                 break;
422         case NEARBY_BTN_TOP:
423         case NEARBY_BTN_LAYOUT:
424                 if (!ev->keyname)
425                         return;
426
427                 if (!strcmp(ev->keyname, KEY_ENTER)
428                         || !strcmp(ev->keyname, KEY_ENTER_REMOTE))
429                         m_LaunchSettingApp();
430
431                 break;
432         default:
433                 break;
434         }
435 }
436
437 void CNearbyLayout::OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev)
438 {
439         switch (id) {
440         case NEARBY_GRID:
441                 Elm_Object_Item *it;
442
443                 it = elm_gengrid_at_xy_item_get(obj, ev->cur.canvas.x,
444                                 ev->cur.canvas.y, NULL, NULL);
445                 if (!it)
446                         return;
447
448                 if (elm_object_item_focus_get(it))
449                         return;
450
451                 elm_object_item_focus_set(it, EINA_TRUE);
452
453                 m->SigCb->cb(m->SigCb->cookie, E_HIGHLIGHT);
454
455                 break;
456         case NEARBY_BTN_TOP:
457         case NEARBY_BTN_LAYOUT:
458                 if (elm_object_focus_get(obj))
459                         return;
460
461                 elm_object_focus_set(obj, EINA_TRUE);
462
463                 break;
464         default:
465                 break;
466         }
467 }
468
469 void CNearbyLayout::OnFocused(int id, Evas_Object *obj, Elm_Object_Item *item)
470 {
471         switch (id) {
472         case NEARBY_GRID:
473                 m->focus_it = (Elm_Object_Item*)item;
474
475                 m->SigCb->cb(m->SigCb->cookie, E_HIGHLIGHT);
476
477                 break;
478         case NEARBY_BTN_TOP:
479         case NEARBY_BTN_LAYOUT:
480                 m->SigCb->cb(m->SigCb->cookie, E_HIGHLIGHT);
481                 break;
482         default:
483                 break;
484         }
485 }