The source code moved from the SPIN with license changed to Flora 1.1
[apps/native/home/homescreen-efl.git] / src / folder_panel.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
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
7  *
8  * http://floralicense.org/license/
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
19 #include "folder_panel.h"
20 #include "homescreen-efl.h"
21 #include "util.h"
22 #include "page_scroller.h"
23 #include "app_icon.h"
24 #include "app_grid.h"
25 #include "layout.h"
26 #include "option_menu.h"
27 #include "tree.h"
28 #include "data_model.h"
29 #include "all_apps.h"
30
31 static struct
32 {
33         Evas_Object *opened_folder_window;
34         Evas_Object *opened_folder_popup;
35         Elm_Theme *folder_entry_theme;
36         app_item_t *folder_item;
37         app_item_t *folder_item_add;
38         Tree_node_t *destination_folder;
39         bool click_ignore;
40         bool is_opened;
41         bool entry_activated;
42         bool opened_folder_name_is_empty;
43         bool opened_folder_entrychange_cb_ignore;
44 } s_info = {
45         .opened_folder_window = NULL,
46         .opened_folder_popup = NULL,
47         .folder_entry_theme = NULL,
48         .folder_item = NULL,
49         .folder_item_add = NULL,
50         .destination_folder = NULL,
51         .click_ignore = false,
52         .is_opened = false,
53         .entry_activated = false,
54         .opened_folder_name_is_empty = true,
55         .opened_folder_entrychange_cb_ignore = true
56 };
57
58
59 static void __folder_panel_create_folder_window_layout_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
60 static void __folder_window_destroy_signal_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
61 static bool __folder_panel_detach_grid_items(Tree_node_t *parent, Tree_node_t *item, void *data);
62 static void __folder_panel_name_set_cb(void *data, Evas_Object *obj, void *event_info);
63 static bool __folder_panel_get_items_count(Tree_node_t *parent, Tree_node_t *item, void *count);
64 /*frees folder UI data related to opened window:*/
65 static void __folder_panel_free_popup_data(folder_data_t *folder_data);
66
67 static Evas_Object* __folder_panel_create_icon(Tree_node_t *new_folder);
68 static Evas_Object *__folder_panel_create_scroller(Evas_Object *folder_window_layout);
69 static bool __folder_panel_create_layout(Evas_Object *parent, app_item_t *folder, bool keypad_show);
70 static bool __folder_panel_fill(Evas_Object *folder_window_layout, Evas_Object *folder_page_scroller,app_item_t *folder);
71 static bool __folder_panel_set_current_view_state(Tree_node_t *parent, Tree_node_t *item, void *data);
72 static bool __folder_panel_show_checkbox(Tree_node_t *parent, Tree_node_t *leaf, void *data);
73 static bool __folder_panel_get_checked_icons(Tree_node_t *parent, Tree_node_t *leaf, void *data);
74 static Evas_Object *__folder_panel_create_add_icon(app_item_t *folder);
75 static Evas_Object *__folder_panel_create_popup(Evas_Object *parent, app_item_t *item);
76
77 static Evas_Object *__folder_panel_create_entry(Evas_Object *parent, const char *default_text);
78 static void __folder_panel_entry_activated_cb(void *data, Evas_Object *obj, void *ei);
79 static void __folder_panel_entry_deactivated_cb(void *data, Evas_Object *obj, void *ei);
80 static void __folder_panel_entry_changed_cb(void *data, Evas_Object *obj, void *ei);
81 static void __folder_panel_entry_clicked_cb(void *data, Evas_Object *obj, void *ei);
82 static void __folder_panel_entry_clear_button_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
83
84 static void __folder_panel_item_add_to_folder_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
85 static void __folder_panel_print_labels(Tree_node_t *folder_tree);
86 static void __folder_panel_close_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
87
88 /*========================================== PUBLIC FUNCTIONS IMPLEMENTATION =============================================*/
89 HAPI void folder_panel_init_module(void)
90 {
91         if (!s_info.folder_entry_theme) {
92                 s_info.folder_entry_theme = elm_theme_new();
93                 if (!s_info.folder_entry_theme) {
94                         LOGE("Failed to create theme");
95                         return;
96                 }
97
98                 elm_theme_ref_set(s_info.folder_entry_theme, NULL);
99                 elm_theme_extension_add(s_info.folder_entry_theme, EDJE_DIR"/folder_entry.edj");
100         }
101 }
102
103 HAPI void folder_panel_deinit_module(void)
104 {
105         elm_theme_free(s_info.folder_entry_theme);
106         s_info.folder_entry_theme = NULL;
107 }
108
109 HAPI app_item_t *folder_panel_create(Tree_node_t *data)
110 {
111         LOGI("");
112         Evas_Object *folder_icon_layout = NULL;
113         folder_data_t *f_data = NULL;
114
115         f_data = (folder_data_t *) calloc(1, sizeof(folder_data_t));
116         if (!f_data) {
117                 LOGE("Failed to create either data: %d", f_data);
118                 return NULL;
119         }
120
121         folder_icon_layout = __folder_panel_create_icon(data);
122         if (!folder_icon_layout) {
123                 LOGE("Failed to create folder");
124                 free(f_data);
125                 f_data = NULL;
126         }
127
128         data->data->layout = folder_icon_layout;
129         data->data->data = f_data;
130
131         __folder_panel_print_labels(data);
132
133         return data->data;
134 }
135
136 HAPI void folder_panel_set_click_ignore_state(bool ignore)
137 {
138         s_info.click_ignore = ignore;
139 }
140
141 HAPI void folder_panel_enable_entry(bool state)
142 {
143         if (s_info.opened_folder_popup) {
144                 if (state) {
145                         elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_ENTRY_BLOCK_OFF, SIGNAL_SOURCE);
146                 } else {
147                         elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_ENTRY_BLOCK_ON, SIGNAL_SOURCE);
148                 }
149         }
150 }
151
152 HAPI Elm_Object_Item * folder_panel_attach_to_grid(Evas_Object *icon, folder_data_t *folder_data)
153 {
154         Evas_Object *grid_layout = NULL;
155         Evas_Object *grid = NULL;
156
157         if (!icon || !folder_data) {
158                 LOGE("icon: %d folder_data: %d", icon, folder_data);
159                 return NULL;
160         }
161
162         if (!folder_data->folder_scroller)
163                 return NULL;
164
165         grid_layout = page_scroller_get_page(folder_data->folder_scroller, 0);
166         grid = elm_object_part_content_get(grid_layout, PART_APP_GRID_CONTENT);
167
168         /*the last item is "+:"*/
169         return app_grid_insert_item_relative(grid_layout, icon, elm_gengrid_last_item_get(grid));
170 }
171
172 HAPI bool folder_panel_open_folder(app_item_t *folder, bool keypad_show)
173 {
174         LOGI("");
175         s_info.is_opened = true;
176         s_info.opened_folder_entrychange_cb_ignore = true;
177
178         return __folder_panel_create_layout(home_screen_get_win(), folder, keypad_show);
179 }
180
181 HAPI void folder_panel_close_folder(void)
182 {
183         s_info.is_opened = false;
184         elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_FOLDER_PANEL_CLOSE, SIGNAL_SOURCE);
185         elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_FOLDER_UNNAMED_TEXT_HIDE, SIGNAL_SOURCE);
186         elm_object_signal_callback_add(s_info.opened_folder_popup, SIGNAL_FOLDER_ANIM_DONE, SIGNAL_SOURCE,
187                 __folder_panel_close_cb, NULL);
188
189 }
190
191 HAPI void folder_panel_cancel_add_icon(void)
192 {
193         if (s_info.folder_item_add)
194                 app_icon_set_color(s_info.folder_item_add->layout, 255, 255, 255, 255);
195         s_info.folder_item_add = NULL;
196         s_info.destination_folder = NULL;
197 }
198
199 HAPI bool folder_panel_is_folder_visible(void)
200 {
201         return s_info.is_opened;
202 }
203
204 HAPI bool folder_panel_set_content_checked(Tree_node_t *node)
205 {
206         bool all_checked = true;
207         tree_in_depth_browse(node, __folder_panel_get_checked_icons, &all_checked);
208         return all_checked;
209 }
210
211 HAPI Tree_node_t *folder_panel_get_opened_folder_node(void)
212 {
213         return s_info.destination_folder;
214 }
215
216 HAPI const app_item_t *folder_panel_get_opened_folder_item(void)
217 {
218         return s_info.folder_item;
219 }
220
221 HAPI int folder_panel_get_items_count(Tree_node_t *folder)
222 {
223         int i = 0;
224         data_model_iterate_pages(folder, NULL, __folder_panel_get_items_count, &i);
225
226         return i;
227 }
228
229 HAPI void folder_panel_remove_empty_folder(Tree_node_t *folder)
230 {
231         if (!folder) {
232                 LOGE("[INVALID_PARAM][folder=NULL]");
233                 return;
234         }
235
236         app_icon_remove(folder->data->layout);
237         folder->data->layout = NULL;
238 }
239
240 HAPI void folder_panel_get_folder_geometry(int *x, int *y, int *w, int *h)
241 {
242         if (!s_info.opened_folder_popup) {
243                 if (x)
244                         *x = -1;
245
246                 if (y)
247                         *y = -1;
248
249                 if (w)
250                         *w = -1;
251
252                 if (h)
253                         *h = -1;
254         }
255
256         evas_object_geometry_get(s_info.opened_folder_popup, x, y, w, h);
257 }
258
259 HAPI void folder_panel_hide_input_panel(void)
260 {
261         Evas_Object *entry = NULL;
262
263         if (!s_info.opened_folder_popup)
264                 return;
265
266         entry = elm_object_part_content_get(s_info.opened_folder_popup, PART_FOLDER_NAME);
267         if (!entry) {
268                 LOGE("[FAILED][entry=NULL]");
269                 return;
270         }
271
272         elm_entry_input_panel_hide(entry);
273 }
274 /*====================================== PRIVATE FUNCTIONS IMPLEMENTATION =================================================*/
275 static bool __folder_panel_get_items_count(Tree_node_t *parent, Tree_node_t *item, void *count)
276 {
277         (*(int *)count)++;
278
279         return true;
280 }
281
282 static void __folder_panel_create_folder_window_layout_cb(void *data, Evas_Object *obj,
283         const char *emission, const char *source)
284 {
285         bool keypad_show = false;
286
287         if (s_info.click_ignore && s_info.destination_folder) { /*don't open a folder when adding items to it*/
288                 LOGI("Click ignore");
289                 return;
290         }
291
292         s_info.folder_item = (app_item_t*) data;
293         if (!s_info.folder_item) {
294                 LOGE("Failed to get folder item");
295                 return;
296         }
297
298         if (!emission && !source)
299                 keypad_show = true;
300
301         if (!folder_panel_open_folder(s_info.folder_item, keypad_show)) {
302                 LOGE("Failed to open folder");
303                 return;
304         }
305
306         app_icon_highlight_folder_icon(s_info.folder_item->layout, FOLDER_ICON_FRAME_POSSIBLE);
307 }
308
309 static void __folder_window_destroy_signal_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
310 {
311         folder_panel_close_folder();
312 }
313
314 static void __folder_panel_name_set_cb(void *data, Evas_Object *obj, void *event_info)
315 {
316         LOGI("");
317         app_item_t *folder = NULL;
318         Tree_node_t *node = NULL;
319         const char *entry_text;
320         char prev_label[NAME_MAX];
321
322         folder = (app_item_t*) data;
323         if (!data) {
324                 LOGE("invalid cb parameter : data is NULL");
325                 return;
326         }
327
328         strncpy(prev_label, folder->label, NAME_MAX - sizeof('\0'));
329
330         if (elm_entry_is_empty(obj) || s_info.opened_folder_name_is_empty) {
331                 free((void *)folder->label);
332                 folder->label = strdup("");
333                 elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_FOLDER_UNNAMED_TEXT_SHOW,
334                                 SIGNAL_SOURCE);
335         } else {
336                 entry_text = elm_object_text_get(obj);
337                 if (!entry_text) {
338                         LOGE("Failed to get the text from the entry");
339                         return;
340                 }
341
342                 free((void *)folder->label);
343                 folder->label = strdup(entry_text);
344                 if (!folder->label) {
345                         LOGE("Failed to copy the text");
346                         return;
347                 }
348
349                 folder->appid = strdup(entry_text);
350                 if (!folder->appid) {
351                         LOGE("Failed to copy the text");
352                         return;
353                 }
354         }
355
356         if (folder->label &&
357                 strncasecmp(prev_label, folder->label, NAME_MAX) != 0) {
358                 app_icon_set_label(folder->layout, folder->label);
359
360                 node = (Tree_node_t*)evas_object_data_get(folder->layout, KEY_ICON_DATA);
361                 if (!node) {
362                         LOGE("node == NULL");
363                         return;
364                 }
365                 data_model_update_item(node);
366                 home_screen_mvc_update_view();
367         }
368
369         home_screen_print_tree();
370 }
371
372 static Evas_Object* __folder_panel_create_icon(Tree_node_t *new_folder)
373 {
374         Evas_Object *folder_icon_layout = app_icon_create(new_folder, APP_ICON_TYPE_FOLDER);
375         if (!folder_icon_layout) {
376                 LOGE("Failed to create folder");
377                 return NULL;
378         }
379
380         elm_object_signal_callback_add(folder_icon_layout, SIGNAL_ICON_CLICKED, SIGNAL_SOURCE, __folder_panel_create_folder_window_layout_cb, new_folder->data);
381
382         return folder_icon_layout;
383 }
384
385 static bool __folder_panel_create_layout(Evas_Object *parent, app_item_t *folder, bool keypad_show)
386 {
387         Evas_Object *entry = NULL;
388         Evas_Object *add_icon = NULL;
389
390         folder_data_t *f_data = NULL;
391         Tree_node_t *f_node = NULL;
392
393         int count = -1;
394
395         if (!parent || !folder) {
396                 LOGE("Invalid parameter");
397                 return false;
398         }
399
400         f_data = (folder_data_t *) folder->data;
401         if (!f_data) {
402                 LOGE("Failed to get folder data");
403                 return false;
404         }
405
406         s_info.opened_folder_window = elm_layout_add(parent);
407         if (!s_info.opened_folder_window) {
408                 LOGE("Failed to create folder icon layout");
409                 return false;
410         }
411
412         if (!elm_layout_file_set(s_info.opened_folder_window, EDJE_DIR"/folder.edj", GROUP_FOLDER_WINDOW)) {
413                 LOGE("Failed to load edje file for layout");
414                 evas_object_del(s_info.opened_folder_window);
415                 s_info.opened_folder_window = NULL;
416                 return false;
417         }
418
419         s_info.opened_folder_popup = __folder_panel_create_popup(parent, folder);
420         if (!s_info.opened_folder_popup) {
421                 LOGE("Failed to create folder_popup ");
422                 evas_object_del(s_info.opened_folder_window);
423                 s_info.opened_folder_window = NULL;
424                 return false;
425         }
426         evas_object_show(s_info.opened_folder_popup);
427
428         entry = __folder_panel_create_entry(s_info.opened_folder_popup, folder->label);
429         if (!entry) {
430                 LOGE("Failed to create entry");
431                 evas_object_del(s_info.opened_folder_window);
432                 evas_object_del(s_info.opened_folder_popup);
433                 s_info.opened_folder_window = NULL;
434                 s_info.opened_folder_popup = NULL;
435                 return false;
436         }
437
438         f_data->folder_scroller = __folder_panel_create_scroller(home_screen_get_win());
439         if (!f_data->folder_scroller) {
440                 LOGE("Failed to create folder layout");
441                 evas_object_del(s_info.opened_folder_window);
442                 evas_object_del(s_info.opened_folder_popup);
443                 s_info.opened_folder_window = NULL;
444                 s_info.opened_folder_popup = NULL;
445                 return false;
446         }
447         elm_object_part_content_set(s_info.opened_folder_popup, PART_FOLDER_CONTENT, f_data->folder_scroller);
448         if (!__folder_panel_fill(s_info.opened_folder_popup, f_data->folder_scroller, folder)) {
449                 LOGE("Failed to fill folder grid");
450                 evas_object_del(s_info.opened_folder_window);
451                 evas_object_del(s_info.opened_folder_popup);
452                 __folder_panel_free_popup_data(folder->data);
453                 s_info.opened_folder_window = NULL;
454                 s_info.opened_folder_popup = NULL;
455                 return false;
456         }
457
458         f_node = evas_object_data_get(folder->layout, KEY_ICON_DATA);
459         if (!f_node) {
460                 LOGE("[FAILED][f_node=NULL]");
461                 evas_object_del(s_info.opened_folder_window);
462                 evas_object_del(s_info.opened_folder_popup);
463                 __folder_panel_free_popup_data(folder->data);
464                 s_info.opened_folder_window = NULL;
465                 s_info.opened_folder_popup = NULL;
466                 return false;
467         }
468
469         count = folder_panel_get_items_count(f_node);
470         if (count < FOLDER_MAX_ITEMS) {
471                 add_icon = __folder_panel_create_add_icon(folder);
472
473                 if (!app_grid_append_item(page_scroller_get_page(f_data->folder_scroller, page_scroller_get_page_count(f_data->folder_scroller)-1), add_icon)) {
474                         LOGE("Creating folder window without \"+\"");
475                         evas_object_del(add_icon);
476                 }
477         }
478
479         evas_object_resize(s_info.opened_folder_window, FOLDER_WINDOW_W, FOLDER_WINDOW_H);
480         evas_object_move(s_info.opened_folder_window, 0, 0);
481         evas_object_show(s_info.opened_folder_window);
482
483         elm_object_signal_callback_add(s_info.opened_folder_window, SIGNAL_BG_CLICKED, SIGNAL_SOURCE, __folder_window_destroy_signal_cb, folder);
484         evas_object_smart_callback_add(entry, "focused", __folder_panel_entry_activated_cb, folder);
485         evas_object_smart_callback_add(entry, "unfocused", __folder_panel_entry_deactivated_cb, folder);
486         elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_FOLDER_PANEL_OPEN, SIGNAL_SOURCE);
487
488         return true;
489 }
490
491 static Evas_Object* __folder_panel_create_scroller(Evas_Object *folder_window_layout)
492 {
493         Evas_Object *folder_page_scroller = NULL;
494         LOGI("");
495
496         if (!folder_window_layout) {
497                 LOGE("Invalid parameter");
498                 return NULL;
499         }
500
501         folder_page_scroller = page_scroller_create(FOLDER_GRID_W_REL*home_screen_get_root_width(), FOLDER_GRID_H_REL*home_screen_get_root_height());
502         if (!folder_page_scroller) {
503                 LOGE("Failed to create folder page scroller layout");
504                 return NULL;
505         }
506
507         elm_scroller_movement_block_set(folder_page_scroller, ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL);
508         elm_scroller_movement_block_set(folder_page_scroller, ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL);
509         elm_scroller_loop_set(folder_page_scroller, EINA_FALSE, EINA_FALSE);
510
511         return folder_page_scroller;
512 }
513
514 static bool __folder_panel_detach_grid_items(Tree_node_t *parent, Tree_node_t *item, void *data)
515 {
516         if (item->data && item->data->grid_item) {
517                 app_grid_unpack_item(item->data->grid_item);
518                 elm_object_item_del(item->data->grid_item);
519                 evas_object_hide(item->data->layout);
520                 item->data->grid_item = NULL;
521
522                 return true;
523         }
524
525         return false;
526 }
527
528 static bool __folder_panel_set_current_view_state(Tree_node_t *parent, Tree_node_t *item, void *data)
529 {
530         app_icon_set_view_mode(item->data->layout, home_screen_get_view_type(), true);
531         return true;
532 }
533
534 static bool __folder_panel_show_checkbox(Tree_node_t *parent, Tree_node_t *leaf, void *data)
535 {
536         if (leaf->data->type == APP_ITEM_ICON) {
537                 if (leaf->data->is_checked)
538                         elm_object_signal_emit(leaf->data->layout, SIGNAL_CHECKBOX_SHOW_CHECKED, SIGNAL_SOURCE);
539                 else
540                         elm_object_signal_emit(leaf->data->layout, SIGNAL_CHECKBOX_SHOW_UNCHECKED, SIGNAL_SOURCE);
541         }
542         return true;
543 }
544
545 static bool __folder_panel_get_checked_icons(Tree_node_t *parent, Tree_node_t *leaf, void *data)
546 {
547         if (leaf->data->type == APP_ITEM_ICON && !leaf->data->is_checked) {
548                 *(bool *)data = false;
549                 return false;
550         }
551         return true;
552 }
553
554 static bool __folder_panel_fill(Evas_Object *folder_window_layout, Evas_Object *folder_page_scroller, app_item_t *folder)
555 {
556         folder_data_t *folder_data = NULL;
557         Tree_node_t *it;
558         Tree_node_t *folder_app_tree = NULL;
559         Evas_Object *folder_app_grid = NULL;
560         LOGI("");
561
562         if (!folder_page_scroller || !folder) {
563                 LOGE("Invalid parameter");
564                 return false;
565         }
566
567         folder_data = (folder_data_t*)folder->data;
568         if (!folder_data) {
569                 LOGE("Failed to get folder data");
570                 return false;
571         }
572
573         folder_app_tree = evas_object_data_get(folder->layout, KEY_ICON_DATA);
574         if (!folder_app_tree) {
575                 LOGE("Failed to get folder app tree");
576                 return false;
577         }
578
579         TREE_NODE_FOREACH(folder_app_tree, it) {
580                 folder_app_grid = app_grid_create(folder_page_scroller, it,
581                                 FOLDER_GRID_W_REL*home_screen_get_root_width(), FOLDER_GRID_H_REL*home_screen_get_root_height(), APP_GRID_TYPE_FOLDER);
582                 if (!folder_app_grid) {
583                         LOGE("[FAILED][app_grid_create]");
584                         return false;
585                 }
586
587                 if (!page_scroller_add_page(folder_page_scroller, folder_app_grid)) {
588                         LOGE("[FAILED][page_scroller_page_add]");
589                         evas_object_del(folder_app_grid);
590                         return false;
591                 }
592
593                 data_model_iterate(it, __folder_panel_set_current_view_state, NULL);
594         }
595
596         if (home_screen_get_view_type() == HOMESCREEN_VIEW_ALL_APPS_CHOOSE)
597                 data_model_iterate(folder_app_tree, __folder_panel_show_checkbox, NULL);
598
599         __folder_panel_print_labels(folder_app_tree);
600
601         return true;
602 }
603
604 static Evas_Object* __folder_panel_create_add_icon(app_item_t *folder)
605 {
606         Evas_Object *icon_layout = NULL;
607         Evas_Object *add_icon = NULL;
608         LOGI("");
609
610         icon_layout = util_create_edje_layout(home_screen_get_win(), EDJE_DIR"/icon.edj", GROUP_ICON_LY);
611         if (!icon_layout) {
612                 LOGE("Failed to create icon layout");
613                 return NULL;
614         }
615
616         add_icon = elm_layout_add(home_screen_get_win());
617         if (!add_icon) {
618                 LOGE("Failed to create folder icon layout");
619                 evas_object_del(icon_layout);
620                 return NULL;
621         }
622
623         if (!elm_layout_file_set(add_icon, EDJE_DIR"/folder.edj", GROUP_FOLDER_ADD_ICON)) {
624                 LOGE("Failed to load edje file for layout");
625                 evas_object_del(add_icon);
626                 evas_object_del(icon_layout);
627                 return NULL;
628         }
629
630         elm_object_part_content_set(icon_layout, PART_ICON_CONTENT, add_icon);
631         evas_object_size_hint_align_set(icon_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
632         evas_object_size_hint_weight_set(icon_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
633         evas_object_show(icon_layout);
634         evas_object_show(add_icon);
635
636         elm_object_signal_callback_add(add_icon, "mouse,clicked,1", "add_icon", __folder_panel_item_add_to_folder_cb, s_info.folder_item);
637         evas_object_data_set(icon_layout, KEY_IS_REPOSITIONABLE, (void*)false);
638
639         return icon_layout;
640 }
641
642 static Evas_Object *__folder_panel_create_popup(Evas_Object *parent, app_item_t *folder)
643 {
644         Evas_Object *folder_popup = NULL;
645         Tree_node_t *folder_app_tree = NULL;
646
647         if (!parent || !folder) {
648                 LOGE("Invalid parameters: [%p] [%p]", parent, folder);
649                 return NULL;
650         }
651
652         folder_app_tree = evas_object_data_get(folder->layout, KEY_ICON_DATA);
653         if (!folder_app_tree) {
654                 LOGE("Failed to get folder app tree");
655                 return NULL;
656         }
657
658         folder_popup = elm_layout_add(parent);
659         if (!folder_popup) {
660                 LOGE("Failed to create folder_popup ");
661                 return NULL;
662         }
663
664         if (!elm_layout_file_set(folder_popup, EDJE_DIR"/folder.edj", GROUP_FOLDER_POPUP)) {
665                 LOGE("Failed to set folder popup");
666                 evas_object_del(folder_popup);
667                 return NULL;
668         }
669
670         elm_object_part_text_set(folder_popup, PART_FOLDER_UNNAMED_TEXT, gettext("IDS_COM_HEADER_UNNAMED_FOLDER"));
671
672         evas_object_resize(folder_popup, FOLDER_POPUP_W_REL*home_screen_get_root_width(), FOLDER_3_ROW_H_REL*home_screen_get_root_height());
673
674         evas_object_move(folder_popup, FOLDER_POPUP_X_REL*home_screen_get_root_width(),
675                 FOLDER_POPUP_Y_REL*home_screen_get_root_height());
676
677         return folder_popup;
678 }
679
680 static Evas_Object *__folder_panel_create_entry(Evas_Object *parent, const char *default_text)
681 {
682         Evas_Object *entry = NULL;
683
684         if (!parent) {
685                 LOGE("Invalid parameter : parent is NULL");
686                 return NULL;
687         }
688
689         entry = elm_entry_add(parent);
690         if (!entry) {
691                 LOGE("Failed to create entry widget");
692                 return NULL;
693         }
694
695         evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
696         elm_entry_single_line_set(entry, EINA_TRUE);
697         elm_entry_scrollable_set(entry, EINA_TRUE);
698         evas_object_show(entry);
699
700         if (s_info.folder_entry_theme) {
701                 elm_object_theme_set(entry, s_info.folder_entry_theme);
702                 elm_object_style_set(entry, "default");
703         }
704
705         elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NORMAL);
706         elm_entry_input_panel_return_key_type_set(entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE);
707
708         evas_object_smart_callback_add(entry,"changed", __folder_panel_entry_changed_cb, parent);
709         evas_object_smart_callback_add(entry, "clicked",__folder_panel_entry_clicked_cb, parent);
710         elm_object_signal_callback_add(parent, SIGNAL_CLEAR_BTN_CLICKED, SIGNAL_SOURCE,
711                                 __folder_panel_entry_clear_button_clicked_cb, entry);
712
713         if (strlen(default_text) > 0) {
714                 elm_entry_entry_set(entry, default_text);
715                 s_info.opened_folder_name_is_empty = false;
716         } else {
717                 elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_FOLDER_UNNAMED_TEXT_SHOW,
718                                                 SIGNAL_SOURCE);
719                 s_info.opened_folder_name_is_empty = true;
720         }
721
722         elm_object_part_content_set(s_info.opened_folder_popup, PART_FOLDER_NAME, entry);
723
724         return entry;
725 }
726
727 static void __folder_panel_entry_activated_cb(void *data, Evas_Object *obj, void *ei)
728 {
729         app_item_t *folder = (app_item_t*) data;
730         LOGI("Entry");
731
732         if (!folder) {
733                 LOGE("Failed to get folder");
734                 return;
735         }
736
737         if (!strcmp(folder->label, "")) {
738                 elm_object_text_set(obj, "");
739                 s_info.opened_folder_name_is_empty = true;
740         }
741
742         elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_FOLDER_UNNAMED_TEXT_HIDE,
743                         SIGNAL_SOURCE);
744
745         s_info.entry_activated = true;
746         s_info.opened_folder_entrychange_cb_ignore = false;
747 }
748
749 static void __folder_panel_entry_deactivated_cb(void *data, Evas_Object *obj, void *ei)
750 {
751         const char *label = NULL;
752         label = elm_entry_entry_get(obj);
753
754         if (!label || !strcmp(label, "")) {
755                 s_info.opened_folder_name_is_empty = true;
756                 elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_FOLDER_UNNAMED_TEXT_SHOW,
757                         SIGNAL_SOURCE);
758         }
759
760         elm_object_signal_emit(s_info.opened_folder_popup, SIGNAL_CLEAR_BTN_HIDE, SIGNAL_SOURCE);
761 }
762
763 static void __folder_panel_entry_changed_cb(void *data, Evas_Object *obj, void *ei)
764 {
765         Evas_Object *folder = (Evas_Object *)data;
766         const char *entry_text = elm_object_text_get(obj);
767
768         if (s_info.opened_folder_entrychange_cb_ignore)
769                 return;
770
771         if (!entry_text || strlen(entry_text) == 0) {
772                 s_info.opened_folder_name_is_empty = true;
773                 elm_object_signal_emit(folder, SIGNAL_CLEAR_BTN_HIDE, SIGNAL_SOURCE);
774         } else {
775                 s_info.opened_folder_name_is_empty = false;
776                 elm_object_signal_emit(folder, SIGNAL_CLEAR_BTN_SHOW, SIGNAL_SOURCE);
777         }
778 }
779
780 static void __folder_panel_entry_clicked_cb(void *data, Evas_Object *obj, void *ei)
781 {
782         Evas_Object *folder_popup = (Evas_Object*) data;
783         LOGI("");
784
785         if (!folder_popup) {
786                 LOGE("Invalid data");
787                 return;
788         }
789
790         if (s_info.entry_activated) {
791                 elm_entry_cursor_end_set(obj);
792                 s_info.entry_activated = false;
793         }
794
795         if (!s_info.opened_folder_name_is_empty)
796                 elm_object_signal_emit(folder_popup, SIGNAL_CLEAR_BTN_SHOW, SIGNAL_SOURCE);
797         else
798                 elm_object_signal_emit(folder_popup, SIGNAL_CLEAR_BTN_HIDE, SIGNAL_SOURCE);
799         elm_entry_input_panel_show(obj);
800 }
801
802 static void __folder_panel_entry_clear_button_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
803 {
804         LOGI("");
805         Evas_Object *entry = NULL;
806
807         entry = (Evas_Object*) data;
808         if (!entry) {
809                 LOGE("Invalid data pointer");
810                 return;
811         }
812
813         elm_object_text_set(entry, "");
814         s_info.opened_folder_name_is_empty = true;
815         elm_object_signal_emit(obj, SIGNAL_CLEAR_BTN_HIDE, SIGNAL_SOURCE);
816 }
817
818 static void __folder_panel_item_add_to_folder_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
819 {
820         app_item_t *folder_item = NULL;
821         Tree_node_t *node = NULL;
822
823         home_screen_set_view_type(HOMESCREEN_VIEW_ALL_APPS_CHOOSE);
824         option_menu_update_on_item_selected();
825         folder_panel_close_folder();
826
827         folder_item = (app_item_t*) data;
828         if (!folder_item) {
829                 LOGE("Failed to get folder item");
830                 return;
831         }
832
833         node = evas_object_data_get(folder_item->layout, KEY_ICON_DATA);
834         if (!node) {
835                 LOGE("[FAILED][node=NULL]");
836                 return;
837         }
838         s_info.destination_folder = node;
839
840         elm_object_signal_emit(folder_item->layout, SIGNAL_CHECKBOX_CHECKED, SIGNAL_SOURCE);
841         elm_object_signal_emit(folder_item->layout, SIGNAL_CHECKBOX_SHOW_CHECKED, SIGNAL_SOURCE);
842         elm_object_signal_emit(folder_item->layout, SIGNAL_CHECKBOX_BLOCK, SIGNAL_SOURCE);
843
844         app_icon_set_color(folder_item->layout, 150, 150, 150, 150);
845         s_info.folder_item_add = folder_item;
846 }
847
848 static void __folder_panel_print_labels(Tree_node_t *folder_tree)
849 {
850         app_item_t *t = NULL;
851         Tree_node_t *page = NULL;
852         Tree_node_t *it = NULL;
853         int i=0;
854         TREE_NODE_FOREACH(folder_tree, page) {
855                 TREE_NODE_FOREACH(page, it) {
856                         t = it->data;
857                         LOGI("item %d: %s", i++, t->label);
858                 }
859         }
860 }
861
862 static void __folder_panel_free_popup_data(folder_data_t *folder_data)
863 {
864         if (!folder_data)
865                 return;
866
867         evas_object_del(folder_data->folder_scroller);
868         folder_data->folder_scroller = NULL;
869 }
870
871 static void __folder_panel_close_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
872 {
873         Tree_node_t *folder_app_tree = NULL;
874         Evas_Object *entry = NULL;
875
876         entry = elm_object_part_content_get(s_info.opened_folder_popup, PART_FOLDER_NAME);
877         elm_object_signal_callback_del(s_info.opened_folder_popup, SIGNAL_FOLDER_ANIM_DONE, SIGNAL_SOURCE, __folder_panel_close_cb);
878         __folder_panel_name_set_cb(s_info.folder_item, entry, NULL);
879
880         if (s_info.folder_item) {
881                 folder_app_tree = evas_object_data_get(s_info.folder_item->layout, KEY_ICON_DATA);
882                 if (folder_app_tree) {
883                         __folder_panel_print_labels(folder_app_tree);
884                         data_model_iterate_pages(folder_app_tree, NULL, __folder_panel_detach_grid_items, NULL);
885                 }
886
887                 app_icon_highlight_folder_icon(s_info.folder_item->layout, FOLDER_ICON_FRAME_NONE);
888                 //app_icon_set_color(s_info.folder_item->layout, 255, 255, 255, 255);
889
890                 __folder_panel_free_popup_data(s_info.folder_item->data);
891                 s_info.folder_item = NULL;
892         }
893
894         if (s_info.opened_folder_popup) {
895                 evas_object_del(s_info.opened_folder_popup);
896                 s_info.opened_folder_popup = NULL;
897         }
898         if (s_info.opened_folder_window) {
899                 evas_object_del(s_info.opened_folder_window);
900                 s_info.opened_folder_window = NULL;
901         }
902 }