tizen 2.4 release
[apps/home/attach-panel.git] / src / ui_manager.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 <bundle.h>
19 #include <efl_extension.h>
20 #include <ui-gadget.h>
21 #include <ui-gadget-module.h>
22
23 #include "attach_panel.h"
24 #include "attach_panel_internal.h"
25 #include "conf.h"
26 #include "content_list.h"
27 #include "gesture.h"
28 #include "list.h"
29 #include "log.h"
30 #include "page.h"
31 #include "scroller.h"
32 #include "toolbar.h"
33 #include "ug.h"
34 #include "grid.h"
35
36
37
38 static const char *const FILE_LAYOUT_EDJ = EDJEDIR"/layout.edj";
39 static const char *const GROUP_LAYOUT = "layout";
40
41
42
43 Evas_Object *_ui_manager_create_content(Evas_Object *page, content_s *content_info, attach_panel_h attach_panel)
44 {
45         Evas_Object *content = NULL;
46         Elm_Object_Item *item = NULL;
47
48         retv_if(!page, NULL);
49         retv_if(!content_info, NULL);
50         retv_if(!attach_panel, NULL);
51
52         switch (content_info->innate_content_info->content_category) {
53         case ATTACH_PANEL_CONTENT_CATEGORY_IMAGE:
54         case ATTACH_PANEL_CONTENT_CATEGORY_CAMERA:
55         case ATTACH_PANEL_CONTENT_CATEGORY_VOICE:
56                 content = _ug_create(content_info->innate_content_info->appid
57                                                 , content_info->innate_content_info->operation
58                                                 , content_info->innate_content_info->selection_mode
59                                                 , content_info->innate_content_info->mime
60                                                 , content_info->extra_data
61                                                 , content_info);
62                 evas_object_show(content);
63                 content_info->grid_item = NULL;
64                 break;
65         default:
66                 /* This function can return NULL, if there is already a grid content */
67                 if (attach_panel->grid) {
68                         content = attach_panel->grid;
69                 } else {
70                         content = _grid_create(page, attach_panel);
71                         attach_panel->grid = content;
72                 }
73
74                 item = _grid_append_item(attach_panel->grid, content_info);
75                 break_if(!item);
76
77                 break;
78         }
79
80         evas_object_size_hint_weight_set(content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
81         elm_object_part_content_set(page, "content", content);
82
83         evas_object_data_set(content, DATA_KEY_PAGE, page);
84
85         return content;
86 }
87
88
89
90 void _ui_manager_destroy_content(content_s *content_info, attach_panel_h attach_panel)
91 {
92         ret_if(!content_info->content);
93         ret_if(!attach_panel);
94
95         evas_object_data_del(content_info->content, DATA_KEY_PAGE);
96
97         switch (content_info->innate_content_info->content_category) {
98         case ATTACH_PANEL_CONTENT_CATEGORY_IMAGE:
99         case ATTACH_PANEL_CONTENT_CATEGORY_CAMERA:
100         case ATTACH_PANEL_CONTENT_CATEGORY_VOICE:
101                 _ug_destroy(content_info->content);
102                 break;
103         default:
104                 _grid_remove_item(attach_panel->grid, content_info);
105
106                 if (!_grid_count_item(attach_panel->grid)) {
107                         _grid_destroy(attach_panel->grid);
108                         attach_panel->grid = NULL;
109                 }
110
111                 break;
112         }
113 }
114
115
116
117 int _ui_manager_append_content_category(Evas_Object *ui_manager, innate_content_s *innate_content_info, bundle *extra_data)
118 {
119         attach_panel_h attach_panel = NULL;
120         content_s *content_info = NULL;
121         Evas_Object *page = NULL;
122
123         retv_if(!ui_manager, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
124         retv_if(!innate_content_info, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
125
126         attach_panel = evas_object_data_get(ui_manager, DATA_KEY_ATTACH_PANEL_INFO);
127         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
128
129         content_info = calloc(1, sizeof(content_s));
130         retv_if(!content_info, ATTACH_PANEL_ERROR_OUT_OF_MEMORY);
131         content_info->attach_panel = attach_panel;
132         content_info->innate_content_info = innate_content_info;
133         content_info->extra_data = extra_data;
134         content_info->order = ORDER_MAX;
135
136         if (innate_content_info->is_ug) {
137                 /* UG side */
138                 page = _page_create(attach_panel, attach_panel->transit_width, 0);
139                 goto_if(!page, ERROR);
140                 _scroller_append_page(attach_panel->scroller, page);
141
142                 content_info->tabbar_item =
143                         _toolbar_append_item(attach_panel->toolbar, innate_content_info->name, page);
144                 goto_if(!content_info->tabbar_item, ERROR);
145                 content_info->content = NULL;
146                 content_info->order = 0;
147         } else {
148                 /* App side */
149                 if (attach_panel->grid) {
150                         /* Grid */
151                         page = attach_panel->grid_page;
152                         content_info->tabbar_item = attach_panel->grid_tabbar_item;
153                 } else {
154                         /* No grid */
155                         Evas_Object *page_bg = NULL;
156                         page = _page_create(attach_panel, attach_panel->transit_width, 0);
157                         page_bg = elm_object_part_content_get(page, "bg");
158                         if (page_bg) {
159                                 evas_object_color_set(page_bg, 250, 250, 250, 255);
160                         }
161                         attach_panel->grid_page = page;
162                         goto_if(!page, ERROR);
163                         _scroller_append_page(attach_panel->scroller, page);
164
165                         content_info->tabbar_item = _toolbar_append_item(attach_panel->toolbar, content_info->innate_content_info->tabbar_name, page);
166                         attach_panel->grid_tabbar_item = content_info->tabbar_item;
167                         goto_if(!content_info->tabbar_item, ERROR);
168                 }
169                 content_info->content = _ui_manager_create_content(page, content_info, attach_panel);
170                 goto_if(!content_info->content, ERROR);
171                 elm_object_part_content_set(page, "content", content_info->content);
172         }
173
174         content_info->page = page;
175
176         if (1 == _toolbar_count_item(attach_panel->toolbar)) {
177                 _toolbar_bring_in(attach_panel->toolbar, content_info->tabbar_item);
178         }
179
180         attach_panel->content_list = eina_list_append(attach_panel->content_list, content_info);
181         content_info->index = eina_list_count(attach_panel->content_list) - 1;
182
183         return ATTACH_PANEL_ERROR_NONE;
184
185 ERROR:
186         if (content_info->tabbar_item) _toolbar_remove_item(attach_panel->toolbar, content_info->tabbar_item);
187         if (content_info->content) _ui_manager_destroy_content(content_info, attach_panel);
188         if (page) _page_destroy(page);
189         free(content_info);
190
191         return ATTACH_PANEL_ERROR_NOT_INITIALIZED;
192 }
193
194
195
196 void _ui_manager_remove_content_category(Evas_Object *ui_manager, content_s *content_info)
197 {
198         attach_panel_h attach_panel = NULL;
199
200         ret_if(!ui_manager);
201         ret_if(!content_info);
202
203         attach_panel = evas_object_data_get(ui_manager, DATA_KEY_ATTACH_PANEL_INFO);
204         ret_if(!attach_panel);
205
206         _ui_manager_destroy_content(content_info, attach_panel);
207
208         if (content_info->innate_content_info->is_ug
209                 || !attach_panel->grid) {
210                 Evas_Object *page = evas_object_data_get(content_info->content, DATA_KEY_PAGE);
211                 if (page) {
212                         _page_destroy(page);
213                 }
214                 _toolbar_remove_item(attach_panel->toolbar, content_info->tabbar_item);
215         }
216
217         attach_panel->content_list = eina_list_remove(attach_panel->content_list, content_info);
218         free(content_info);
219 }
220
221
222
223 static void __remove_content_categories(Evas_Object *ui_manager)
224 {
225         attach_panel_h attach_panel = NULL;
226         content_s *content_info = NULL;
227
228         ret_if(!ui_manager);
229
230         attach_panel = evas_object_data_get(ui_manager, DATA_KEY_ATTACH_PANEL_INFO);
231         ret_if(!attach_panel);
232
233         EINA_LIST_FREE(attach_panel->content_list, content_info) {
234                 Evas_Object *page = NULL;
235
236                 _ui_manager_destroy_content(content_info, attach_panel);
237                 page= evas_object_data_get(content_info->content, DATA_KEY_PAGE);
238                 if (page) {
239                         elm_object_part_content_unset(page, "content");
240                         _page_destroy(page);
241                 }
242                 _toolbar_remove_item(attach_panel->toolbar, content_info->tabbar_item);
243                 free(content_info);
244         }
245 }
246
247
248
249 static void __resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
250 {
251         Evas_Object *ui_manager = obj;
252         Evas_Coord x = 0;
253         Evas_Coord y = 0;
254         Evas_Coord w = 0;
255         Evas_Coord h = 0;
256
257         ret_if(!ui_manager);
258
259         evas_object_geometry_get(ui_manager, &x, &y, &w, &h);
260         _D("ui_manager resize(%d, %d, %d, %d)", x, y, w, h);
261 }
262
263
264
265 static void _change_tab_cb(Evas_Object *toolbar, int event_type, void *event_info, void *data)
266 {
267         attach_panel_h attach_panel = data;
268         Evas_Object *page = event_info;
269         content_s *content_info = NULL;
270
271         ret_if(!attach_panel);
272         ret_if(!attach_panel->toolbar);
273         ret_if(!attach_panel->scroller);
274         ret_if(!page);
275
276         content_info = eina_list_nth(attach_panel->content_list, attach_panel->cur_page_no);
277         ret_if(!content_info);
278         ret_if(!content_info->innate_content_info);
279
280         if (EINA_TRUE == attach_panel->is_delete) {
281                 _D("This is attach_panel_destroy");
282                 return;
283         }
284
285         if (page == content_info->page) {
286                 _D("Tab the same page");
287                 return;
288         }
289
290         if (ATTACH_PANEL_STATE_HIDE == _gesture_get_state()) {
291                 _D("state of attach_panel is hide state");
292                 return;
293         }
294
295         /* TODO : destroy the ug when page is not shown
296
297         if (content_info->innate_content_info->is_ug) {
298                 _ui_manager_destroy_content(content_info, attach_panel);
299                 content_info->content = NULL;
300         } */
301
302         _scroller_bring_in_page(attach_panel->scroller, page, &attach_panel->cur_page_no);
303         content_info = eina_list_nth(attach_panel->content_list, attach_panel->cur_page_no);
304         ret_if(!content_info);
305         ret_if(!content_info->innate_content_info);
306
307         if (!content_info->innate_content_info->is_ug) {
308                 return;
309         }
310
311         if (content_info->content) {
312                 return;
313         }
314
315         _D("change tab for create ug (%s)", content_info->innate_content_info->appid);
316
317         content_info->content = _ui_manager_create_content(content_info->page, content_info, attach_panel);
318         ret_if(!content_info->content);
319         if (ATTACH_PANEL_STATE_FULL == _gesture_get_state()) {
320                 _content_list_send_message(attach_panel->content_list, APP_CONTROL_DATA_SELECTION_MODE, SELECTION_MODE_MULTIPLE, ATTACH_PANEL_CONTENT_CATEGORY_UG);
321         } else {
322                 _content_list_send_message(attach_panel->content_list, APP_CONTROL_DATA_SELECTION_MODE, SELECTION_MODE_SINGLE, ATTACH_PANEL_CONTENT_CATEGORY_UG);
323         }
324 }
325
326
327
328 static void _scroll_cb(Evas_Object *scroller, int event_type, void *event_info, void *data)
329 {
330         attach_panel_h attach_panel = data;
331         Elm_Object_Item *tabbar_item = event_info;
332
333         ret_if(!attach_panel);
334         ret_if(!attach_panel->toolbar);
335         ret_if(!tabbar_item);
336
337         _toolbar_bring_in(attach_panel->toolbar, tabbar_item);
338 }
339
340
341
342 static void __window_resume_cb(void *data, Evas_Object *scroller, void *event_info)
343 {
344         attach_panel_h attach_panel = data;
345         ret_if(!attach_panel);
346
347         if (ATTACH_PANEL_STATE_HIDE == _gesture_get_state()) {
348                 _D("attach panel is already hide");
349                 return;
350         }
351
352         _D("caller window is resumed");
353         _content_list_set_resume(attach_panel->content_list, ATTACH_PANEL_CONTENT_CATEGORY_UG);
354
355         attach_panel->content_list = _list_sort_by_rua(attach_panel->content_list);
356         _grid_refresh(attach_panel->grid);
357 }
358
359
360
361 static void __window_pause_cb(void *data, Evas_Object *scroller, void *event_info)
362 {
363         attach_panel_h attach_panel = data;
364         ret_if(!attach_panel);
365
366         if (ATTACH_PANEL_STATE_HIDE == _gesture_get_state()) {
367                 _D("attach panel is already hide");
368                 return;
369         }
370
371         _D("caller window is paused");
372         _content_list_set_pause(attach_panel->content_list, ATTACH_PANEL_CONTENT_CATEGORY_UG);
373 }
374
375
376
377 static void __lang_changed_cb(void *data, Evas_Object *obj, void *event_info)
378 {
379         _D("language changed");
380         ug_send_event(UG_EVENT_LANG_CHANGE);
381 }
382
383
384
385 static void __keypad_on_cb(void *data, Evas_Object *obj, void *event_info)
386 {
387         attach_panel_h attach_panel = data;
388         ret_if(!attach_panel);
389
390         _D("keypad state on");
391
392         if (ATTACH_PANEL_STATE_HIDE == _gesture_get_state()) {
393                 _D("attach panel is already hide");
394                 return;
395         }
396         /* This is same with attach_panel_hide */
397         _content_list_set_pause(attach_panel->content_list, ATTACH_PANEL_CONTENT_CATEGORY_UG);
398         _gesture_hide(attach_panel);
399 }
400
401
402
403 static void __key_back_cb(void *data, Evas_Object *obj, void *event_info)
404 {
405         attach_panel_h attach_panel = data;
406         ret_if(!attach_panel);
407
408         if (ATTACH_PANEL_STATE_HIDE == _gesture_get_state()) {
409                 _D("attach panel is already hide");
410                 return;
411         }
412         /* This is same with attach_panel_hide() */
413         _content_list_set_pause(attach_panel->content_list, ATTACH_PANEL_CONTENT_CATEGORY_UG);
414         _gesture_hide(attach_panel);
415 }
416
417
418
419 Evas_Object *_ui_manager_create(attach_panel_h attach_panel)
420 {
421         Evas_Object *ui_manager = NULL;
422         Evas_Object *parent = NULL;
423         int ret = ATTACH_PANEL_ERROR_NONE;
424
425         retv_if(!attach_panel, NULL);
426         retv_if(!attach_panel->conformant, NULL);
427
428         ui_manager = elm_layout_add(attach_panel->conformant);
429         retv_if(!ui_manager, NULL);
430         elm_layout_file_set(ui_manager, FILE_LAYOUT_EDJ, GROUP_LAYOUT);
431         evas_object_size_hint_weight_set(ui_manager, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
432         evas_object_size_hint_align_set(ui_manager, EVAS_HINT_FILL, 1.0);
433         evas_object_show(ui_manager);
434
435         evas_object_data_set(ui_manager, DATA_KEY_ATTACH_PANEL_INFO, attach_panel);
436         evas_object_event_callback_add(ui_manager, EVAS_CALLBACK_RESIZE, __resize_cb, NULL);
437
438         attach_panel->toolbar = _toolbar_create(ui_manager, attach_panel);
439         goto_if(!attach_panel->toolbar, ERROR);
440         elm_object_part_content_set(ui_manager, "toolbar", attach_panel->toolbar);
441
442         ret = _toolbar_register_event_cb(attach_panel->toolbar, TOOLBAR_EVENT_TYPE_CHANGE_TAB, _change_tab_cb, attach_panel);
443         goto_if(ATTACH_PANEL_ERROR_NONE != ret, ERROR);
444
445         attach_panel->scroller = _scroller_create(ui_manager, attach_panel);
446         goto_if(!attach_panel->scroller, ERROR);
447         elm_object_part_content_set(ui_manager, "scroller", attach_panel->scroller);
448
449         ret = _scroller_register_event_cb(attach_panel->scroller, SCROLLER_EVENT_TYPE_SCROLL, _scroll_cb, attach_panel);
450         goto_if(ATTACH_PANEL_ERROR_NONE != ret, ERROR);
451
452         parent = attach_panel->conformant;
453         do {
454                 const char *type = NULL;
455
456                 parent = elm_object_parent_widget_get(parent);
457                 break_if(!parent);
458
459                 type = elm_object_widget_type_get(parent);
460                 continue_if(!type);
461                 if (!strcmp(type, "Elm_Win")) {
462                         UG_INIT_EFL(parent, UG_OPT_INDICATOR_DISABLE);
463                         attach_panel->win = parent;
464                         break;
465                 }
466         } while (parent);
467
468         evas_object_smart_callback_add(parent, "normal", __window_resume_cb, attach_panel);
469         evas_object_smart_callback_add(parent, "iconified", __window_pause_cb, attach_panel);
470         evas_object_smart_callback_add(attach_panel->conformant, "language,changed", __lang_changed_cb, NULL);
471         evas_object_smart_callback_add(attach_panel->conformant, "virtualkeypad,state,on", __keypad_on_cb, attach_panel);
472         eext_object_event_callback_add(ui_manager, EEXT_CALLBACK_BACK, __key_back_cb, attach_panel);
473
474         return ui_manager;
475
476 ERROR:
477         if (attach_panel->toolbar) {
478                 _toolbar_destroy(attach_panel->toolbar);
479         }
480
481         if (ui_manager) {
482                 evas_object_del(ui_manager);
483         }
484
485         return NULL;
486 }
487
488
489
490 void _ui_manager_destroy(Evas_Object *ui_manager)
491 {
492         attach_panel_h attach_panel = NULL;
493         int ret = ATTACH_PANEL_ERROR_NONE;
494
495         __remove_content_categories(ui_manager);
496
497         /* attach_panel_h is used in the __remove_content_categories */
498         attach_panel = evas_object_data_del(ui_manager, DATA_KEY_ATTACH_PANEL_INFO);
499         ret_if(!attach_panel);
500
501         eext_object_event_callback_del(ui_manager, EEXT_CALLBACK_BACK, __key_back_cb);
502         evas_object_smart_callback_del(attach_panel->conformant, "virtualkeypad,state,on", __keypad_on_cb);
503         evas_object_smart_callback_del(attach_panel->conformant, "language,changed", __lang_changed_cb);
504         evas_object_event_callback_del(ui_manager, EVAS_CALLBACK_RESIZE, __resize_cb);
505         if (attach_panel->win) {
506                 evas_object_smart_callback_del(attach_panel->win, "normal", __window_resume_cb);
507                 evas_object_smart_callback_del(attach_panel->win, "iconified", __window_pause_cb);
508         }
509
510         if (attach_panel->scroller) {
511                 ret = _scroller_unregister_event_cb(attach_panel->scroller, SCROLLER_EVENT_TYPE_SCROLL, _scroll_cb);
512                 if (ATTACH_PANEL_ERROR_NONE != ret) {
513                         _E("cannot unregiter event_cb for scroller");
514                 }
515                 elm_object_part_content_unset(ui_manager, "scroller");
516                 _scroller_destroy(attach_panel->scroller);
517         }
518
519         if (attach_panel->toolbar) {
520                 ret = _toolbar_unregister_event_cb(attach_panel->toolbar, TOOLBAR_EVENT_TYPE_CHANGE_TAB, _change_tab_cb);
521                 if (ATTACH_PANEL_ERROR_NONE != ret) {
522                         _E("cannot unregiter event_cb for toolbar");
523                 }
524                 elm_object_part_content_unset(ui_manager, "toolbar");
525                 _toolbar_destroy(attach_panel->toolbar);
526         }
527
528         if (attach_panel->ui_manager) {
529                 evas_object_del(ui_manager);
530         }
531 }