2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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
8 * http://floralicense.org/license/
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.
18 #include <Elementary.h>
20 #include <app_preference.h>
21 #include <system_settings.h>
23 #include "homescreen-efl.h"
25 #include "option_menu.h"
26 #include "livebox/livebox_panel.h"
27 #include "livebox/livebox_utils.h"
32 #include "data_model.h"
34 #include "folder_panel.h"
35 #include "livebox_all_pages.h"
42 Evas_Object *gradient_bg;
43 Evas_Object *conformant;
45 Evas_Object *all_apps;
49 homescreen_view_t view_type;
61 .view_type = HOMESCREEN_VIEW_HOME,
62 .is_bg_blurred = false
65 static bool mvc_badge_refresh_enable = true;
67 /*======================================UI HELPER FUNCTIONS========================*/
68 static void __homescreen_efl_create_base_gui(void);
69 static void __homescreen_efl_win_delete_request_cb(void *data, Evas_Object *obj, void *event_info);
70 static void __homescreen_efl_get_window_size(Evas_Object *win);
71 static void __homescreen_efl_home_btn_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
72 static void __homescreen_efl_menu_btn_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
73 static void __homescreen_efl_attach_badge_callback(void);
74 static void __homescreen_efl_detach_badge_callback(void);
75 static bool __homescreen_efl_update_icon_label(Tree_node_t *parent, Tree_node_t *node, void *data);
76 static void __homescreen_efl_make_gradient_bg(void);
77 static void __homescreen_efl_show_gradient_bg(void);
78 static void __homescreen_efl_show_normal_bg(void);
80 /*======================================APP CONTROL CALLBACKS=======================*/
81 static bool __homescreen_efl_app_create_cb(void *data);
82 static void __homescreen_efl_app_control_cb(app_control_h app_control, void *data);
83 static void __homescreen_efl_app_pause_cb(void *data);
84 static void __homescreen_efl_app_resume_cb(void *data);
85 static void __homescreen_efl_app_terminate_cb(void *data);
88 /*============================UI CALLBACKS==========================================*/
89 static void __homescreen_efl_lang_changed_cb(app_event_info_h event_info, void *user_data);
90 static void __homescreen_efl_orient_changed_cb(app_event_info_h event_info, void *user_data);
91 static void __homescreen_efl_region_changed_cb(app_event_info_h event_info, void *user_data);
92 static void __homescreen_efl_low_battery_cb(app_event_info_h event_info, void *user_data);
93 static void __homescreen_efl_low_memory_cb(app_event_info_h event_info, void *user_data);
95 /*==================== MVC Controller functions implementation: ===================*/
96 static bool __update_all_badges_count(Tree_node_t *parent, Tree_node_t *node, void *data);
97 static void __badge_change_cb(unsigned int action, const char *app_id, unsigned int count, void *user_data);
98 static bool __homescreen_efl_update_icon_badge(Tree_node_t *parent, Tree_node_t *node, void *data);
99 static void __homescreen_efl_badge_count_update_cb(void *app_item);
100 static void __homescreen_efl_activate_chooser_caption(void);
101 static void __homescreen_efl_deactivate_chooser_caption(void);
102 static void __homescreen_efl_chooser_caption_done_button_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
103 static void __homescreen_efl_chooser_caption_cancel_button_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
104 static bool __homescreen_efl_free_grid_item(Tree_node_t *page, Tree_node_t *item, void *data);
105 static bool __homescreen_efl_increment_page(Tree_node_t *parent, Tree_node_t *item, void *data);
106 static bool __homescreen_efl_attach_all_apps_grid_item(Tree_node_t *page, Tree_node_t *item, void *data);
107 static void __homescreen_efl_apply_data_model_to_view(void);
108 static void __homescreen_efl_show_all_apps(void);
109 static void __homescreen_efl_show_home_view(void);
110 static void __homescreen_efl_home_bg_changed_cb(system_settings_key_e key, void *data);
111 static void __homescreen_efl_apply_home_bg_effect(bool is_on);
112 static Eina_Bool __homescreen_efl_show_all_apps_anim(void *data, double pos);
113 static Eina_Bool __homescreen_efl_show_home_anim(void *data, double pos);
114 /*====================PUBLIC FUNCTIONS IMPLEMENTATION===============================*/
116 /*used to iterate over data model:*/
117 static bool folder_count_pending = false;
118 static unsigned int folder_badge_counter = 0;
120 DAPI int main(int argc, char *argv[])
122 dlog_print(DLOG_DEBUG, LOG_TAG, "Starting homescreen-efl");
125 ui_app_lifecycle_callback_s event_callback = {0,};
126 app_event_handler_h handlers[5] = {NULL, };
128 event_callback.create = __homescreen_efl_app_create_cb;
129 event_callback.terminate = __homescreen_efl_app_terminate_cb;
130 event_callback.pause = __homescreen_efl_app_pause_cb;
131 event_callback.resume = __homescreen_efl_app_resume_cb;
132 event_callback.app_control = __homescreen_efl_app_control_cb;
134 ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, __homescreen_efl_low_battery_cb, NULL);
135 ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, __homescreen_efl_low_memory_cb, NULL);
136 ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, __homescreen_efl_orient_changed_cb, NULL);
137 ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, __homescreen_efl_lang_changed_cb, NULL);
138 ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, __homescreen_efl_region_changed_cb, NULL);
139 ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
141 ret = ui_app_main(argc, argv, &event_callback, NULL);
142 if (ret != APP_ERROR_NONE)
143 dlog_print(DLOG_ERROR, LOG_TAG, "ui_app_main() is failed. err = %d", ret);
145 s_info.view_type = HOMESCREEN_VIEW_HOME;
150 HAPI int home_screen_get_root_width(void)
152 return s_info.root_width;
155 HAPI int home_screen_get_root_height(void)
157 return s_info.root_height;
160 HAPI Evas_Object *home_screen_get_win(void)
165 HAPI Evas_Object *home_screen_get_layout(void)
167 return s_info.layout;
170 HAPI homescreen_view_t home_screen_get_view_type(void)
172 return s_info.view_type;
175 HAPI void home_screen_set_view_type(homescreen_view_t view)
178 case HOMESCREEN_VIEW_HOME:
179 __homescreen_efl_apply_home_bg_effect(false);
180 __homescreen_efl_show_normal_bg();
181 if (s_info.view_type == HOMESCREEN_VIEW_ALL_APPS) {
182 all_apps_set_view_mode(view);
183 __homescreen_efl_show_home_view();
185 else if(s_info.view_type == HOMESCREEN_VIEW_HOME_EDIT)
186 elm_object_signal_emit(s_info.layout, SIGNAL_BOTTOM_BUTTONS_HOME_STATE_SET, SIGNAL_SOURCE);
188 case HOMESCREEN_VIEW_HOME_EDIT:
189 LOGI("HOMESCREEN_VIEW_HOME_EDIT");
190 elm_object_signal_emit(s_info.layout, SIGNAL_BOTTOM_BUTTONS_HOME_EDIT_STATE_SET, SIGNAL_SOURCE);
192 case HOMESCREEN_VIEW_HOME_ALL_PAGES:
193 LOGI("HOMESCREEN_VIEW_HOME_ALL_PAGES");
194 livebox_all_pages_show();
196 case HOMESCREEN_VIEW_ALL_APPS:
197 __homescreen_efl_apply_home_bg_effect(true);
198 __homescreen_efl_show_gradient_bg();
199 if (s_info.view_type == HOMESCREEN_VIEW_HOME)
200 __homescreen_efl_show_all_apps();
202 if (s_info.view_type == HOMESCREEN_VIEW_ALL_APPS_CHOOSE)
203 __homescreen_efl_deactivate_chooser_caption();
204 all_apps_set_view_mode(view);
205 elm_object_signal_emit(s_info.layout, SIGNAL_BOTTOM_BUTTONS_ALL_APPS_STATE_SET, SIGNAL_SOURCE);
206 __badge_change_cb(0, NULL, 0, NULL);
208 case HOMESCREEN_VIEW_ALL_APPS_EDIT:
209 LOGI("HOMESCREEN_VIEW_ALL_APPS_EDIT");
210 if (s_info.view_type == HOMESCREEN_VIEW_ALL_APPS_CHOOSE)
211 __homescreen_efl_deactivate_chooser_caption();
212 all_apps_set_view_mode(view);
213 elm_object_signal_emit(s_info.layout, SIGNAL_BOTTOM_BUTTONS_ALL_APPS_EDIT_STATE_SET, SIGNAL_SOURCE);
215 case HOMESCREEN_VIEW_ALL_APPS_CHOOSE:
216 LOGI("HOMESCREEN_VIEW_ALL_APPS_CHOOSE");
217 __homescreen_efl_activate_chooser_caption();
218 all_apps_set_view_mode(view);
220 case HOMESCREEN_VIEW_UNKNOWN:
221 LOGI("HOMESCREEN_VIEW_UNKNOWN");
224 LOGE("UKNOWN VIEW TYPE");
228 s_info.view_type = view;
231 HAPI void home_screen_set_indice_state(indice_type_t indice)
234 case INDICE_NEXT_PAGE_ON:
235 elm_object_signal_emit(s_info.layout, SIGNAL_NEXT_PAGE_INDICE_SHOW, SIGNAL_SOURCE);
237 case INDICE_PREV_PAGE_ON:
238 elm_object_signal_emit(s_info.layout, SIGNAL_PREV_PAGE_INDICE_SHOW, SIGNAL_SOURCE);
241 elm_object_signal_emit(s_info.layout, SIGNAL_INDICE_HIDE, SIGNAL_SOURCE);
248 HAPI void home_screen_mvc_set_ly_scale(Evas_Object *layout)
250 Evas_Object *edje = NULL;
255 LOGE("[FAILED][invalid parameter]");
259 edje = elm_layout_edje_get(layout);
261 width = s_info.root_width;
262 height = s_info.root_height;
264 if (width == HD_WIDTH && height == HD_HEIGHT) {
266 edje_object_scale_set(edje, HD_SCALE_FACTOR);
267 } else if(width == QHD_WIDTH && height == QHD_HEIGHT) {
269 edje_object_scale_set(edje, QHD_SCALE_FACTOR);
270 } else if(width == WVGA_WIDTH && height == WVGA_HEIGHT) {
272 edje_object_scale_set(edje, WVGA_SCALE_FACTOR);
273 } else if(width == UHD_WIDTH && height == UHD_HEIGHT) {
274 edje_object_scale_set(edje, UHD_SCALE_FACTOR);
278 HAPI void home_screen_close_all_apps_choose_view(void)
280 folder_panel_cancel_add_icon();
281 folder_panel_set_click_ignore_state(false);
282 data_model_check_all_apps(data_model_get_all_apps(), false);
283 home_screen_set_view_type(HOMESCREEN_VIEW_ALL_APPS);
286 /*====================END OF PUBLIC FUNCTIONS IMPLEMENTATION=========================*/
288 static void __homescreen_efl_win_delete_request_cb(void *data, Evas_Object *obj, void *event_info)
293 static Evas_Object *_create_conformant(void)
295 Evas_Object *conformant = NULL;
298 LOGE("Window is not created");
302 conformant = elm_conformant_add(s_info.win);
304 LOGE("Failed to create conformant");
307 elm_win_conformant_set(s_info.win, EINA_TRUE);
309 evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
310 elm_win_resize_object_add(s_info.win, conformant);
312 elm_win_indicator_mode_set(s_info.win, ELM_WIN_INDICATOR_SHOW);
313 elm_win_indicator_opacity_set(s_info.win, ELM_WIN_INDICATOR_TRANSLUCENT);
314 elm_object_signal_emit(conformant, "elm,state,indicator,overlap", "elm");
316 evas_object_show(conformant);
321 static void __homescreen_efl_create_base_gui(void)
323 char edj_path[PATH_MAX] = {0, };
324 const char *bg_path = util_get_res_file_path(IMAGE_DIR"/default_bg.png");
325 char trbuf[PATH_MAX] = {0, };
330 s_info.win = elm_win_util_standard_add(PACKAGE, PACKAGE);
331 // evas_object_resize(s_info.win, 1440, 2560);
332 elm_win_autodel_set(s_info.win, EINA_TRUE);
334 evas_object_smart_callback_add(s_info.win, "delete,request", __homescreen_efl_win_delete_request_cb, NULL);
337 s_info.bg = evas_object_image_filled_add(evas_object_evas_get(s_info.win));
339 ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN, &buf);
340 if (!buf || ret != SYSTEM_SETTINGS_ERROR_NONE) {
341 evas_object_image_file_set(s_info.bg, bg_path, "bg");
343 evas_object_image_file_set(s_info.bg, buf, "bg");
347 system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN, __homescreen_efl_home_bg_changed_cb, NULL);
349 elm_win_resize_object_add(s_info.win, s_info.bg);
350 evas_object_show(s_info.bg);
352 __homescreen_efl_get_window_size(s_info.win);
355 s_info.conformant = _create_conformant();
358 snprintf(edj_path, sizeof(edj_path), "%s", util_get_res_file_path(EDJE_DIR"/home.edj"));
359 s_info.layout = elm_layout_add(s_info.win);
360 elm_layout_file_set(s_info.layout, edj_path, GROUP_HOME_LY);
361 evas_object_size_hint_weight_set(s_info.layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
362 elm_win_resize_object_add(s_info.win, s_info.layout);
363 evas_object_show(s_info.layout);
365 home_screen_mvc_set_ly_scale(s_info.layout);
367 s_info.home = livebox_panel_create(s_info.layout);
369 evas_object_del(s_info.win);
370 evas_object_del(s_info.bg);
371 evas_object_del(s_info.conformant);
372 evas_object_del(s_info.layout);
374 LOGE("s_info.home == NULL");
378 elm_object_part_content_set(s_info.layout, PART_CONTENT, s_info.home);
380 /* Show window after base gui is set up */
381 dlog_print(DLOG_INFO, LOG_TAG ,"WINDOW SIZE IS : %d %d", s_info.root_width, s_info.root_height);
382 evas_object_show(s_info.win);
383 elm_object_signal_callback_add(s_info.layout, SIGNAL_HOME_BTN_CLICKED, SIGNAL_SOURCE, __homescreen_efl_home_btn_clicked, NULL);
384 elm_object_signal_callback_add(s_info.layout, SIGNAL_MENU_BTN_CLICKED, SIGNAL_SOURCE, __homescreen_efl_menu_btn_clicked, NULL);
386 /*Chooser caption setup:*/
387 elm_layout_signal_callback_add(s_info.layout, "mouse,clicked,*",
388 "chooser_caption_left_clickable_space",
389 __homescreen_efl_chooser_caption_cancel_button_cb, NULL);
390 elm_layout_signal_callback_add(s_info.layout, "mouse,clicked,*",
391 "chooser_caption_right_clickable_space",
392 __homescreen_efl_chooser_caption_done_button_cb, NULL);
394 snprintf(trbuf, sizeof(trbuf), _("IDS_MEMO_HEADER_PD_SELECTED_ABB2"), 0);
395 layout_main_caption_set_menu_texts(trbuf,
396 _("IDS_TPLATFORM_ACBUTTON_CANCEL_ABB"),
397 _("IDS_TPLATFORM_ACBUTTON_DONE_ABB"));
400 /*TODO: coding convention!*/
401 bool tree_print_cb(Tree_node_t *parent_node, Tree_node_t *tn, void *data)
403 app_item_t *item = tn->data;
404 app_item_t *parent = NULL;
407 parent = tn->parent->data;
409 LOGD("TYPE: %2d; PARENT name: %12.12s; id: %2d | ITEM appid: %28.28s; id: %2d; [%d, %d; %d, %d]; %s",
411 parent ? parent->appid : "NULL",
412 parent ? parent->unique_id : -1,
424 /*TODO: coding convention!*/
425 void home_screen_print_tree(void)
427 LOGD("TREE TEST START");
428 data_model_iterate(data_model_get_data(), tree_print_cb, NULL);
431 static void __homescreen_efl_attach_badge_callback(void)
433 app_mgr_register_badge_callback(__badge_change_cb);
436 static void __homescreen_efl_detach_badge_callback(void)
438 app_mgr_unregister_badge_callback(__badge_change_cb);
441 static bool __homescreen_efl_app_create_cb(void *data)
443 elm_config_accel_preference_set("3d");
444 ecore_animator_frametime_set(FRAMES_PER_SECOND);
449 __homescreen_efl_create_base_gui();
450 folder_panel_init_module();
453 if(!data_model_load_db()) {
454 data_model_load_app_mgr();
457 livebox_panel_fill();
458 livebox_panel_set_content(s_info.layout);
459 __homescreen_efl_attach_badge_callback();
461 home_screen_mvc_update_view();
465 static void __homescreen_efl_app_control_cb(app_control_h app_control, void *data)
467 elm_win_activate(s_info.win);
470 static void __homescreen_efl_app_pause_cb(void *data)
472 /* Take necessary actions when application becomes invisible. */
473 livebox_panel_paused();
476 static void __homescreen_efl_app_resume_cb(void *data)
478 /* Take necessary actions when application becomes visible. */
479 livebox_panel_resumed();
482 static void __homescreen_efl_app_terminate_cb(void *data)
484 /* Release all resources. */
485 __homescreen_efl_detach_badge_callback();
491 folder_panel_deinit_module();
493 livebox_panel_destroy();
496 static bool __homescreen_efl_update_icon_label(Tree_node_t *parent, Tree_node_t *node, void *data)
498 if(!node || !node->data)
502 if (node->data->label && node->data->type == APP_ITEM_ICON) {
503 free(node->data->label);
504 node->data->label = app_mgr_get_app_label(node->data->appid);
508 elm_object_part_text_set(node->data->layout, PART_ICON_NAME, node->data->label);
513 static void __homescreen_efl_make_gradient_bg(void)
515 #ifdef HOME_HOME_SCREEN_GRADIENT_ENABLED
517 Evas_Colorspace ec = EVAS_COLORSPACE_ARGB8888;
518 char *image_raw_data = NULL;
520 int image_height = 0;
529 ec = evas_object_image_colorspace_get(s_info.bg);
531 if(ec != EVAS_COLORSPACE_ARGB8888)
534 image_raw_data = evas_object_image_data_get(s_info.bg, EINA_FALSE);
538 evas_object_image_size_get(s_info.bg, &image_width, &image_height);
539 if(image_width == 0 || image_height == 0)
542 if(!s_info.gradient_bg)
543 s_info.gradient_bg = evas_object_rectangle_add(evas_object_evas_get(s_info.win));
545 if(!s_info.gradient_bg)
548 evas_object_resize(s_info.gradient_bg, s_info.root_width, s_info.root_height);
554 evas_map_util_points_populate_from_object(m, s_info.gradient_bg);
556 r = image_raw_data[2] & 0xff;
557 g = image_raw_data[1] & 0xff;
558 b = image_raw_data[0] & 0xff;
559 a = image_raw_data[3] & 0xff;
560 evas_map_point_color_set(m, 0, r, g, b, a);
562 r = image_raw_data[4*image_width -4 + 2] & 0xff;
563 g = image_raw_data[4*image_width -4 + 1] & 0xff;
564 b = image_raw_data[4*image_width -4 + 0] & 0xff;
565 a = image_raw_data[4*image_width -4 + 3] & 0xff;
566 evas_map_point_color_set(m, 1, r, g, b, a);
568 r = image_raw_data[4*image_width -4 + (image_height-1)*4*image_width + 2] & 0xff;
569 g = image_raw_data[4*image_width -4 + (image_height-1)*4*image_width + 1] & 0xff;
570 b = image_raw_data[4*image_width -4 + (image_height-1)*4*image_width + 0] & 0xff;
571 a = image_raw_data[4*image_width -4 + (image_height-1)*4*image_width + 3] & 0xff;
572 evas_map_point_color_set(m, 2, r, g, b, a);
574 r = image_raw_data[(image_height-1)*4*image_width + 2] & 0xff;
575 g = image_raw_data[(image_height-1)*4*image_width + 1] & 0xff;
576 b = image_raw_data[(image_height-1)*4*image_width + 0] & 0xff;
577 a = image_raw_data[(image_height-1)*4*image_width + 3] & 0xff;
578 evas_map_point_color_set(m, 3, r, g, b, a);
580 evas_object_map_set(s_info.gradient_bg, m);
581 evas_object_map_enable_set(s_info.gradient_bg, EINA_TRUE);
586 static void __homescreen_efl_show_gradient_bg(void)
588 #ifdef HOME_HOME_SCREEN_GRADIENT_ENABLED
589 if(s_info.gradient_bg) {
590 evas_object_hide(s_info.bg);
591 elm_win_resize_object_del(s_info.win, s_info.bg);
592 elm_win_resize_object_add(s_info.win, s_info.gradient_bg);
593 evas_object_show(s_info.gradient_bg);
594 evas_object_raise(s_info.layout);
599 static void __homescreen_efl_show_normal_bg(void)
601 #ifdef HOME_HOME_SCREEN_GRADIENT_ENABLED
602 evas_object_hide(s_info.gradient_bg);
603 elm_win_resize_object_del(s_info.win, s_info.gradient_bg);
604 elm_win_resize_object_add(s_info.win, s_info.bg);
605 evas_object_show(s_info.bg);
606 evas_object_raise(s_info.layout);
610 static void __homescreen_efl_lang_changed_cb(app_event_info_h event_info, void *user_data)
612 data_model_iterate(NULL, __homescreen_efl_update_icon_label, NULL);
615 static void __homescreen_efl_orient_changed_cb(app_event_info_h event_info, void *user_data)
617 /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/
620 static void __homescreen_efl_region_changed_cb(app_event_info_h event_info, void *user_data)
622 /*APP_EVENT_REGION_FORMAT_CHANGED*/
625 static void __homescreen_efl_low_battery_cb(app_event_info_h event_info, void *user_data)
627 /*APP_EVENT_LOW_BATTERY*/
630 static void __homescreen_efl_low_memory_cb(app_event_info_h event_info, void *user_data)
632 /*APP_EVENT_LOW_MEMORY*/
635 static void __homescreen_efl_get_window_size(Evas_Object *win)
637 elm_win_screen_size_get(win, NULL, NULL, &s_info.root_width, &s_info.root_height);
638 dlog_print(DLOG_DEBUG, LOG_TAG, "Width: [%d], Height: [%d]", s_info.root_width, s_info.root_height);
641 static void __homescreen_efl_home_btn_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
643 homescreen_view_t view_t = home_screen_get_view_type();
645 if (view_t == HOMESCREEN_VIEW_HOME) {
646 home_screen_set_view_type(HOMESCREEN_VIEW_ALL_APPS);
647 } else if (view_t == HOMESCREEN_VIEW_ALL_APPS) {
648 home_screen_set_view_type(HOMESCREEN_VIEW_HOME);
652 static void __homescreen_efl_menu_btn_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
654 homescreen_view_t view = home_screen_get_view_type();
657 case HOMESCREEN_VIEW_HOME:
658 case HOMESCREEN_VIEW_ALL_APPS:
666 /*==================== MVC Controller functions implementation: ===================*/
668 /*TODO: code convention!*/
669 void home_screen_mvc_item_uninstall_cb(Tree_node_t *item)
671 if (!item || !item->data)
674 if (item->data->type == APP_ITEM_ICON) {
675 app_mgr_uninstall_app(item->data->appid);
676 data_model_uninstall_application(item);
677 } else {/*folder item type:*/
678 data_model_delete_folder(item);
681 /*by default model is being sorted:*/
682 data_model_sort(NULL);
683 data_model_free_empty_pages(NULL);
684 __homescreen_efl_apply_data_model_to_view();
685 all_apps_remove_empty_pages();
688 void home_screen_mvc_update_view(void)
690 data_model_sort(NULL);
691 __homescreen_efl_apply_data_model_to_view();
694 void home_screen_mvc_drag_item_to_folder_cb(Tree_node_t *dragged_item, Tree_node_t *folder)
696 if (dragged_item && folder) {
698 data_model_append_node_to_folder(folder, dragged_item); /*there were no pages in folder*/
700 data_model_reposition_item(dragged_item, folder->last, folder->last->last, REPOSITION_SIDE_TO_RIGHT, FOLDER_APPS_PAGE);
702 /*for now model is always sorted:*/
703 data_model_sort(NULL);
704 data_model_free_empty_pages(NULL);
705 __homescreen_efl_apply_data_model_to_view();
706 all_apps_remove_empty_pages();
710 /*TODO:All mvc funcitons will be moved to separeted file.*/
711 void home_screen_mvc_drag_item_from_folder_cb(void)
713 __homescreen_efl_apply_data_model_to_view();
716 static void __homescreen_efl_activate_chooser_caption(void)
718 data_model_check_all_apps(data_model_get_all_apps(), false);
719 elm_layout_signal_emit(s_info.layout, SIGNAL_CHOOSER_CAPTION_ACTIVATE, SIGNAL_SOURCE);
720 elm_win_indicator_mode_set(s_info.win, ELM_WIN_INDICATOR_HIDE);
723 static void __homescreen_efl_deactivate_chooser_caption(void)
725 elm_layout_signal_emit(s_info.layout, SIGNAL_CHOOSER_CAPTION_DEACTIVATE, SIGNAL_SOURCE);
726 elm_win_indicator_mode_set(s_info.win, ELM_WIN_INDICATOR_SHOW);
729 static bool __homescreen_efl_free_grid_item(Tree_node_t *page, Tree_node_t *item, void *data)
731 if (!item->data || !item->data->grid_item) {
732 LOGE("__homescreen_efl_free_grid_item, skipping: %d %d", item->data, item->data ? item->data->type : -1);
736 if (!item->data->layout)
737 LOGD("__homescreen_efl_free_grid_item, %s item->data->layout == NULL", item->data->label);
739 all_apps_detach_from_grid(item->data->grid_item);
740 item->data->grid_item = NULL;
741 evas_object_hide(item->data->layout);
746 static bool __homescreen_efl_increment_page(Tree_node_t *parent, Tree_node_t *item, void *data)
753 static bool __homescreen_efl_attach_all_apps_grid_item(Tree_node_t *page, Tree_node_t *item, void *data)
756 LOGE("__homescreen_efl_attach_all_apps_grid_item, skipping: %d", item->data);
760 item->data->grid_item = all_apps_attach_to_grid(item->data->layout, *(int *)data);
762 if (!item->data->grid_item) {
763 /*failed to attach item - there is no room in page scroller
764 so we have to add another page. This problem does not concern folders.*/
766 if (!all_apps_append_page(page))
767 LOGE("Could not create page for item: %s", item->data->label);
770 app_icon_set_view_mode(item->data->layout, home_screen_get_view_type(), false);
775 static bool _folder_grid_item_att(Tree_node_t *page, Tree_node_t *item, void *data)
777 if (!item->data || !page->parent || !page->parent->data ||
778 page->parent->data->type != APP_ITEM_FOLDER ||
779 folder_panel_get_opened_folder_item() != page->parent->data) {
780 LOGE("_folder_grid_item_att, skipping: %s dest_folder: %d", item->data ? item->data->appid : NULL);
784 item->data->grid_item = folder_panel_attach_to_grid(item->data->layout, ((app_item_t *)page->parent->data)->data);
789 static bool _folder_data_model_to_view_apply_cb(Tree_node_t *page, Tree_node_t *item, void *data)
791 if (!item->data || item->data->type != APP_ITEM_FOLDER)
794 data_model_iterate_pages(item, NULL, __homescreen_efl_free_grid_item, NULL);
795 data_model_iterate_pages(item, NULL, _folder_grid_item_att, NULL);
796 app_icon_update_folder_icon(item);
800 static void __homescreen_efl_apply_data_model_to_view(void)
802 int page_counter = -1;
803 Tree_node_t *apps_root = data_model_get_all_apps();
805 if (!apps_root || !apps_root->data || apps_root->data->type != APP_ITEM_ALL_APPS_ROOT) {
806 LOGE("Can't apply view [apps root]: %d %d", apps_root, apps_root ? apps_root->data : NULL);
810 mvc_badge_refresh_enable = false;
812 data_model_iterate_pages(NULL, NULL, __homescreen_efl_free_grid_item, NULL);
813 data_model_iterate_pages(NULL, NULL, _folder_data_model_to_view_apply_cb, NULL);
814 data_model_iterate_pages(NULL, __homescreen_efl_increment_page, __homescreen_efl_attach_all_apps_grid_item, &page_counter);
815 all_apps_update_dynamic_index_count();
817 mvc_badge_refresh_enable = true;
819 __badge_change_cb(0, NULL, 0, NULL);
822 static bool _checked_items_get(Tree_node_t *root, Tree_node_t *item, void *list)
824 Eina_List **checked_items_list = (Eina_List **)list;
826 if (item->data && item->data->is_checked) {
827 *checked_items_list = eina_list_append(*checked_items_list, item);
828 item->data->is_checked = false;
834 static void __homescreen_efl_chooser_caption_done_button_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
836 /*Folder creation/modification:*/
837 app_item_t *destination_folder_data = NULL;
838 Eina_List *iterator = NULL, *checked_items_list = NULL;
839 Tree_node_t *item = NULL;
840 Tree_node_t *destination_folder = folder_panel_get_opened_folder_node();
842 if (!destination_folder) {
843 destination_folder_data = app_item_create(APP_ITEM_FOLDER, -1, "", NULL, NULL, NULL, NULL, true, 0, 0, 0, 0, NULL);
845 if (!destination_folder_data) {
846 LOGE("caption_done_button_cb: failed to create destination_folder_data");
850 destination_folder = data_model_create_folder(destination_folder_data);
852 if (!destination_folder) {
853 LOGE("caption_done_button_cb: failed to create destination_folder");
854 folder_panel_cancel_add_icon();
855 folder_panel_set_click_ignore_state(false);
856 app_item_free(destination_folder_data);
859 folder_panel_create(destination_folder);
862 /*all checked items should be added to the folder:*/
863 data_model_iterate(NULL, _checked_items_get, &checked_items_list);
865 EINA_LIST_FOREACH(checked_items_list, iterator, item)
866 data_model_append_node_to_folder(destination_folder, item);
868 eina_list_free(checked_items_list);
869 /*for now they are always sorted:*/
870 data_model_sort(NULL);
872 folder_panel_cancel_add_icon();
873 folder_panel_set_click_ignore_state(false);
875 data_model_free_empty_pages(NULL);
876 home_screen_set_view_type(HOMESCREEN_VIEW_ALL_APPS);
877 __homescreen_efl_apply_data_model_to_view();
878 all_apps_remove_empty_pages();
881 static void __homescreen_efl_chooser_caption_cancel_button_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
883 home_screen_close_all_apps_choose_view();
886 static void __homescreen_efl_show_all_apps(void)
888 livebox_panel_unset_content(s_info.layout);
891 if (!s_info.all_apps)
892 s_info.all_apps = all_apps_create(s_info.layout, NULL);
894 elm_object_part_content_unset(s_info.layout, PART_CONTENT);
896 evas_object_hide(s_info.all_apps);
897 evas_object_move(s_info.all_apps, 0, s_info.root_height);
899 elm_object_signal_emit(s_info.layout, SIGNAL_BLOCK_EVENTS, SIGNAL_SOURCE);
900 app_icon_set_click_ignore(true);
902 ecore_animator_timeline_add(APPS_SHOW_HIDE_ANIMATION_TIME, __homescreen_efl_show_all_apps_anim, NULL);
905 static void __homescreen_efl_show_home_view(void)
907 elm_object_part_content_unset(s_info.layout, PART_CONTENT);
909 elm_object_signal_emit(s_info.layout, SIGNAL_BOTTOM_BUTTONS_HOME_STATE_SET, SIGNAL_SOURCE);
911 elm_object_signal_emit(s_info.layout, SIGNAL_BLOCK_EVENTS, SIGNAL_SOURCE);
912 app_icon_set_click_ignore(true);
914 ecore_animator_timeline_add(APPS_SHOW_HIDE_ANIMATION_TIME, __homescreen_efl_show_home_anim, NULL);
917 static bool __update_all_badges_count(Tree_node_t *parent, Tree_node_t *node, void *data)
919 app_item_t *item = NULL;
923 __homescreen_efl_badge_count_update_cb(item);
929 static void __badge_change_cb(unsigned int action, const char *app_id, unsigned int count, void *user_data)
931 data_model_iterate(NULL, __update_all_badges_count, NULL);
934 static bool __homescreen_efl_update_icon_badge(Tree_node_t *parent, Tree_node_t *node, void *data)
936 app_item_t *app = (app_item_t *)data;
938 if (!folder_count_pending && app != node->data)
941 if (!folder_count_pending && app == node->data) {
942 folder_count_pending = true;
943 data_model_iterate(node, __homescreen_efl_update_icon_badge, app);
944 folder_count_pending = false;
947 if (folder_count_pending && node->data->type == APP_ITEM_ICON)
948 folder_badge_counter += node->data->badge_count;
950 if (!folder_count_pending && app == node->data)
956 static void __homescreen_efl_badge_count_update_cb(void *app_item)
958 app_item_t *app = (app_item_t *)app_item;
960 if (!mvc_badge_refresh_enable)
964 LOGE("badge_count_update_cb: app_item is NULL");
968 if (app->type == APP_ITEM_ICON && !app_mgr_app_get_badge_count(app->appid, &app->badge_count)) {
969 LOGE("badge_count_update_cb: get_badge_count returned error");
973 if (app->type == APP_ITEM_FOLDER) {
974 folder_count_pending = false;
975 folder_badge_counter = 0;
976 data_model_iterate(NULL, __homescreen_efl_update_icon_badge, app);
977 app->badge_count = folder_badge_counter;
980 app_icon_show_badge(app->layout, app->badge_count);
983 static void __homescreen_efl_home_bg_changed_cb(system_settings_key_e key, void *data)
989 LOGE("[FAILED][bg=NULL]");
993 ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN, &buf);
994 if (!buf || ret != SYSTEM_SETTINGS_ERROR_NONE) {
995 LOGE("[FAILED][failed to get bg path]");
999 evas_object_image_file_set(s_info.bg, buf, "bg");
1002 __homescreen_efl_make_gradient_bg();
1005 static void __homescreen_efl_apply_home_bg_effect(bool is_on)
1007 #ifndef HOME_HOME_SCREEN_BLUR_ENABLED
1012 /*source data and destination data (pixel values)*/
1013 uint32_t *src = NULL, *dst = NULL;
1015 /*values of channels in each pixel*/
1016 uint32_t A = 0, R = 0, G = 0, B = 0;
1018 /*helper variables*/
1019 uint32_t *s = NULL, *d = NULL, w = 0, p = 0;
1021 int width = -1, height = -1;
1024 int i = 0, j = 0, k = 0;
1026 /*kernel used for transform the image*/
1028 const int size = COUNT_OF(kernel);
1029 const int half = size / 2;
1032 LOGE("[FAILED][bg=NULL]");
1036 /*if is_on == false, then restore original image data*/
1038 /*restore original data and return;*/
1039 system_settings_get_value_string(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN, &buf);
1041 LOGE("[FAILED][failed to get bg path]");
1045 evas_object_image_file_set(s_info.bg, buf, "bg");
1047 s_info.is_bg_blurred = false;
1051 evas_object_image_size_get(s_info.bg, &width, &height);
1052 src = evas_object_image_data_get(s_info.bg, EINA_TRUE);
1054 /*if image is already blurred then we should not perform once again*/
1055 if (s_info.is_bg_blurred)
1058 dst = (uint32_t *) alloca(sizeof(uint32_t) * width * height);
1060 LOGE("[FAILED][dst=NULL]");
1066 for (i = 0; i < size; i++) {
1067 double f = i - half;
1068 w += kernel[i] = exp(-f * f / 60.0) * 40;
1071 /*Apply modifications from src - > dst*/
1072 for (i = 0; i < height; i++) {
1073 s = (uint32_t *) (src + i * width);
1074 d = (uint32_t *) (dst + i * width);
1076 for (j = 0; j < width; j++) {
1078 for (k = 0; k < size; k++) {
1079 if (j - half + k < 0 || j - half + k >= width) {
1084 p = s[j - half + k];
1086 A = (p & 0xff000000);
1087 R += ((p >> 16) & 0xff) * kernel[k];
1088 G += ((p >> 8) & 0xff) * kernel[k];
1089 B += ((p >> 0) & 0xff) * kernel[k];
1091 d[j] = A | (((uint32_t)(R / w)) << 16) | (((uint32_t)(G / w)) << 8) | ((uint32_t)(B / w));
1095 /*Apply modification from dst -> srcs*/
1096 for (i = 0; i < height; i++) {
1097 s = (uint32_t *) (dst + i * width);
1098 d = (uint32_t *) (src + i * width);
1099 for (j = 0; j < width; j++) {
1101 for (k = 0; k < size; k++) {
1102 if (i - half + k < 0 || i - half + k >= height) {
1107 s = (uint32_t *) (dst + (i - half + k) * width);
1110 A = (p & 0xff000000);
1111 R += ((p >> 16) & 0xff) * kernel[k];
1112 G += ((p >> 8) & 0xff) * kernel[k];
1113 B += ((p >> 0) & 0xff) * kernel[k];
1115 d[j] = A | (((uint32_t)(R / w)) << 16) | (((uint32_t)(G / w)) << 8) | ((uint32_t)(B / w));
1119 s_info.is_bg_blurred = true;
1120 evas_object_image_data_update_add(s_info.bg, 0, 0, width, height);
1123 static Eina_Bool __homescreen_efl_show_all_apps_anim(void *data, double pos)
1125 Evas_Object *box = elm_object_content_get(s_info.all_apps);
1127 evas_object_show(s_info.all_apps);
1128 evas_object_move(s_info.all_apps, 0, (1.0 - pos) * ALL_APPS_ANIMATION_DELTA_Y);
1129 evas_object_move(s_info.home, 0, -pos * ALL_APPS_ANIMATION_HOME_DELTA_Y);
1131 evas_object_color_set(box, 255, 255, 255, pos*(double)255);
1134 elm_object_part_content_set(s_info.layout, PART_CONTENT, s_info.all_apps);
1136 elm_object_signal_emit(s_info.layout, SIGNAL_UNBLOCK_EVENTS, SIGNAL_SOURCE);
1137 return ECORE_CALLBACK_DONE;
1140 return ECORE_CALLBACK_RENEW;
1143 static Eina_Bool __homescreen_efl_show_home_anim(void *data, double pos)
1145 Evas_Object *box = elm_object_content_get(s_info.all_apps);
1147 evas_object_move(s_info.all_apps, 0, pos * ALL_APPS_ANIMATION_DELTA_Y);
1148 evas_object_move(s_info.home, 0, -(1.0 - pos ) * ALL_APPS_ANIMATION_HOME_DELTA_Y);
1150 evas_object_color_set(box, 255, 255, 255, (1.0 - pos * 2.0)*(double)255);
1153 if (s_info.layout && elm_object_part_content_get(s_info.layout, PART_CONTENT) == NULL && s_info.home) {
1154 elm_object_part_content_set(s_info.layout, PART_CONTENT, s_info.home);
1155 livebox_panel_set_content(s_info.layout);
1158 elm_object_signal_emit(s_info.layout, SIGNAL_UNBLOCK_EVENTS, SIGNAL_SOURCE);
1159 return ECORE_CALLBACK_DONE;
1162 return ECORE_CALLBACK_RENEW;