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 "homescreen-efl.h"
21 #include "page_scroller.h"
23 #include "folder_panel.h"
26 #include "data_model.h"
32 } page_change_action_t;
38 } possible_view_modes_t;
41 page_change_action_t action;
46 Tree_node_t *repositioned_node;
47 Tree_node_t *opened_folder_node;
48 Tree_node_t *destination_folder;
49 Evas_Object *repositioned_icon_layout;
50 Evas_Object *src_grid;
51 Evas_Object *repositioned_icon;
52 Elm_Object_Item *repositioned_item;
57 Elm_Gengrid_Item_Class *gic;
64 Ecore_Timer *change_page_timer;
65 Ecore_Timer *outside_folder_timer;
66 change_page_data_t cp_data;
68 .repositioned_node = NULL,
69 .opened_folder_node = NULL,
70 .destination_folder = NULL,
71 .repositioned_icon_layout = NULL,
73 .repositioned_icon = NULL,
74 .repositioned_item = NULL,
86 .change_page_timer = NULL,
87 .outside_folder_timer = NULL,
94 /*================================= PRIVATE FUNCTIONS ============================================*/
95 static bool __app_grid_fill(Evas_Object *grid, Tree_node_t *data);
96 static Evas_Object *__app_grid_create_ly(Evas_Object *parent);
97 static bool __app_grid_resize(Evas_Object *app_grid, Evas_Coord new_w, Evas_Coord new_h);
98 static Evas_Object *__app_grid_get_icon_container_ptr(Elm_Object_Item *it);
99 static Eina_Bool __app_grid_change_page_cb(void *data);
100 static void __app_grid_check_page_change(Evas_Object *scroller, int x, int y);
101 static void __app_grid_clear_reposition_structure(void);
102 static Eina_Bool __app_grid_close_folder_cb(void *data);
103 static Evas_Object *__app_grid_create_item_container(Evas_Object *parent);
105 /*================================= GENGRID CALLBACK FUNCTIONS ===================================*/
106 static void __app_grid_item_longpressed_cb(void *data, Evas_Object *obj, void *ei);
107 static Evas_Object *__app_grid_get_content(void *data, Evas_Object *obj, const char *part);
108 static Eina_Bool __app_grid_get_state(void *data, Evas_Object *obj, const char *part);
109 static void __app_grid_del_content(void *data, Evas_Object *obj);
110 static char *__app_grid_get_text(void *data, Evas_Object *obj, const char *part);
111 static void __app_grid_resize_cb(void *data, Evas *e, Evas_Object *obj, void *ei);
113 /*================================= MOUSE HANDLERS ===============================================*/
114 static Eina_Bool _app_grid_mouse_move_cb(void *data, int type, void *event);
115 static Eina_Bool __app_grid_mouse_up_cb(void *data, int type, void *event);
117 /*================================= DND FUNCTIONS ================================================*/
118 static void __app_grid_return_to_origin_pos(void);
119 static void __app_grid_dnd_pos_cb(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y,
120 Elm_Xdnd_Action action);
121 static void __app_grid_dnd_drag_done_cb(void *data, Evas_Object *obj);
122 static void __app_grid_dnd_pos_changed_cb(void *data, Evas_Object *obj, Evas_Coord x,
123 Evas_Coord y, Elm_Xdnd_Action action);
125 /*================================= PUBLIC FUNCTIONS DEFS ========================================*/
126 HAPI Evas_Object *app_grid_create(Evas_Object *parent, Tree_node_t *data, Evas_Coord gengrid_width,
127 Evas_Coord gengrid_height, app_grid_type_t type)
129 Evas_Object *gengrid = NULL;
130 Evas_Object *layout = NULL;
131 Evas_Object *rect = NULL;
134 LOGE("[INVALID_PARAM]['parent'='%p']", parent);
138 rect = evas_object_rectangle_add(evas_object_evas_get(parent));
140 LOGE("[FAILED][rect=NULL]");
144 layout = __app_grid_create_ly(parent);
146 LOGE("[FAILED][__app_grid_create_ly]");
147 evas_object_del(rect);
151 evas_object_color_set(rect, 0, 0, 0, 0);
152 evas_object_size_hint_min_set(rect, gengrid_width, gengrid_height);
153 evas_object_size_hint_max_set(rect, gengrid_width, gengrid_height);
154 elm_object_part_content_set(layout, PART_APP_GRID_SIZE_SETTER, rect);
156 gengrid = elm_gengrid_add(layout);
158 LOGE("[FAILED][elm_gengrid_add]");
159 evas_object_del(layout);
160 evas_object_del(rect);
164 evas_object_size_hint_weight_set(gengrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
165 evas_object_show(gengrid);
168 if (!(s_info.gic = elm_gengrid_item_class_new())) {
169 LOGE("[FAILED][elm_gengrid_item_class_new]");
170 evas_object_del(layout);
171 evas_object_del(rect);
175 s_info.gic->item_style = "default";
176 s_info.gic->func.content_get = __app_grid_get_content;
177 s_info.gic->func.del = __app_grid_del_content;
178 s_info.gic->func.text_get = __app_grid_get_text;
179 s_info.gic->func.state_get = __app_grid_get_state;
181 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _app_grid_mouse_move_cb, parent);
182 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, __app_grid_mouse_up_cb, NULL);
185 elm_object_scale_set(gengrid, 0.5);
187 elm_gengrid_select_mode_set(gengrid, ELM_OBJECT_SELECT_MODE_NONE);
188 elm_gengrid_reorder_mode_set(gengrid, EINA_FALSE);
189 elm_gengrid_align_set(gengrid, 0.0, 0.0);
191 if (!__app_grid_fill(gengrid, data)) {
192 LOGE("[FAILED][__app_grid_fill]");
193 evas_object_del(layout);
194 evas_object_del(rect);
198 if (type == APP_GRID_TYPE_ALL_APPS) {
199 s_info.w = gengrid_width;
200 s_info.h = gengrid_height;
201 } else if (type == APP_GRID_TYPE_FOLDER) {
202 elm_object_signal_emit(layout, SIGNAL_APP_GRID_BG_HIDE, SIGNAL_SOURCE);
205 elm_object_part_content_set(layout, PART_APP_GRID_CONTENT, gengrid);
206 evas_object_smart_callback_add(gengrid, "longpressed", __app_grid_item_longpressed_cb, NULL);
208 elm_drop_target_add(gengrid, ELM_SEL_FORMAT_TARGETS,
209 NULL, NULL, NULL, NULL, __app_grid_dnd_pos_cb, NULL, NULL, NULL);
211 data->data->layout = layout;
212 evas_object_event_callback_add(gengrid, EVAS_CALLBACK_RESIZE, __app_grid_resize_cb, (void *)type);
214 /*It is used only internal.*/
215 evas_object_data_set(gengrid, KEY_APP_GRID_DATA, layout);
217 elm_scroller_movement_block_set(gengrid, ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL);
218 elm_scroller_movement_block_set(gengrid, ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL);
219 elm_gengrid_wheel_disabled_set(gengrid, EINA_TRUE);
224 HAPI Elm_Object_Item *app_grid_append_item(Evas_Object *layout, Evas_Object *icon_to_append)
227 Elm_Object_Item *result = NULL;
228 Evas_Object *container = NULL;
230 if (!layout || !icon_to_append) {
231 LOGE("[INVALID_PARAM][layout='%p'][icon_to_append='%p']", layout, icon_to_append);
235 Evas_Object *grid = elm_object_part_content_get(layout, PART_APP_GRID_CONTENT);
237 LOGE("[FAILED][elm_object_part_content_get]");
241 if (!(result = elm_gengrid_item_append(grid, s_info.gic,
242 (container = app_grid_item_pack(grid, icon_to_append)), NULL, NULL))) {
243 LOGE("Failed to append item");
247 evas_object_show(icon_to_append);
251 HAPI Elm_Object_Item *app_grid_insert_item_relative(Evas_Object *layout, Evas_Object *item,
252 Elm_Object_Item *rel_it)
254 Evas_Object *app_grid = NULL, *container = NULL;
255 Elm_Object_Item *result = NULL;
258 if (!layout || !item) {
259 LOGE("[INVALID_PARAM][layout='%p'][item='%p']", layout, item);
263 app_grid = elm_object_part_content_get(layout, PART_APP_GRID_CONTENT);
265 LOGE("[FAILED][elm_object_part_content_get]");
270 dst_idx = elm_gengrid_item_index_get(rel_it);
272 if ((s_info.src_grid == app_grid && s_info.src_idx > dst_idx)
273 || (s_info.src_grid != app_grid)) {
274 if (!(result = elm_gengrid_item_insert_before(app_grid, s_info.gic,
275 (container = app_grid_item_pack(app_grid, item)), rel_it, NULL, NULL))) {
276 LOGE("[FAILED][elm_gengrid_item_insert_before]");
277 evas_object_del(container);
280 } else if (s_info.src_grid == app_grid && s_info.src_idx < dst_idx) {
281 if (!(result = elm_gengrid_item_insert_after(app_grid, s_info.gic,
282 (container = app_grid_item_pack(app_grid, item)), rel_it, NULL, NULL))) {
283 LOGE("[FAILED][elm_gengrid_item_insert_before]");
288 if (!(result = elm_gengrid_item_append(app_grid, s_info.gic,
289 (container = app_grid_item_pack(app_grid, item)), NULL, NULL))) {
290 LOGE("[FAILED][elm_gengrid_item_append]");
295 evas_object_show(item);
299 HAPI Evas_Object *app_grid_item_pack(Evas_Object *p, Evas_Object *c)
301 Evas_Object *container = NULL;
303 if (!p) { /*When c is null it is not a big problem...it creates then empty gengrid item */
304 LOGD("[ERR][INVALID_PARAM]['p'='%p']", p);
308 /*This items will be removed when gengrid items will be deleted.
309 It was checked in EVAS_CALLBACK_DEL function. */
310 container = __app_grid_create_item_container(home_screen_get_win());
312 LOGE("[FAILED][container=NULL]");
317 elm_object_part_content_set(container, PART_APP_GRID_ITEM, c);
322 HAPI void app_grid_unpack_item(Elm_Object_Item *item)
324 Evas_Object *container = NULL;
327 LOGE("[INVALID_PARAM][item=NULL]");
331 container = elm_object_item_part_content_get(item, GRID_CONTENT);
333 LOGE("[FAILED][elm_object_item_part_content_get]");
337 elm_object_part_content_unset(container, PART_APP_GRID_ITEM);
340 HAPI Eina_Bool app_grid_get_item_content(Elm_Object_Item *item, Evas_Object **icon,
343 Evas_Object *ic = NULL;
344 Evas_Object *container = NULL;
347 LOGE("[INVALID_PARAM][item='%p']", item);
351 container = elm_object_item_part_content_get(item, GRID_CONTENT);
353 LOGE("[FAILED][elm_object_item_part_content_get]");
357 ic = elm_object_part_content_get(container, PART_APP_GRID_ITEM);
359 LOGE("[FAILED][eina_list_data_get]");
367 *data = evas_object_data_get(ic, KEY_ICON_DATA);
369 LOGE("[FAILED][evas_object_data_get]");
370 /*eina_list_free(box_content);*/
377 /*=====================GENGRID CALLBACKS IMPLEMENTATION===========================================*/
378 static void __app_grid_item_longpressed_cb(void *data, Evas_Object *obj, void *ei)
380 Elm_Object_Item *it = (Elm_Object_Item *)ei;
381 Evas_Coord x, y, w, h, m_x, m_y;
382 Evas_Object *icon_layout = NULL;
383 Evas_Object *icon = NULL;
384 Tree_node_t *icon_node = NULL;
386 if (!it || !app_grid_get_item_content(it, &icon_layout, NULL)) {
387 LOGE("[FAILED][app_grid_item_content_get]");
391 if (!evas_object_data_get(icon_layout, KEY_IS_REPOSITIONABLE))
394 if (home_screen_get_view_type() == HOMESCREEN_VIEW_ALL_APPS_CHOOSE)
397 if (home_screen_get_view_type() == HOMESCREEN_VIEW_ALL_APPS) {
398 home_screen_set_view_type(HOMESCREEN_VIEW_ALL_APPS_EDIT);
399 elm_drag_cancel(obj);
403 LOGE("[FAILED][icon_layout=NULL]");
407 icon = elm_object_part_content_get(icon_layout, PART_ICON_CONTENT);
409 LOGE("[FAILED][icon=NULL]");
413 icon_node = evas_object_data_get(icon_layout, KEY_ICON_DATA);
415 LOGE("[FAILED][icon_node=NULL]");
419 /*check if the repositioned item is from a folder.
420 It is necessary for removing item from the folder.*/
421 if (icon_node->parent && icon_node->parent->parent && icon_node->parent->parent->data
422 && icon_node->parent->parent->data->type == APP_ITEM_FOLDER) {
423 s_info.opened_folder_node = icon_node->parent->parent;
424 folder_panel_get_folder_geometry(&s_info.f_x, &s_info.f_y, &s_info.f_w, &s_info.f_h);
427 evas_object_geometry_get(icon, &x, &y, &w, &h);
428 evas_pointer_output_xy_get(evas_object_evas_get(obj), &m_x, &m_y);
429 s_info.dx = abs(m_x - x);
430 s_info.dy = abs(m_y - y);
432 /*check if user perform longpress action on icon or on item.
433 (item is a container for icon..is bigger because it must have place also for icon name)*/
434 if ((m_x >= x && m_x <= x+w) && (m_y >= y && m_y <= y + h)) {
435 s_info.repositioned_icon_layout = icon_layout;
436 s_info.repositioned_icon = icon;
437 s_info.repositioned_item = it;
438 s_info.repositioned_node = icon_node;
439 s_info.src_grid = obj;
440 s_info.src_idx = elm_gengrid_item_index_get(s_info.repositioned_item);
441 s_info.is_dnd_on = true;
443 app_grid_unpack_item(it);
445 elm_drag_start(icon, ELM_SEL_FORMAT_TARGETS, "dnd", ELM_XDND_ACTION_MOVE,
446 NULL, NULL, __app_grid_dnd_pos_changed_cb, NULL, NULL, NULL, __app_grid_dnd_drag_done_cb, obj);
448 evas_object_data_set(icon, KEY_REPOSITION_DATA, icon_layout);
449 /*This is necessary for hide only box content in grid*/
450 elm_object_part_content_unset(icon_layout, PART_ICON_CONTENT);
451 evas_object_hide(icon_layout);
452 all_apps_set_scrolling_blocked_state(true);
453 folder_panel_enable_entry(false);
457 static char *__app_grid_get_text(void *data, Evas_Object *obj, const char *part)
462 static Evas_Object *__app_grid_get_content(void *data, Evas_Object *obj, const char *part)
465 LOGE("[INVALID_PARAM][data='%p']", data);
469 if (!strcmp(GRID_CONTENT, part))
470 return (Evas_Object *) data;
475 static Eina_Bool __app_grid_get_state(void *data, Evas_Object *obj, const char *part)
480 static void __app_grid_del_content(void *data, Evas_Object *obj)
482 LOGD("DELETING : ", evas_object_type_get(obj));
486 static void __app_grid_resize_cb(void *data, Evas *e, Evas_Object *obj, void *ei)
488 int w = -1, h = -1, item_w = -1, item_h = -1;
489 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
491 if ((app_grid_type_t)data == APP_GRID_TYPE_ALL_APPS) {
494 } else if ((app_grid_type_t)data == APP_GRID_TYPE_FOLDER) {
495 item_w = w/FOLDER_COL_APPS - FOLDER_ITEM_MARGIN*home_screen_get_root_width();
496 item_h = h/FOLDER_ROW_APPS;
499 elm_gengrid_item_size_set(obj, item_w, item_h);
502 /*=========================== MOUSE HANDLERS =====================================================*/
503 static Eina_Bool __app_grid_mouse_up_cb(void *data, int type, void *event)
505 home_screen_set_indice_state(INDICE_OFF);
506 return ECORE_CALLBACK_RENEW;
509 static Eina_Bool _app_grid_mouse_move_cb(void *data, int type, void *event)
511 if (s_info.is_dnd_on) {
512 Evas_Object *scroller = (Evas_Object *) data;
513 Ecore_Event_Mouse_Move *move = event;
514 __app_grid_check_page_change(scroller, move->x, move->y);
517 return ECORE_CALLBACK_RENEW;
520 /*========================= PRIVATE FUNCTIONS ====================================================*/
521 static bool __app_grid_fill(Evas_Object *grid, Tree_node_t *data)
523 Evas_Object *icon = NULL, *box = NULL;
524 app_item_t *item = NULL;
525 Tree_node_t *it = NULL;
527 if (!data || !grid) {
528 LOGE("[INVALID_PARAM][grid='%p'][data='%p']", grid, data);
532 TREE_NODE_FOREACH(data, it) {
535 LOGE("[FAILED][item=%p", item);
539 if (!item->exec || !item->icon || !item->label || !item->appid) {
540 LOGE("[FAILED][exec='%p'][icon='%p'][label='%p'][appid='%p']",
541 item->exec, item->label, item->icon, item->appid);
545 LOGI("add item: [%s]", item->label);
547 if (item->type == APP_ITEM_ICON) {
548 icon = app_icon_create(it, APP_ICON_TYPE_APP);
549 } else if (item->type == APP_ITEM_FOLDER) {
550 folder_panel_create(it);
551 app_icon_update_folder_icon(it);
556 LOGE("[FAILED][app_icon_create]");
560 if (!(item->grid_item = elm_gengrid_item_append(grid, s_info.gic,
561 (box = app_grid_item_pack(grid, icon)), NULL, NULL))) {
562 LOGE("Failed to append an item!");
563 evas_object_del(box);
564 if (!box) {/*app_grid_item_pack had failed so the icon is still allocated:*/
565 app_icon_destroy(icon);
576 static Evas_Object *__app_grid_create_ly(Evas_Object *parent)
578 Evas_Object *ly = NULL;
581 LOGE("[INVALID_PARAM][parent='%p']", parent);
585 ly = elm_layout_add(parent);
587 LOGE("[FAILED][elm_layout_add]");
591 if (!elm_layout_file_set(ly, EDJE_DIR"/app_grid.edj", GROUP_APP_GRID)) {
592 LOGE("[FAILED][elm_layout_file_set][%s]", EDJE_DIR"/app_grid.edj");
597 evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
598 evas_object_size_hint_align_set(ly, EVAS_HINT_FILL, EVAS_HINT_FILL);
599 evas_object_show(ly);
604 void app_grid_set_view_mode(Evas_Object *app_grid, homescreen_view_t view)
607 LOGE("[INVALID_PARAM]");
612 case HOMESCREEN_VIEW_ALL_APPS:
613 elm_object_signal_emit(app_grid, SIGNAL_CHOOSE_MODE_OFF, SIGNAL_SOURCE);
614 elm_object_signal_emit(app_grid, SIGNAL_EDIT_MODE_OFF, SIGNAL_SOURCE);
615 __app_grid_resize(app_grid, s_info.w, s_info.h);
617 case HOMESCREEN_VIEW_ALL_APPS_EDIT:
618 elm_object_signal_emit(app_grid, SIGNAL_CHOOSE_MODE_OFF, SIGNAL_SOURCE);
619 elm_object_signal_emit(app_grid, SIGNAL_EDIT_MODE_ON, SIGNAL_SOURCE);
620 __app_grid_resize(app_grid, EDIT_MODE_SCALE*s_info.w, EDIT_MODE_SCALE*s_info.h);
622 case HOMESCREEN_VIEW_ALL_APPS_CHOOSE:
623 elm_object_signal_emit(app_grid, SIGNAL_EDIT_MODE_OFF, SIGNAL_SOURCE);
624 elm_object_signal_emit(app_grid, SIGNAL_CHOOSE_MODE_ON, SIGNAL_SOURCE);
625 __app_grid_resize(app_grid, CHOOSE_MODE_SCALE*s_info.w, CHOOSE_MODE_SCALE*s_info.h);
628 LOGE("[FAILED][type='%d']", view);
633 static bool __app_grid_resize(Evas_Object *app_grid, Evas_Coord new_w, Evas_Coord new_h)
635 Evas_Object *gengrid = NULL;
637 Evas_Coord new_item_w = new_w/APP_COLS;
638 Evas_Coord new_item_h = new_h/APP_ROWS;
641 LOGE("[INVALID_PARAM][app_grid='%p']", app_grid);
645 gengrid = elm_object_part_content_get(app_grid, PART_APP_GRID_CONTENT);
647 LOGE("[FAILED][elm_object_part_content_get]");
651 if (new_item_w < 0 || new_item_h < 0) {
652 LOGE("[INVALID_SIZE]");
656 /*elm_gengrid_item_size_set(gengrid, new_item_w, new_item_h);*/
661 static Eina_Bool __app_grid_change_page_cb(void *data)
663 LOGI("__app_grid_change_page_cb");
664 change_page_data_t *ch_page_data = (change_page_data_t *) data;
665 Evas_Object *parent = NULL;
667 s_info.change_page_timer = NULL;
670 LOGE("[INVALID_PARAM][ch_page_data='%p']", ch_page_data);
671 return ECORE_CALLBACK_CANCEL;
672 } else if (!ch_page_data->parent) {
673 LOGE("[INVALID_PARAM][ch_page_data->parent='%p']", ch_page_data->parent);
674 return ECORE_CALLBACK_CANCEL;
677 parent = ch_page_data->parent;
679 if (ch_page_data->action == NEXT_PAGE_CB) {
680 LOGI("next_page_signal");
681 elm_object_signal_emit(parent, SIGNAL_NEXT_PAGE_CHANGE, SIGNAL_SOURCE);
684 if (ch_page_data->action == PREV_PAGE_CB) {
685 LOGI("prev_page_signal");
686 elm_object_signal_emit(parent, SIGNAL_PREV_PAGE_CHANGE, SIGNAL_SOURCE);
689 return ECORE_CALLBACK_CANCEL;
692 static void __app_grid_check_page_change(Evas_Object *scroller, int x, int y)
695 LOGE("[INVALID_PARAM][scroller='%p']", scroller);
699 s_info.cp_data.parent = scroller;
700 home_screen_set_indice_state(INDICE_OFF);
702 if (x < CHANGE_PAGE_RIGHT_AREA * home_screen_get_root_width() &&
703 x > CHANGE_PAGE_LEFT_AREA * home_screen_get_root_width() &&
704 s_info.change_page_timer) {
705 ecore_timer_del(s_info.change_page_timer);
706 s_info.change_page_timer = NULL;
710 if (x >= CHANGE_PAGE_RIGHT_AREA * home_screen_get_root_width()) {
711 home_screen_set_indice_state(INDICE_NEXT_PAGE_ON);
712 s_info.cp_data.action = NEXT_PAGE_CB;
715 if (x <= CHANGE_PAGE_LEFT_AREA * home_screen_get_root_width()) {
716 home_screen_set_indice_state(INDICE_PREV_PAGE_ON);
717 s_info.cp_data.action = PREV_PAGE_CB;
720 if (!s_info.change_page_timer) {
721 s_info.change_page_timer = ecore_timer_add(CHANGE_PAGE_TIMER, __app_grid_change_page_cb,
722 (void *) &s_info.cp_data);
726 static Evas_Object *__app_grid_get_icon_container_ptr(Elm_Object_Item *it)
728 Evas_Object *container = NULL;
731 LOGE("[INVALID_PARAM][it='%p']", it);
735 container = elm_object_item_part_content_get(it, GRID_CONTENT);
739 static void __app_grid_clear_reposition_structure(void)
741 s_info.destination_folder = NULL;
742 s_info.repositioned_icon_layout = NULL;
743 s_info.repositioned_item = NULL;
744 s_info.repositioned_icon = NULL;
745 s_info.repositioned_node = NULL;
746 s_info.opened_folder_node = NULL;
747 s_info.src_grid = NULL;
749 s_info.is_dnd_on = false;
756 if (s_info.outside_folder_timer) {
757 ecore_timer_del(s_info.outside_folder_timer);
758 s_info.outside_folder_timer = NULL;
761 if (s_info.change_page_timer) {
762 ecore_timer_del(s_info.change_page_timer);
763 s_info.change_page_timer = NULL;
767 static Eina_Bool __app_grid_close_folder_cb(void *data)
769 data_model_detach_from_folder(s_info.opened_folder_node, s_info.repositioned_node);
770 folder_panel_close_folder();
774 static Evas_Object *__app_grid_create_item_container(Evas_Object *parent)
776 Evas_Object *container = NULL;
779 LOGE("[INVALID_PARAM]");
783 container = elm_layout_add(parent);
785 if (!elm_layout_file_set(container, EDJE_DIR"/app_grid.edj", GROUP_APP_GRID_ITEM_CONTAINER)) {
786 LOGE("[FAILED][elm_layout_file_set][%s]", EDJE_DIR"/app_grid.edj");
787 evas_object_del(container);
791 evas_object_size_hint_weight_set(container, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
792 evas_object_show(container);
796 /*=============================== DND FUNCTIONS ==================================================*/
798 static void __app_grid_return_to_origin_pos(void)
800 Evas_Object *container = NULL;
802 if (!s_info.repositioned_item || !s_info.repositioned_icon_layout) {
803 LOGE("[FAILED][repositioned_item='%p'][repositioned_icon='%p']",
804 s_info.repositioned_item, s_info.repositioned_icon_layout);
808 container = __app_grid_get_icon_container_ptr(s_info.repositioned_item);
810 LOGE("[FAILED][__app_grid_get_icon_container_ptr]");
814 elm_object_part_content_set(container, PART_APP_GRID_ITEM, s_info.repositioned_icon_layout);
815 elm_object_part_content_set(s_info.repositioned_icon_layout,
816 PART_ICON_CONTENT, s_info.repositioned_icon);
817 evas_object_show(s_info.repositioned_icon_layout);
820 static void __app_grid_dnd_pos_cb(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y,
821 Elm_Xdnd_Action action)
823 static Elm_Object_Item *it = NULL;
824 Evas_Object *icon = NULL;
825 Evas_Object *old_icon = NULL;
826 Elm_Object_Item *old_it = it;
827 Tree_node_t *destination_icon_data = NULL;
829 it = elm_gengrid_at_xy_item_get(obj, x, y, NULL, NULL);
831 app_grid_get_item_content(old_it, &old_icon, NULL);
832 app_grid_get_item_content(it, &icon, &destination_icon_data);
834 if (!s_info.repositioned_node || !s_info.repositioned_node->data) {
835 LOGE("[INVALID_DATA]");
840 elm_object_signal_emit(old_icon, SIGNAL_UNHIGHLIGHT_FOLDER, SIGNAL_SOURCE);
841 /*function not be invoked when s_info.repositioned_node == NULL;*/
842 if (s_info.repositioned_node->data->type == APP_ITEM_FOLDER ||
843 folder_panel_get_items_count(destination_icon_data) >= FOLDER_MAX_ITEMS) {
844 elm_object_signal_emit(icon, SIGNAL_HIGHLIGHT_IMPOSSIBLE_FOLDER, SIGNAL_SOURCE);
846 elm_object_signal_emit(icon, SIGNAL_HIGHLIGHT_FOLDER, SIGNAL_SOURCE);
850 if (destination_icon_data && destination_icon_data->data->type == APP_ITEM_FOLDER) {
851 s_info.destination_folder = destination_icon_data;
853 s_info.destination_folder = NULL;
857 static void __app_grid_dnd_drag_done_cb(void *data, Evas_Object *obj)
859 Tree_node_t *folder = s_info.destination_folder;
860 Tree_node_t *item = s_info.repositioned_node;
861 Tree_node_t *src_folder = s_info.opened_folder_node;
863 char trbuf[PATH_MAX] = {0, };
865 /*Check if folder has empty space*/
866 if (item && folder && folder_panel_get_items_count(folder) < FOLDER_MAX_ITEMS
867 && item->data->type != APP_ITEM_FOLDER) {
868 home_screen_mvc_drag_item_to_folder_cb(item, folder);
869 evas_object_hide(s_info.repositioned_icon);
870 } else if (item && folder && folder_panel_get_items_count(folder) >= FOLDER_MAX_ITEMS) {
871 popup_data_t *p_data = popup_create_data();
873 LOGE("[FAILED][failed to create popup data]");
877 snprintf(trbuf, sizeof(trbuf), _("IDS_HS_TPOP_MAXIMUM_NUMBER_OF_APPLICATIONS_IN_FOLDER_HPD_REACHED"),
880 p_data->type = POPUP_INFO;
881 p_data->popup_title_text = NULL;
882 p_data->popup_content_text = strdup(trbuf);
883 p_data->popup_confirm_text = NULL;
884 p_data->popup_cancel_text = NULL;
885 p_data->orientation = ELM_POPUP_ORIENT_CENTER;
886 p_data->visible_time = 1.5;
888 popup_show(p_data, NULL, NULL, NULL);
890 __app_grid_return_to_origin_pos();
891 } else if (item && src_folder && !folder_panel_is_folder_visible()) {
892 home_screen_mvc_drag_item_from_folder_cb();
893 elm_object_part_content_set(s_info.repositioned_icon_layout, PART_ICON_CONTENT,
894 s_info.repositioned_icon);
895 app_icon_set_view_mode(s_info.repositioned_icon_layout, home_screen_get_view_type(), false);
897 __app_grid_return_to_origin_pos();
900 if (folder && folder->data->layout)
901 elm_object_signal_emit(folder->data->layout, SIGNAL_UNHIGHLIGHT_FOLDER, SIGNAL_SOURCE);
903 __app_grid_clear_reposition_structure();
904 all_apps_set_scrolling_blocked_state(false);
905 folder_panel_enable_entry(true);
908 static void __app_grid_dnd_pos_changed_cb(void *data, Evas_Object *obj, Evas_Coord x,
909 Evas_Coord y, Elm_Xdnd_Action action)
911 evas_object_move(obj, x - s_info.dx, y - s_info.dy);
913 if (folder_panel_is_folder_visible()) {
914 if ((y <= s_info.f_y || y >= s_info.f_y + s_info.f_h) && !s_info.outside_folder_timer) {
915 s_info.outside_folder_timer = ecore_timer_add(1.0, __app_grid_close_folder_cb, NULL);
916 if (!s_info.outside_folder_timer) {
917 LOGE("[FAILED][timer=NULL]");
920 } else if (y >= s_info.f_y && y <= s_info.f_y + s_info.f_h) {
921 ecore_timer_del(s_info.outside_folder_timer);
922 s_info.outside_folder_timer = NULL;