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_icon_drop(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y,
120 Elm_Xdnd_Action action);
121 static void __app_grid_drag_done(void *data, Evas_Object *obj);
122 static Evas_Event_Flags __app_grid_icon_move(void *data, void *event_info);
123 static Evas_Event_Flags __app_grid_icon_move_end(void *data, void *event_info);
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 data->data->layout = layout;
209 evas_object_event_callback_add(gengrid, EVAS_CALLBACK_RESIZE, __app_grid_resize_cb, (void *)type);
211 /*It is used only internal.*/
212 evas_object_data_set(gengrid, KEY_APP_GRID_DATA, layout);
214 elm_scroller_movement_block_set(gengrid, ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL);
215 elm_scroller_movement_block_set(gengrid, ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL);
216 elm_gengrid_wheel_disabled_set(gengrid, EINA_TRUE);
221 HAPI Elm_Object_Item *app_grid_append_item(Evas_Object *layout, Evas_Object *icon_to_append)
223 Elm_Object_Item *result = NULL;
224 Evas_Object *container = NULL;
226 if (!layout || !icon_to_append) {
227 LOGE("[INVALID_PARAM][layout='%p'][icon_to_append='%p']", layout, icon_to_append);
231 Evas_Object *grid = elm_object_part_content_get(layout, PART_APP_GRID_CONTENT);
233 LOGE("[FAILED][elm_object_part_content_get]");
237 if (!(result = elm_gengrid_item_append(grid, s_info.gic,
238 (container = app_grid_item_pack(grid, icon_to_append)), NULL, NULL))) {
239 LOGE("Failed to append item");
243 evas_object_show(icon_to_append);
247 HAPI Elm_Object_Item *app_grid_insert_item_relative(Evas_Object *layout, Evas_Object *item,
248 Elm_Object_Item *rel_it)
250 Evas_Object *app_grid = NULL, *container = NULL;
251 Elm_Object_Item *result = NULL;
254 if (!layout || !item) {
255 LOGE("[INVALID_PARAM][layout='%p'][item='%p']", layout, item);
259 app_grid = elm_object_part_content_get(layout, PART_APP_GRID_CONTENT);
261 LOGE("[FAILED][elm_object_part_content_get]");
266 dst_idx = elm_gengrid_item_index_get(rel_it);
268 if ((s_info.src_grid == app_grid && s_info.src_idx > dst_idx)
269 || (s_info.src_grid != app_grid)) {
270 if (!(result = elm_gengrid_item_insert_before(app_grid, s_info.gic,
271 (container = app_grid_item_pack(app_grid, item)), rel_it, NULL, NULL))) {
272 LOGE("[FAILED][elm_gengrid_item_insert_before]");
273 evas_object_del(container);
276 } else if (s_info.src_grid == app_grid && s_info.src_idx < dst_idx) {
277 if (!(result = elm_gengrid_item_insert_after(app_grid, s_info.gic,
278 (container = app_grid_item_pack(app_grid, item)), rel_it, NULL, NULL))) {
279 LOGE("[FAILED][elm_gengrid_item_insert_before]");
284 if (!(result = elm_gengrid_item_append(app_grid, s_info.gic,
285 (container = app_grid_item_pack(app_grid, item)), NULL, NULL))) {
286 LOGE("[FAILED][elm_gengrid_item_append]");
291 evas_object_show(item);
295 HAPI Evas_Object *app_grid_item_pack(Evas_Object *p, Evas_Object *c)
297 Evas_Object *container = NULL;
299 if (!p) { /*When c is null it is not a big problem...it creates then empty gengrid item */
300 LOGD("[ERR][INVALID_PARAM]['p'='%p']", p);
304 /*This items will be removed when gengrid items will be deleted.
305 It was checked in EVAS_CALLBACK_DEL function. */
306 container = __app_grid_create_item_container(home_screen_get_win());
308 LOGE("[FAILED][container=NULL]");
313 elm_object_part_content_set(container, PART_APP_GRID_ITEM, c);
318 HAPI void app_grid_unpack_item(Elm_Object_Item *item)
320 Evas_Object *container = NULL;
323 LOGE("[INVALID_PARAM][item=NULL]");
327 container = elm_object_item_part_content_get(item, GRID_CONTENT);
329 LOGE("[FAILED][elm_object_item_part_content_get]");
333 elm_object_part_content_unset(container, PART_APP_GRID_ITEM);
336 HAPI Eina_Bool app_grid_get_item_content(Elm_Object_Item *item, Evas_Object **icon,
339 Evas_Object *ic = NULL;
340 Evas_Object *container = NULL;
343 LOGE("[INVALID_PARAM][item='%p']", item);
347 container = elm_object_item_part_content_get(item, GRID_CONTENT);
349 LOGE("[FAILED][elm_object_item_part_content_get]");
353 ic = elm_object_part_content_get(container, PART_APP_GRID_ITEM);
355 LOGE("[FAILED][eina_list_data_get]");
363 *data = evas_object_data_get(ic, KEY_ICON_DATA);
365 LOGE("[FAILED][evas_object_data_get]");
366 /*eina_list_free(box_content);*/
373 static Evas_Event_Flags __app_grid_icon_move(void *data, void *event_info)
375 Elm_Gesture_Momentum_Info *pos_info = event_info;
377 if(s_info.repositioned_icon == NULL)
378 return EVAS_EVENT_FLAG_NONE;
380 evas_object_move(s_info.repositioned_icon, pos_info->x2 - s_info.dx, pos_info->y2 - s_info.dy);
382 if (folder_panel_is_folder_visible()) {
383 LOGD("Folder is visible");
384 if ((pos_info->y2 <= s_info.f_y || pos_info->y2 >= s_info.f_y + s_info.f_h) &&
385 !s_info.outside_folder_timer) {
387 LOGD("Icon is outside folder");
388 s_info.outside_folder_timer = ecore_timer_add(1.0, __app_grid_close_folder_cb, NULL);
389 if (!s_info.outside_folder_timer) {
390 LOGE("[FAILED][timer=NULL]");
391 return EVAS_EVENT_FLAG_ON_HOLD;
393 } else if (pos_info->y2 >= s_info.f_y && pos_info->y2 <= s_info.f_y + s_info.f_h) {
394 LOGD("Icons position is on folder");
395 ecore_timer_del(s_info.outside_folder_timer);
396 s_info.outside_folder_timer = NULL;
400 return EVAS_EVENT_FLAG_NONE;
403 static Eina_Bool __app_grid_icon_move_cb_set(void *data)
405 LOGD("Set icon move cb");
408 ret = home_screen_gesture_cb_set(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_MOVE,
409 __app_grid_icon_move, NULL);
410 ret |= home_screen_gesture_cb_set(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_END,
411 __app_grid_icon_move_end, NULL);
412 ret |= home_screen_gesture_cb_set(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_ABORT,
413 __app_grid_icon_move_end, NULL);
416 LOGE("Can not set icon move callbacks");
423 static Eina_Bool __app_grid_icon_move_cb_del(void *data)
425 LOGD("Delete icon move cb");
428 ret = home_screen_gesture_cb_unset(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_MOVE,
429 __app_grid_icon_move, NULL);
430 ret |= home_screen_gesture_cb_unset(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_END,
431 __app_grid_icon_move_end, NULL);
432 ret |= home_screen_gesture_cb_unset(ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_ABORT,
433 __app_grid_icon_move_end, NULL);
436 LOGE("Can not unset callbacks");
438 return ECORE_CALLBACK_CANCEL;
441 static Evas_Event_Flags __app_grid_icon_move_end(void *data, void *event_info)
443 Elm_Gesture_Momentum_Info *pos_info = event_info;
444 LOGD("Drag end at: x,y=<%d,%d>", pos_info->x2, pos_info->y2);
447 if(s_info.repositioned_icon != NULL) {
448 __app_grid_icon_drop(NULL, s_info.src_grid, pos_info->x2,
449 pos_info->y2, ELM_XDND_ACTION_UNKNOWN);
450 __app_grid_drag_done(NULL, NULL);
453 /* quickfix: idler adds delay so cb func might be deleted after it is finished
454 * removing cb inside its body causes memory errors
456 ecore_idler_add(__app_grid_icon_move_cb_del, NULL);
458 return EVAS_EVENT_FLAG_NONE;
461 /*=====================GENGRID CALLBACKS IMPLEMENTATION===========================================*/
462 static void __app_grid_item_longpressed_cb(void *data, Evas_Object *obj, void *ei)
464 Elm_Object_Item *it = (Elm_Object_Item *)ei;
465 Evas_Coord x, y, w, h, m_x, m_y;
466 Evas_Object *icon_layout = NULL;
467 Evas_Object *icon = NULL;
468 Tree_node_t *icon_node = NULL;
469 homescreen_view_t view_type = HOMESCREEN_VIEW_UNKNOWN;
471 view_type = home_screen_get_view_type();
473 if (view_type != HOMESCREEN_VIEW_ALL_APPS &&
474 view_type != HOMESCREEN_VIEW_ALL_APPS_EDIT)
477 if (!it || !app_grid_get_item_content(it, &icon_layout, NULL)) {
478 LOGE("[FAILED][app_grid_item_content_get]");
482 if (!evas_object_data_get(icon_layout, KEY_IS_REPOSITIONABLE))
486 LOGE("[FAILED][icon_layout=NULL]");
490 if (view_type == HOMESCREEN_VIEW_ALL_APPS)
491 home_screen_set_view_type(HOMESCREEN_VIEW_ALL_APPS_EDIT);
493 icon = elm_object_part_content_get(icon_layout, PART_ICON_CONTENT);
495 LOGE("[FAILED][icon=NULL]");
499 icon_node = evas_object_data_get(icon_layout, KEY_ICON_DATA);
501 LOGE("[FAILED][icon_node=NULL]");
505 /*check if the repositioned item is from a folder.
506 It is necessary for removing item from the folder.*/
507 if (icon_node->parent && icon_node->parent->parent && icon_node->parent->parent->data
508 && icon_node->parent->parent->data->type == APP_ITEM_FOLDER) {
509 s_info.opened_folder_node = icon_node->parent->parent;
510 folder_panel_get_folder_geometry(&s_info.f_x, &s_info.f_y, &s_info.f_w, &s_info.f_h);
513 evas_object_geometry_get(icon, &x, &y, &w, &h);
514 evas_pointer_output_xy_get(evas_object_evas_get(obj), &m_x, &m_y);
515 s_info.dx = abs(m_x - x);
516 s_info.dy = abs(m_y - y);
518 /*check if user perform longpress action on icon or on item.
519 (item is a container for icon..is bigger because it must have place also for icon name)*/
520 if ((m_x >= x && m_x <= x+w) && (m_y >= y && m_y <= y + h)) {
521 s_info.repositioned_icon_layout = icon_layout;
522 s_info.repositioned_icon = icon;
523 s_info.repositioned_item = it;
524 s_info.repositioned_node = icon_node;
525 s_info.src_grid = obj;
526 s_info.src_idx = elm_gengrid_item_index_get(s_info.repositioned_item);
527 s_info.is_dnd_on = true;
529 app_grid_unpack_item(it);
531 if (__app_grid_icon_move_cb_set(NULL)) {
532 LOGE("Gesture cb set failed");
534 __app_grid_icon_move_cb_del(NULL);
537 evas_object_data_set(icon, KEY_REPOSITION_DATA, icon_layout);
538 /*This is necessary for hide only box content in grid*/
539 elm_object_part_content_unset(icon_layout, PART_ICON_CONTENT);
540 evas_object_hide(icon_layout);
541 all_apps_set_scrolling_blocked_state(true);
542 folder_panel_enable_entry(false);
546 static char *__app_grid_get_text(void *data, Evas_Object *obj, const char *part)
551 static Evas_Object *__app_grid_get_content(void *data, Evas_Object *obj, const char *part)
554 LOGE("[INVALID_PARAM][data='%p']", data);
558 if (!strcmp(GRID_CONTENT, part))
559 return (Evas_Object *) data;
564 static Eina_Bool __app_grid_get_state(void *data, Evas_Object *obj, const char *part)
569 static void __app_grid_del_content(void *data, Evas_Object *obj)
571 LOGD("DELETING : ", evas_object_type_get(obj));
575 static void __app_grid_resize_cb(void *data, Evas *e, Evas_Object *obj, void *ei)
577 int w = -1, h = -1, item_w = -1, item_h = -1;
578 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
580 if ((app_grid_type_t)data == APP_GRID_TYPE_ALL_APPS) {
583 } else if ((app_grid_type_t)data == APP_GRID_TYPE_FOLDER) {
584 item_w = (int)(w/FOLDER_COL_APPS - FOLDER_ITEM_MARGIN*home_screen_get_root_width());
585 item_h = h/FOLDER_ROW_APPS;
588 elm_gengrid_item_size_set(obj, item_w, item_h);
591 /*=========================== MOUSE HANDLERS =====================================================*/
592 static Eina_Bool __app_grid_mouse_up_cb(void *data, int type, void *event)
594 home_screen_set_indice_state(INDICE_OFF);
595 return ECORE_CALLBACK_RENEW;
598 static Eina_Bool _app_grid_mouse_move_cb(void *data, int type, void *event)
600 if (s_info.is_dnd_on) {
601 Evas_Object *scroller = (Evas_Object *) data;
602 Ecore_Event_Mouse_Move *move = event;
603 __app_grid_check_page_change(scroller, move->x, move->y);
606 return ECORE_CALLBACK_RENEW;
609 /*========================= PRIVATE FUNCTIONS ====================================================*/
610 static bool __app_grid_fill(Evas_Object *grid, Tree_node_t *data)
612 Evas_Object *icon = NULL, *box = NULL;
613 app_item_t *item = NULL;
614 Tree_node_t *it = NULL;
616 if (!data || !grid) {
617 LOGE("[INVALID_PARAM][grid='%p'][data='%p']", grid, data);
621 TREE_NODE_FOREACH(data, it) {
624 LOGE("[FAILED][item=%p", item);
628 if (!item->exec || !item->icon || !item->label || !item->appid) {
629 LOGE("[FAILED][exec='%p'][icon='%p'][label='%p'][appid='%p']",
630 item->exec, item->label, item->icon, item->appid);
634 LOGI("add item: [%s]", item->label);
636 if (item->type == APP_ITEM_ICON) {
637 icon = app_icon_create(it, APP_ICON_TYPE_APP);
638 } else if (item->type == APP_ITEM_FOLDER) {
639 folder_panel_create(it);
640 app_icon_update_folder_icon(it);
645 LOGE("[FAILED][app_icon_create]");
649 if (!(item->grid_item = elm_gengrid_item_append(grid, s_info.gic,
650 (box = app_grid_item_pack(grid, icon)), NULL, NULL))) {
651 LOGE("Failed to append an item!");
652 evas_object_del(box);
653 if (!box) {/*app_grid_item_pack had failed so the icon is still allocated:*/
654 app_icon_destroy(icon);
665 static Evas_Object *__app_grid_create_ly(Evas_Object *parent)
667 Evas_Object *ly = NULL;
670 LOGE("[INVALID_PARAM][parent='%p']", parent);
674 ly = elm_layout_add(parent);
676 LOGE("[FAILED][elm_layout_add]");
680 if (!elm_layout_file_set(ly, util_get_res_file_path(EDJE_DIR"/app_grid.edj"), GROUP_APP_GRID)) {
681 LOGE("[FAILED][elm_layout_file_set][%s]", util_get_res_file_path(EDJE_DIR"/app_grid.edj"));
686 evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
687 evas_object_size_hint_align_set(ly, EVAS_HINT_FILL, EVAS_HINT_FILL);
688 evas_object_show(ly);
693 void app_grid_set_view_mode(Evas_Object *app_grid, homescreen_view_t view)
696 LOGE("[INVALID_PARAM]");
701 case HOMESCREEN_VIEW_ALL_APPS:
702 elm_object_signal_emit(app_grid, SIGNAL_CHOOSE_MODE_OFF, SIGNAL_SOURCE);
703 elm_object_signal_emit(app_grid, SIGNAL_EDIT_MODE_OFF, SIGNAL_SOURCE);
704 __app_grid_resize(app_grid, s_info.w, s_info.h);
706 case HOMESCREEN_VIEW_ALL_APPS_EDIT:
707 elm_object_signal_emit(app_grid, SIGNAL_CHOOSE_MODE_OFF, SIGNAL_SOURCE);
708 elm_object_signal_emit(app_grid, SIGNAL_EDIT_MODE_ON, SIGNAL_SOURCE);
709 __app_grid_resize(app_grid, EDIT_MODE_SCALE*s_info.w, EDIT_MODE_SCALE*s_info.h);
711 case HOMESCREEN_VIEW_ALL_APPS_CHOOSE:
712 elm_object_signal_emit(app_grid, SIGNAL_EDIT_MODE_OFF, SIGNAL_SOURCE);
713 elm_object_signal_emit(app_grid, SIGNAL_CHOOSE_MODE_ON, SIGNAL_SOURCE);
714 __app_grid_resize(app_grid, CHOOSE_MODE_SCALE*s_info.w, CHOOSE_MODE_SCALE*s_info.h);
717 LOGE("[FAILED][type='%d']", view);
722 static bool __app_grid_resize(Evas_Object *app_grid, Evas_Coord new_w, Evas_Coord new_h)
724 Evas_Object *gengrid = NULL;
726 Evas_Coord new_item_w = new_w/APP_COLS;
727 Evas_Coord new_item_h = new_h/APP_ROWS;
730 LOGE("[INVALID_PARAM][app_grid='%p']", app_grid);
734 gengrid = elm_object_part_content_get(app_grid, PART_APP_GRID_CONTENT);
736 LOGE("[FAILED][elm_object_part_content_get]");
740 if (new_item_w < 0 || new_item_h < 0) {
741 LOGE("[INVALID_SIZE]");
745 /*elm_gengrid_item_size_set(gengrid, new_item_w, new_item_h);*/
750 static Eina_Bool __app_grid_change_page_cb(void *data)
752 LOGI("__app_grid_change_page_cb");
753 change_page_data_t *ch_page_data = (change_page_data_t *) data;
754 Evas_Object *parent = NULL;
756 s_info.change_page_timer = NULL;
759 LOGE("[INVALID_PARAM][ch_page_data='%p']", ch_page_data);
760 return ECORE_CALLBACK_CANCEL;
761 } else if (!ch_page_data->parent) {
762 LOGE("[INVALID_PARAM][ch_page_data->parent='%p']", ch_page_data->parent);
763 return ECORE_CALLBACK_CANCEL;
766 parent = ch_page_data->parent;
768 if (ch_page_data->action == NEXT_PAGE_CB) {
769 LOGI("next_page_signal");
770 elm_object_signal_emit(parent, SIGNAL_NEXT_PAGE_CHANGE, SIGNAL_SOURCE);
773 if (ch_page_data->action == PREV_PAGE_CB) {
774 LOGI("prev_page_signal");
775 elm_object_signal_emit(parent, SIGNAL_PREV_PAGE_CHANGE, SIGNAL_SOURCE);
778 return ECORE_CALLBACK_CANCEL;
781 static void __app_grid_check_page_change(Evas_Object *scroller, int x, int y)
784 LOGE("[INVALID_PARAM][scroller='%p']", scroller);
788 s_info.cp_data.parent = scroller;
789 home_screen_set_indice_state(INDICE_OFF);
791 if (x < CHANGE_PAGE_RIGHT_AREA * home_screen_get_root_width() &&
792 x > CHANGE_PAGE_LEFT_AREA * home_screen_get_root_width() &&
793 s_info.change_page_timer) {
794 ecore_timer_del(s_info.change_page_timer);
795 s_info.change_page_timer = NULL;
799 if (x >= CHANGE_PAGE_RIGHT_AREA * home_screen_get_root_width()) {
800 home_screen_set_indice_state(INDICE_NEXT_PAGE_ON);
801 s_info.cp_data.action = NEXT_PAGE_CB;
804 if (x <= CHANGE_PAGE_LEFT_AREA * home_screen_get_root_width()) {
805 home_screen_set_indice_state(INDICE_PREV_PAGE_ON);
806 s_info.cp_data.action = PREV_PAGE_CB;
809 if (!s_info.change_page_timer) {
810 s_info.change_page_timer = ecore_timer_add(CHANGE_PAGE_TIMER, __app_grid_change_page_cb,
811 (void *) &s_info.cp_data);
815 static Evas_Object *__app_grid_get_icon_container_ptr(Elm_Object_Item *it)
817 Evas_Object *container = NULL;
820 LOGE("[INVALID_PARAM][it='%p']", it);
824 container = elm_object_item_part_content_get(it, GRID_CONTENT);
828 static void __app_grid_clear_reposition_structure(void)
830 s_info.destination_folder = NULL;
831 s_info.repositioned_icon_layout = NULL;
832 s_info.repositioned_item = NULL;
833 s_info.repositioned_icon = NULL;
834 s_info.repositioned_node = NULL;
835 s_info.opened_folder_node = NULL;
836 s_info.src_grid = NULL;
838 s_info.is_dnd_on = false;
845 if (s_info.outside_folder_timer) {
846 ecore_timer_del(s_info.outside_folder_timer);
847 s_info.outside_folder_timer = NULL;
850 if (s_info.change_page_timer) {
851 ecore_timer_del(s_info.change_page_timer);
852 s_info.change_page_timer = NULL;
856 static Eina_Bool __app_grid_close_folder_cb(void *data)
858 data_model_detach_from_folder(s_info.opened_folder_node, s_info.repositioned_node);
859 folder_panel_close_folder();
863 static Evas_Object *__app_grid_create_item_container(Evas_Object *parent)
865 Evas_Object *container = NULL;
868 LOGE("[INVALID_PARAM]");
872 container = elm_layout_add(parent);
874 if (!elm_layout_file_set(container, util_get_res_file_path(EDJE_DIR"/app_grid.edj"), GROUP_APP_GRID_ITEM_CONTAINER)) {
875 LOGE("[FAILED][elm_layout_file_set][%s]", util_get_res_file_path(EDJE_DIR"/app_grid.edj"));
876 evas_object_del(container);
880 evas_object_size_hint_weight_set(container, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
881 evas_object_show(container);
885 /*=============================== DND FUNCTIONS ==================================================*/
887 static void __app_grid_return_to_origin_pos(void)
889 Evas_Object *container = NULL;
891 if (!s_info.repositioned_item || !s_info.repositioned_icon_layout) {
892 LOGE("[FAILED][repositioned_item='%p'][repositioned_icon='%p']",
893 s_info.repositioned_item, s_info.repositioned_icon_layout);
897 container = __app_grid_get_icon_container_ptr(s_info.repositioned_item);
899 LOGE("[FAILED][__app_grid_get_icon_container_ptr]");
903 elm_object_part_content_set(container, PART_APP_GRID_ITEM, s_info.repositioned_icon_layout);
904 elm_object_part_content_set(s_info.repositioned_icon_layout,
905 PART_ICON_CONTENT, s_info.repositioned_icon);
906 evas_object_show(s_info.repositioned_icon_layout);
909 static void __app_grid_icon_drop(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y,
910 Elm_Xdnd_Action action)
912 static Elm_Object_Item *it = NULL;
913 Evas_Object *icon = NULL;
914 Evas_Object *old_icon = NULL;
915 Elm_Object_Item *old_it = it;
916 Tree_node_t *destination_icon_data = NULL;
918 it = elm_gengrid_at_xy_item_get(obj, x, y, NULL, NULL);
920 app_grid_get_item_content(old_it, &old_icon, NULL);
921 app_grid_get_item_content(it, &icon, &destination_icon_data);
923 if (!s_info.repositioned_node || !s_info.repositioned_node->data) {
924 LOGE("[INVALID_DATA]");
929 elm_object_signal_emit(old_icon, SIGNAL_UNHIGHLIGHT_FOLDER, SIGNAL_SOURCE);
930 /*function not be invoked when s_info.repositioned_node == NULL;*/
931 if (s_info.repositioned_node->data->type == APP_ITEM_FOLDER ||
932 folder_panel_get_items_count(destination_icon_data) >= FOLDER_MAX_ITEMS) {
933 elm_object_signal_emit(icon, SIGNAL_HIGHLIGHT_IMPOSSIBLE_FOLDER, SIGNAL_SOURCE);
935 elm_object_signal_emit(icon, SIGNAL_HIGHLIGHT_FOLDER, SIGNAL_SOURCE);
939 if (destination_icon_data && destination_icon_data->data->type == APP_ITEM_FOLDER) {
940 s_info.destination_folder = destination_icon_data;
942 s_info.destination_folder = NULL;
946 static void __app_grid_drag_done(void *data, Evas_Object *obj)
948 Tree_node_t *folder = s_info.destination_folder;
949 Tree_node_t *item = s_info.repositioned_node;
950 Tree_node_t *src_folder = s_info.opened_folder_node;
952 char trbuf[PATH_MAX] = {0, };
954 /*Check if folder has empty space*/
955 if (item && folder && folder_panel_get_items_count(folder) < FOLDER_MAX_ITEMS
956 && item->data->type != APP_ITEM_FOLDER) {
957 home_screen_mvc_drag_item_to_folder_cb(item, folder);
958 evas_object_hide(s_info.repositioned_icon);
959 } else if (item && folder && folder_panel_get_items_count(folder) >= FOLDER_MAX_ITEMS) {
960 popup_data_t *p_data = popup_create_data();
962 LOGE("[FAILED][failed to create popup data]");
966 snprintf(trbuf, sizeof(trbuf), _("IDS_HS_TPOP_MAXIMUM_NUMBER_OF_APPLICATIONS_IN_FOLDER_HPD_REACHED"),
969 p_data->type = POPUP_INFO;
970 p_data->popup_title_text = NULL;
971 p_data->popup_content_text = strdup(trbuf);
972 p_data->popup_confirm_text = NULL;
973 p_data->popup_cancel_text = NULL;
974 p_data->orientation = ELM_POPUP_ORIENT_CENTER;
975 p_data->visible_time = 1.5;
977 popup_show(p_data, NULL, NULL, NULL);
979 __app_grid_return_to_origin_pos();
980 } else if (item && src_folder && !folder_panel_is_folder_visible()) {
981 home_screen_mvc_drag_item_from_folder_cb();
982 elm_object_part_content_set(s_info.repositioned_icon_layout, PART_ICON_CONTENT,
983 s_info.repositioned_icon);
984 app_icon_set_view_mode(s_info.repositioned_icon_layout, home_screen_get_view_type(), false);
986 __app_grid_return_to_origin_pos();
989 if (folder && folder->data->layout)
990 elm_object_signal_emit(folder->data->layout, SIGNAL_UNHIGHLIGHT_FOLDER, SIGNAL_SOURCE);
992 __app_grid_clear_reposition_structure();
993 all_apps_set_scrolling_blocked_state(false);
994 folder_panel_enable_entry(true);