0beedd98424fd78dd79e8dccf12c713325565954
[apps/native/menu-screen.git] / src / page_scroller.c
1 /*
2  * MENU-SCREEN
3  *
4  * Copyright (c) 2009-2014 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <Elementary.h>
21 #include <vconf.h>
22
23 #include "item_badge.h"
24 #include "conf.h"
25 #include "index.h"
26 #include "item.h"
27 #include "item_event.h"
28 #include "layout.h"
29 #include "list.h"
30 #include "mapbuf.h"
31 #include "menu_screen.h"
32 #include "page.h"
33 #include "page_scroller.h"
34 #include "pkgmgr.h"
35 #include "util.h"
36
37 #define BUFSZE 1024
38 #define PAGE_SCROLL_SENSITIVE 0.2
39 #define PROP_PORTRAIT_HEIGHT (PAGE_PORTRAIT_HEIGHT / BASE_HEIGHT)
40
41
42
43 static int _count_pages(Evas_Object *scroller)
44 {
45         const Eina_List *children;
46         Evas_Object *box;
47
48         box = evas_object_data_get(scroller, "box");
49         retv_if(NULL == box, 0);
50
51         children = elm_box_children_get(box);
52         return eina_list_count(children);
53 }
54
55
56
57 HAPI void page_scroller_bring_in(Evas_Object *scroller, int idx)
58 {
59         Evas_Object *index;
60         int w, h;
61
62         _D("BRING IN TO %d", idx);
63
64         evas_object_data_set(scroller, "current_idx", (void *) idx);
65
66         evas_object_geometry_get(scroller, NULL, NULL, &w, &h);
67         elm_scroller_region_bring_in(scroller, idx * w, 0, w, h);
68
69         index = evas_object_data_get(scroller, "index");
70         if (!index) {
71                 _E("cannot find index.");
72         }
73         _D("page index bring in to %d", idx);
74         index_bring_in(index, idx);
75 }
76
77
78
79 HAPI void page_scroller_show_region(Evas_Object *scroller, int idx)
80 {
81         Evas_Object *index;
82         int w, h;
83
84         evas_object_geometry_get(scroller, NULL, NULL, &w, &h);
85         elm_scroller_region_show(scroller, idx * w, 0, w, h);
86
87         index = evas_object_data_get(scroller, "index");
88         if (!index) {
89                 _E("cannot find index.");
90         }
91         _D("page index bring in to %d", idx);
92         index_bring_in(index, idx);
93 }
94
95
96
97 static void _anim_stop_cb(void *data, Evas_Object *scroller, void *event_info)
98 {
99         _D("Invoked");
100 }
101
102
103
104 static void _anim_start_cb(void *data, Evas_Object *scroller, void *event_info)
105 {
106         Evas_Coord x;
107         Evas_Coord y;
108         Evas_Coord w;
109         Evas_Coord h;
110         Evas_Object *index;
111         Elm_Object_Item *idx_it;
112
113         int idx;
114         int drag_start;
115         int previous_x;
116         int threshold;
117
118         _D("Invoked");
119
120         drag_start = (int) evas_object_data_get(scroller, "drag_start");
121         previous_x = (int) evas_object_data_get(scroller, "previous_x");
122         index = evas_object_data_get(scroller, "index");
123
124         ret_if(drag_start == 0);
125         evas_object_data_set(scroller, "drag_start", (void *) 0);
126
127         elm_scroller_region_get(scroller, &x, &y, &w, &h);
128         threshold = w * PAGE_SCROLL_SENSITIVE;
129
130         idx_it = elm_index_selected_item_get(index, 0);
131         idx = (int) elm_object_item_data_get(idx_it);
132
133         if (abs(previous_x - x) > threshold) {
134                 if (x > previous_x) idx ++;
135                 else if ((x < previous_x) && (idx != 0)) idx --;
136         }
137
138         ret_if(idx >= _count_pages(scroller) || idx < 0);
139
140         page_scroller_bring_in(scroller, idx);
141 }
142
143
144
145 static void _drag_start_cb(void *data, Evas_Object *scroller, void *event_info)
146 {
147         int previous_x;
148
149         _D("Invoked");
150
151         elm_scroller_region_get(scroller, &previous_x, NULL, NULL, NULL);
152         evas_object_data_set(scroller, "previous_x", (void *) previous_x);
153         evas_object_data_set(scroller, "drag_start", (void *) 1);
154 }
155
156
157
158 static void _drag_stop_cb(void *data, Evas_Object *scroller, void *event_info)
159 {
160         Evas_Coord x;
161         Evas_Coord w;
162         Evas_Coord y;
163         Evas_Coord h;
164         int previous_x;
165
166         _D("Invoked");
167
168         elm_scroller_region_get(scroller, &x, &y, &w, &h);
169         previous_x = (int) evas_object_data_get(scroller, "previous_x");
170         if (x == previous_x) {
171                 _D("\e[33mHold scroller (previous) %d (current) %d\e[0m", previous_x, x);
172         }
173 }
174
175
176
177 static void _scroller_register(Evas_Object *scroller)
178 {
179         evas_object_smart_callback_add(scroller, "scroll,anim,start", _anim_start_cb, NULL);
180         evas_object_smart_callback_add(scroller, "scroll,anim,stop", _anim_stop_cb, NULL);
181         evas_object_smart_callback_add(scroller, "scroll,drag,start", _drag_start_cb, NULL);
182         evas_object_smart_callback_add(scroller, "scroll,drag,stop", _drag_stop_cb, NULL);
183 }
184
185
186
187 static void _scroller_unregister(Evas_Object *scroller)
188 {
189         evas_object_smart_callback_del(scroller, "scroll,anim,start", _anim_start_cb);
190         evas_object_smart_callback_del(scroller, "scroll,anim,stop", _anim_stop_cb);
191         evas_object_smart_callback_del(scroller, "scroll,drag,start", _drag_start_cb);
192         evas_object_smart_callback_del(scroller, "scroll,drag,stop", _drag_stop_cb);
193 }
194
195
196
197 static menu_screen_error_e _find_position_by_default(Evas_Object *scroller, int *candidate_page, int *candidate_pos, void *data)
198 {
199         Evas_Object *page;
200         Evas_Object *item;
201         register unsigned int page_no;
202         register unsigned int position_no;
203         unsigned int nr_of_pages;
204         int page_max_app;
205
206         retv_if(NULL == scroller, MENU_SCREEN_ERROR_INVALID_PARAMETER);
207         retv_if(NULL == candidate_page, MENU_SCREEN_ERROR_INVALID_PARAMETER);
208         retv_if(NULL == candidate_pos, MENU_SCREEN_ERROR_INVALID_PARAMETER);
209
210         *candidate_page = 0;
211         *candidate_pos = 0;
212         nr_of_pages = page_scroller_count_page(scroller);
213         page_max_app = (int) evas_object_data_get(scroller, "page_max_app");
214         for (page_no = 0; page_no < nr_of_pages; page_no ++) {
215                 page = page_scroller_get_page_at(scroller, page_no);
216                 if (!page) {
217                         _D("Page is not found at %d", page_no);
218                         return MENU_SCREEN_ERROR_FAIL;
219                 }
220
221                 for (position_no = 0; position_no < page_max_app; position_no ++) {
222                         item = page_get_item_at(page, position_no);
223                         if (!item) {
224                                 *candidate_page = page_no;
225                                 *candidate_pos = position_no;
226                                 return MENU_SCREEN_ERROR_OK;
227                         }
228                 }
229         }
230
231         *candidate_page = page_no;
232         *candidate_pos = 0;
233
234         return MENU_SCREEN_ERROR_OK;
235 }
236
237
238
239 static menu_screen_error_e _find_position_by_package(Evas_Object *scroller, int *candidate_page, int *candidate_pos, void *data)
240 {
241         Evas_Object *page;
242         Evas_Object *item;
243         register int page_no;
244         register int position_no;
245         unsigned int nr_of_pages;
246         int page_max_app;
247         app_info_t *ai = data;
248
249         retv_if(NULL == scroller, MENU_SCREEN_ERROR_INVALID_PARAMETER);
250         retv_if(NULL == candidate_page, MENU_SCREEN_ERROR_INVALID_PARAMETER);
251         retv_if(NULL == candidate_pos, MENU_SCREEN_ERROR_INVALID_PARAMETER);
252         retv_if(NULL == data, MENU_SCREEN_ERROR_INVALID_PARAMETER);
253         retv_if(NULL == ai->package, MENU_SCREEN_ERROR_INVALID_PARAMETER);
254
255         *candidate_page = 0;
256         *candidate_pos = 0;
257         nr_of_pages = page_scroller_count_page(scroller);
258         page_max_app = (int) evas_object_data_get(scroller, "page_max_app");
259         for (page_no = 0; page_no < nr_of_pages; page_no ++) {
260                 page = page_scroller_get_page_at(scroller, page_no);
261                 if (!page) {
262                         _D("Page is not found at %d", page_no);
263                         return MENU_SCREEN_ERROR_FAIL;
264                 }
265
266                 for (position_no = 0; position_no < page_max_app; position_no ++) {
267                         char *package;
268
269                         item = page_get_item_at(page, position_no);
270                         if (!item) {
271                                 *candidate_page = page_no;
272                                 *candidate_pos = position_no;
273                                 return MENU_SCREEN_ERROR_OK;
274                         } else if ((package = item_get_package(item)) && strcmp(package, ai->package) > 0) {
275                                 *candidate_page = page_no;
276                                 *candidate_pos = position_no;
277                                 return MENU_SCREEN_ERROR_OK;
278                         }
279                 }
280         }
281
282         return MENU_SCREEN_ERROR_OK;
283 }
284
285
286
287 static menu_screen_error_e _find_position_by_name(Evas_Object *scroller, int *candidate_page, int *candidate_pos, void *data)
288 {
289         Evas_Object *page;
290         Evas_Object *item;
291         register int page_no;
292         register int position_no;
293         unsigned int nr_of_pages;
294         int page_max_app;
295         app_info_t *ai = data;
296
297         retv_if(NULL == scroller, MENU_SCREEN_ERROR_INVALID_PARAMETER);
298         retv_if(NULL == candidate_page, MENU_SCREEN_ERROR_INVALID_PARAMETER);
299         retv_if(NULL == candidate_pos, MENU_SCREEN_ERROR_INVALID_PARAMETER);
300         retv_if(NULL == data, MENU_SCREEN_ERROR_INVALID_PARAMETER);
301         retv_if(NULL == ai->name, MENU_SCREEN_ERROR_INVALID_PARAMETER);
302
303         *candidate_page = 0;
304         *candidate_pos = 0;
305         nr_of_pages = page_scroller_count_page(scroller);
306         page_max_app = (int) evas_object_data_get(scroller, "page_max_app");
307         for (page_no = 0; page_no < nr_of_pages; page_no ++) {
308                 page = page_scroller_get_page_at(scroller, page_no);
309                 if (!page) {
310                         _D("Page is not found at %d", page_no);
311                         return MENU_SCREEN_ERROR_FAIL;
312                 }
313
314                 for (position_no = 0; position_no < page_max_app; position_no ++) {
315                         char *name;
316
317                         item = page_get_item_at(page, position_no);
318                         if (!item) {
319                                 *candidate_page = page_no;
320                                 *candidate_pos = position_no;
321                                 return MENU_SCREEN_ERROR_OK;
322                         } else if ((name = item_get_name(item)) && strcmp(name, ai->name) > 0) {
323                                 *candidate_page = page_no;
324                                 *candidate_pos = position_no;
325                                 return MENU_SCREEN_ERROR_OK;
326                         }
327                 }
328         }
329
330         return MENU_SCREEN_ERROR_OK;
331 }
332
333
334
335 static menu_screen_error_e _animated_pack_item(Evas_Object *item, Evas_Object *scroller, Evas_Object *page, int from)
336 {
337         Evas_Object *item_out_page = NULL;
338         char buf[32];
339         int to;
340         int page_no;
341
342         retv_if(NULL == item, MENU_SCREEN_ERROR_INVALID_PARAMETER);
343         retv_if(NULL == scroller, MENU_SCREEN_ERROR_INVALID_PARAMETER);
344         retv_if(NULL == page, MENU_SCREEN_ERROR_INVALID_PARAMETER);
345
346         page_no = page_scroller_get_page_no(scroller, page);
347         do {
348                 to = page_find_empty_near(page, from);
349                 if (to < 0) {
350                         int page_max_app;
351                         page_max_app = (int) evas_object_data_get(page, "page_max_app");
352                         to = page_max_app - 1;
353                         item_out_page = page_unpack_item_at(page, to);
354                 }
355
356                 for (to --; to >= from; to --) {
357                         Evas_Object *item_in_page;
358                         item_in_page = page_unpack_item_at(page, to);
359                         page_pack_item(page, to + 1, item_in_page);
360                         snprintf(buf, 32, "menu%d", to + 1);
361                         edje_object_signal_emit(_EDJ(page), STR_MOVE_PREV, buf);
362                         edje_object_signal_emit(_EDJ(page), STR_ANI_RETURN, buf);
363                 }
364
365                 page_pack_item(page, from, item);
366
367                 if (!item_out_page) break;
368
369                 page_no ++;
370                 page = page_scroller_get_page_at(scroller, page_no);
371                 if (!page) {
372                         int rotate;
373                         rotate = (int) evas_object_data_get(scroller, "rotate");
374                         page = page_create(scroller, page_no, rotate);
375                         retv_if(NULL == page, MENU_SCREEN_ERROR_FAIL);
376                         mapbuf_enable(page, 0);
377                 }
378
379                 from = 0;
380                 item = item_out_page;
381                 item_out_page = NULL;
382         } while (page && item);
383
384         return MENU_SCREEN_ERROR_OK;
385 }
386
387
388
389 static Evas_Object *_animated_unpack_item(Evas_Object *scroller, Evas_Object *page, unsigned int pos)
390 {
391         Evas_Object *out = NULL;
392         Evas_Object *item;
393         Evas_Object *next_page;
394
395         char buf[32];
396         unsigned int page_max_app;
397         unsigned int page_no;
398         page_scroller_sort_type_e sort_type;
399
400         out = page_unpack_item_at(page, pos);
401         retv_if(NULL == out, NULL);
402
403         page_no = page_scroller_get_page_no(scroller, page);
404         page_max_app = (unsigned int) evas_object_data_get(scroller, "page_max_app");
405         sort_type = (page_scroller_sort_type_e) evas_object_data_get(scroller, "sort_type");
406
407         pos ++;
408         while (page && page_no < MAX_PAGE_NO) {
409                 if (0 == page_count_item(page)) {
410                         page_destroy(scroller, page);
411                         break;
412                 }
413
414                 for (; pos < page_max_app; pos ++) {
415                         item = page_unpack_item_at(page, pos);
416                         if (NULL == item) continue;
417
418                         page_pack_item(page, pos - 1, item);
419                         snprintf(buf, 32, "menu%d", pos - 1);
420                         edje_object_signal_emit(_EDJ(page), STR_MOVE_NEXT, buf);
421                         edje_object_signal_emit(_EDJ(page), STR_ANI_RETURN, buf);
422                 }
423
424                 if (sort_type == PAGE_SCROLLER_SORT_MAX) {
425                         return NULL;
426                 }
427
428                 page_no ++;
429                 next_page = page_scroller_get_page_at(scroller, page_no);
430                 if (next_page) {
431                         item = page_unpack_item_at(next_page, 0);
432                         if (NULL == item) continue;
433
434                         page_pack_item(page, page_max_app - 1, item);
435                 } else break;
436
437                 pos = 1;
438                 page = next_page;
439         }
440
441         return out;
442 }
443
444
445
446 HAPI Evas_Object *page_scroller_push_item(Evas_Object *scroller, app_info_t *ai)
447 {
448         Evas_Object *page;
449         Evas_Object *item;
450         unsigned int nr_of_pages;
451         int candidate_page = -1;
452         int candidate_pos = 0;
453         int sort_type;
454         register int i;
455
456         struct {
457                 page_scroller_sort_type_e sort_type;
458                 menu_screen_error_e (*sort_func)(Evas_Object *scroller, int *candidate_page, int *candidate_pos, void *data);
459         } sort_type_map[] = {
460                 {
461                         .sort_type = PAGE_SCROLLER_SORT_BY_DEFAULT,
462                         .sort_func = _find_position_by_default,
463                 },
464                 {
465                         .sort_type = PAGE_SCROLLER_SORT_BY_PACKAGE,
466                         .sort_func = _find_position_by_package,
467                 },
468                 {
469                         .sort_type = PAGE_SCROLLER_SORT_BY_NAME,
470                         .sort_func = _find_position_by_name,
471                 },
472                 {
473                         .sort_type = PAGE_SCROLLER_SORT_MAX,
474                         .sort_func = NULL,
475                 },
476         };
477
478         sort_type = (int) evas_object_data_get(scroller, "sort_type");
479         sort_type_map[sort_type].sort_func(scroller, &candidate_page, &candidate_pos, ai);
480
481         nr_of_pages = page_scroller_count_page(scroller);
482
483         for (i = nr_of_pages; i <= candidate_page; i ++) {
484                 Evas_Object *new_page;
485                 int rotate;
486
487                 rotate = (int) evas_object_data_get(scroller, "rotate");
488                 new_page = page_create(scroller, nr_of_pages, rotate);
489                 retv_if(NULL == new_page, NULL);
490                 mapbuf_enable(new_page, 0);
491         }
492
493         item = item_create(scroller, ai);
494         retv_if(NULL == item, NULL);
495
496         page = page_scroller_get_page_at(scroller, candidate_page);
497         if (!page) {
498                 _D("Impossible, page is not found");
499                 item_destroy(item);
500                 return NULL;
501         }
502
503         retv_if(MENU_SCREEN_ERROR_OK !=
504                         _animated_pack_item(item, scroller, page, candidate_pos),
505                         NULL);
506
507         return item;
508 }
509
510
511
512 static inline menu_screen_error_e _create_cb(const char *package, void *data)
513 {
514         app_info_t ai = {0,};
515         Evas_Object *item;
516         Evas_Object *scroller = data;
517
518         if (MENU_SCREEN_ERROR_FAIL == list_get_values(package, &ai)) {
519                 list_free_values(&ai);
520                 return MENU_SCREEN_ERROR_FAIL;
521         }
522
523         do {
524                 if (!scroller) {
525                         _D("Scroller is NULL.");
526                         break;
527                 }
528
529                 if (ai.nodisplay || !ai.enabled)
530                 {
531                         Evas_Object *page;
532
533                         _D("package %s is not visible", package);
534                         item = pkgmgr_find_pended_object(ai.package, 1, scroller, &page);
535                         if (item) {
536                                 if (page) {
537                                         page_unpack_item(page, item);
538                                         page_scroller_trim_items(scroller);
539                                 }
540
541                                 item_destroy(item);
542                         }
543
544                         break;
545                 }
546
547                 item = pkgmgr_find_pended_object(ai.package, 1, scroller, NULL);
548                 if (!item) {
549                         item = page_scroller_find_item_by_package(scroller, ai.package, NULL);
550                         if (!item) {
551                                 Evas_Object *item;
552                                 _D("package %s is installed directly", package);
553                                 item = page_scroller_push_item(scroller, &ai);
554                                 if (item) {
555                                         break;
556                                 } else {
557                                         list_free_values(&ai);
558                                         retv_if(1, MENU_SCREEN_ERROR_FAIL);
559                                 }
560                         }
561                 }
562
563                 _D("Package %s is found, update it!", package);
564                 item_update(item, &ai);
565         } while(0);
566
567         list_free_values(&ai);
568         return MENU_SCREEN_ERROR_OK;
569 }
570
571
572
573 static inline menu_screen_error_e _update_cb(const char *package, void *data)
574 {
575         Evas_Object *scroller = data;
576         Evas_Object *item;
577         int page_no = 0;
578         app_info_t ai = {0,};
579
580         if (MENU_SCREEN_ERROR_FAIL == list_get_values(package, &ai)) {
581                 list_free_values(&ai);
582                 return MENU_SCREEN_ERROR_FAIL;
583         }
584
585         do {
586                 if (!scroller) {
587                         _D("Scroller is NULL.");
588                         break;
589                 }
590
591                 item = page_scroller_find_item_by_package(scroller, package, &page_no);
592                 if (!item) {
593                         Evas_Object *page;
594                         _D("There is no loaded item is found");
595                         item = pkgmgr_find_pended_object(package, 1, scroller, &page);
596                         if (item) {
597                                 if (!ai.nodisplay && ai.enabled) {
598                                         _D("Item is found for updating from the install list, Ignore this.");
599                                         item_update(item, &ai);
600                                 } else {
601                                         _D("Item is found for updating from the install list, But nodisplay");
602                                         if (page) {
603                                                 page_unpack_item(page, item);
604                                                 page_scroller_trim_items(scroller);
605                                         }
606                                         item_destroy(item);
607                                 }
608                         } else {
609                                 Evas_Object *item;
610                                 _D("Item is not found. Create a new one");
611                                 item = ((!ai.nodisplay && ai.enabled) ? page_scroller_push_item(scroller, &ai) : NULL);
612                                 if (item) {
613                                         break;
614                                 } else {
615                                         list_free_values(&ai);
616                                         retv_if(1, MENU_SCREEN_ERROR_FAIL);
617                                 }
618                         }
619                 } else {
620                         Evas_Object *page;
621                         Evas_Object *pended_item;
622
623                         pended_item = pkgmgr_find_pended_object(package, 1, scroller, &page);
624                         if (!pended_item ) {
625                                 _D("Cannot find package in the install list");
626                         }
627
628                         if (!ai.nodisplay && ai.enabled) {
629                                 item_update(item, &ai);
630                                 break;
631                         }
632
633                         page = page_scroller_get_page_at(scroller, page_no);
634                         if (page) {
635                                 page_unpack_item(page, item);
636                                 page_scroller_trim_items(scroller);
637                         }
638                         item_destroy(item);
639                 }
640         } while (0);
641
642         list_free_values(&ai);
643         return MENU_SCREEN_ERROR_OK;
644 }
645
646
647
648 static inline menu_screen_error_e _delete_cb(const char *package, void *data)
649 {
650         Evas_Object *item;
651         Evas_Object *page;
652         Evas_Object *scroller = data;
653         Evas_Object *tmp;
654         int page_no = 0;
655         register unsigned int i;
656         unsigned int page_max_app;
657
658         do {
659                 if (!scroller) {
660                         _D("Scroller is NULL.");
661                         break;
662                 }
663
664                 tmp = pkgmgr_find_pended_object(package, 1, scroller, NULL);
665
666                 item = page_scroller_find_item_by_package(scroller, package, &page_no);
667                 retv_if(NULL == item, MENU_SCREEN_ERROR_FAIL);
668
669                 if (tmp != item) {
670                         _D("Pended item is %p, Found item is %p", tmp, item);
671                 }
672
673                 page = page_scroller_get_page_at(scroller, page_no);
674                 retv_if(NULL == page, MENU_SCREEN_ERROR_FAIL);
675
676                 page_max_app = (unsigned int) evas_object_data_get(scroller, "page_max_app");
677                 for (i = 0; i < page_max_app; i++) {
678                         if (item == page_get_item_at(page, i)) {
679                                 break;
680                         }
681                 }
682
683                 item = _animated_unpack_item(scroller, page, i);
684                 retv_if(NULL == item, MENU_SCREEN_ERROR_FAIL);
685                 item_destroy(item);
686         } while (0);
687
688         return MENU_SCREEN_ERROR_OK;
689 }
690
691
692
693 static struct pkg_event_handler {
694         const char *event_name;
695         int (*event_handler)(const char *package, void *data);
696 } event_table[] = {
697         {
698                 .event_name = "create",
699                 .event_handler = _create_cb,
700         },
701         {
702                 .event_name = "update",
703                 .event_handler = _update_cb,
704         },
705         {
706                 .event_name = "delete",
707                 .event_handler = _delete_cb,
708         },
709         {
710                 .event_name = NULL,
711                 .event_handler = NULL,
712         },
713 };
714
715
716
717 static void _desktop_cb(keynode_t *node, void *data)
718 {
719         char *event;
720         char type[10];
721         char package[BUFSZE];
722         register int i;
723
724         event = vconf_get_str(vconf_keynode_get_name(node));
725         ret_if(NULL == event);
726
727         if (sscanf(event, "%10[^:]:%1023s", type, package) != 2) {
728                 _D("Failed to parse the event format : [%s], [%s]", type, package);
729         }
730
731         _D("command[%s], package[%s]", type, package);
732
733         for (i = 0; event_table[i].event_name; i ++) {
734                 if (!strcasecmp(type, event_table[i].event_name)) {
735                         if (event_table[i].event_handler(package, data) == MENU_SCREEN_ERROR_FAIL) {
736                                 _E("Failed to handles the desktop notification event");
737                         }
738
739                         free(event);
740                         return;
741                 }
742         }
743
744         _E("Failed to find a proper event handler");
745         free(event);
746 }
747
748
749
750 static void _mapbuf_cb(keynode_t *node, void *data)
751 {
752         int value;
753         int nr_of_pages;
754         register int i;
755         Evas_Object *page;
756
757         if (vconf_get_int("memory/menuscreen/mapbuf", &value) < 0) {
758                 _D("Failed to get mapbuf status");
759                 return;
760         }
761
762         nr_of_pages = page_scroller_count_page(data);
763         if (value) {
764                 for (i = 0; i < nr_of_pages; i ++) {
765                         page = page_scroller_get_page_at(data, i);
766                         if (!page) continue;
767
768                         if (!mapbuf_is_enabled(page)) {
769                                 _D("Enable mapbuf %d", i);
770                                 mapbuf_enable(page, 1);
771                         }
772                 }
773         } else {
774                 for (i = 0; i < nr_of_pages; i ++) {
775                         page = page_scroller_get_page_at(data, i);
776                         if (!page) continue;
777
778                         if (mapbuf_is_enabled(page)) {
779                                 _D("Disable mapbuf %d", i);
780                                 mapbuf_disable(page, 1);
781                         }
782                 }
783         }
784 }
785
786
787
788 static void _mouse_wheel_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
789 {
790         Evas_Event_Mouse_Wheel *ei = event_info;
791         Evas_Object *scroller = data;
792         int x, y, w, h;
793         int idx = -1;
794
795         _D("Wheel's up or down(%d)", ei->z);
796
797         elm_scroller_region_get(scroller, &x, &y, &w, &h);
798         if (ei->z > 0) { // Wheel's up
799                 idx = x / w;
800                 idx ++;
801         } else if (ei->z < 0) { // Wheel's down
802                 idx = x / w; // Scroller got ECORE events at first, then Menu-screen gets EVAS events.
803         } else { // Wheel's not moving.
804                 _D("Wheel's not moving");
805         }
806
807         if (idx >= page_scroller_count_page(scroller) || idx < 0) return;
808         page_scroller_bring_in(scroller, idx);
809 }
810
811
812
813 HAPI Evas_Object *page_scroller_create(Evas_Object *tab, Evas_Object *index, page_scroller_sort_type_e sort_type, int rotate)
814 {
815         Evas_Object *box;
816         Evas_Object *scroller;
817         int width;
818         int height;
819
820         scroller = elm_scroller_add(tab);
821         retv_if(NULL == scroller, NULL);
822
823         elm_scroller_content_min_limit(scroller, EINA_FALSE, EINA_FALSE);
824         elm_scroller_bounce_set(scroller, EINA_TRUE, EINA_FALSE);
825         elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
826
827         width = menu_screen_get_root_width();
828         height = (int) ((double) PROP_PORTRAIT_HEIGHT * ((double) menu_screen_get_root_height()));
829         elm_scroller_page_size_set(scroller, width, height);
830
831         evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
832         evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
833         evas_object_size_hint_min_set(scroller, width, height);
834         evas_object_size_hint_max_set(scroller, width, height);
835
836         _scroller_register(scroller);
837
838         box = elm_box_add(scroller);
839         if (!box) {
840                 _D("Failed to create box");
841                 evas_object_del(scroller);
842                 return NULL;
843         }
844         elm_box_horizontal_set(box, 1);
845         evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
846
847         evas_object_data_set(scroller, "win", evas_object_data_get(tab, "win"));
848         evas_object_data_set(scroller, "layout", evas_object_data_get(tab, "layout"));
849         evas_object_data_set(scroller, "controlbar", evas_object_data_get(tab, "controlbar"));
850         evas_object_data_set(scroller, "tab", tab);
851         evas_object_data_set(scroller, "page_edje", evas_object_data_get(tab, "page_edje"));
852         evas_object_data_set(scroller, "page_max_app", evas_object_data_get(tab, "page_max_app"));
853         evas_object_data_set(scroller, "item_edje", evas_object_data_get(tab, "item_edje"));
854         evas_object_data_set(scroller, "item_width", evas_object_data_get(tab, "item_width"));
855         evas_object_data_set(scroller, "item_height", evas_object_data_get(tab, "item_height"));
856         evas_object_data_set(scroller, "item_enable_long_press", evas_object_data_get(tab, "item_enable_long_press"));
857         evas_object_data_set(scroller, "item_text_dual_line", evas_object_data_get(tab, "item_text_dual_line"));
858         evas_object_data_set(scroller, "enable_bg_image", evas_object_data_get(tab, "enable_bg_image"));
859         evas_object_data_set(scroller, "box", box);
860         evas_object_data_set(scroller, "drag_start", (void *) 0);
861         evas_object_data_set(scroller, "previous_x", (void *) 0);
862         evas_object_data_set(scroller, "index", index);
863         evas_object_data_set(scroller, "sort_type", (void *) sort_type);
864         evas_object_data_set(scroller, "install_list", (void *) 0);
865         evas_object_data_set(scroller, "rotate", (void *) rotate);
866         evas_object_data_set(scroller, "is_edited", (void *) false);
867         elm_object_content_set(scroller, box);
868
869         evas_object_event_callback_add(box, EVAS_CALLBACK_DEL, _evas_object_event_del_cb, "BOX");
870         evas_object_event_callback_add(scroller, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, scroller);
871
872         evas_object_show(box);
873         evas_object_show(scroller);
874
875         if (vconf_notify_key_changed(VCONFKEY_AIL_INFO_STATE, _desktop_cb, scroller) < 0) {
876                 _E("Failed to register a desktop change event handler");
877         }
878
879         if (vconf_notify_key_changed("memory/menuscreen/mapbuf", _mapbuf_cb, scroller) < 0) {
880                 _E("Failed to register a vconf cb for %s", "memory/menuscreen/mapbuf");
881         }
882
883         // FIXME : This will be enabled after rebuilding the routine for appid <-> pkgid.
884         //pkgmgr_init(scroller);
885         item_badge_register_changed_cb(scroller);
886
887         return scroller;
888 }
889
890
891
892 HAPI void page_scroller_destroy(Evas_Object *scroller)
893 {
894         Evas_Object *box;
895         Evas_Object *page;
896         Evas_Object *tmp;
897
898         const Eina_List *page_list;
899         const Eina_List *l;
900         const Eina_List *ln;
901
902         ret_if(NULL == scroller);
903         ret_if(NULL == (box = evas_object_data_get(scroller, "box")));
904         ret_if(NULL == (page_list = elm_box_children_get(box)));
905
906         item_badge_unregister_changed_cb();
907
908         // FIXME : This will be enabled after rebuilding the routine for appid <-> pkgid.
909         //pkgmgr_fini();
910
911         EINA_LIST_FOREACH_SAFE(page_list, l, ln, page) {
912                 int count;
913
914                 if (!page) {
915                         _D("page list contains nil item");
916                         continue;
917                 }
918
919                 count = eina_list_count(page_list);
920                 _D("page_list count : %d", count);
921                 if (count < 1) {
922                         elm_box_unpack(box, page);
923                 }
924
925                 tmp = mapbuf_get_page(page);
926                 if (tmp) page = tmp;
927
928                 page_destroy(scroller, page);
929         }
930
931         box = elm_object_content_unset(scroller);
932         evas_object_del(box);
933
934         _scroller_unregister(scroller);
935         evas_object_data_del(scroller, "win");
936         evas_object_data_del(scroller, "layout");
937         evas_object_data_del(scroller, "controlbar");
938         evas_object_data_del(scroller, "tab");
939         evas_object_data_del(scroller, "page_edje");
940         evas_object_data_del(scroller, "page_max_app");
941         evas_object_data_del(scroller, "item_edje");
942         evas_object_data_del(scroller, "item_width");
943         evas_object_data_del(scroller, "item_height");
944         evas_object_data_del(scroller, "item_enable_long_press");
945         evas_object_data_del(scroller, "item_text_dual_line");
946         evas_object_data_del(scroller, "enable_bg_image");
947         evas_object_data_del(scroller, "box");
948         evas_object_data_del(scroller, "drag_start");
949         evas_object_data_del(scroller, "previous_x");
950         evas_object_data_del(scroller, "index");
951         evas_object_data_del(scroller, "sort_type");
952         evas_object_data_del(scroller, "rotate");
953         evas_object_data_del(scroller, "is_edited");
954         evas_object_data_del(scroller, "install_list");
955
956         evas_object_del(scroller);
957         evas_object_event_callback_del(box, EVAS_CALLBACK_DEL, _evas_object_event_del_cb);
958         evas_object_event_callback_del(scroller, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb);
959
960         if (vconf_ignore_key_changed(VCONFKEY_AIL_INFO_STATE, _desktop_cb) < 0) {
961                 _E("Failed to ignore the desktop event");
962         }
963
964         if (vconf_ignore_key_changed("memory/menuscreen/mapbuf", _mapbuf_cb) < 0) {
965                 _E("Failed to remove vconf %s", "memory/menuscreen/mapbuf");
966         }
967 }
968
969
970
971 HAPI void page_scroller_clean(Evas_Object *scroller)
972 {
973         Evas_Object *page;
974         Evas_Object *item;
975
976         register unsigned int i;
977         unsigned int page_max_app;
978         unsigned int count;
979
980         count = page_scroller_count_page(scroller);
981         if (count == 0) return;
982
983         for (i = 1; i < MAX_PAGE_NO; i++) {
984                 page = page_scroller_get_page_at(scroller, i);
985                 if (NULL == page) break;
986
987                 page_destroy(scroller, page);
988         }
989
990         page = page_scroller_get_page_at(scroller, 0);
991         ret_if(NULL == page);
992
993         page_max_app = (unsigned int) evas_object_data_get(scroller, "page_max_app");
994         for (i = 0; i < page_max_app; i++) {
995                 item = page_get_item_at(page, i);
996                 if (item) {
997                         item_destroy(item);
998                 } else break;
999         }
1000 }
1001
1002
1003
1004 HAPI Evas_Object *page_scroller_get_page_at(Evas_Object *scroller, unsigned int idx)
1005 {
1006         const Eina_List *page_list;
1007         Evas_Object *item;
1008         Evas_Object *box;
1009
1010         retv_if(idx >= MAX_PAGE_NO, NULL);
1011
1012         box = evas_object_data_get(scroller, "box");
1013         retv_if(NULL == box, NULL);
1014
1015         page_list = elm_box_children_get(box);
1016         retv_if(NULL == page_list, NULL);
1017
1018         item = eina_list_nth(page_list, idx);
1019         if (item) {
1020                 item = mapbuf_get_page(item);
1021         }
1022
1023         return item;
1024 }
1025
1026
1027
1028 HAPI unsigned int page_scroller_count_page(Evas_Object *scroller)
1029 {
1030         const Eina_List *page_list;
1031         Evas_Object *box;
1032
1033         box = evas_object_data_get(scroller, "box");
1034         retv_if(NULL == box, 0);
1035
1036         page_list = elm_box_children_get(box);
1037         retv_if(NULL == page_list, 0);
1038
1039         return eina_list_count(page_list);
1040 }
1041
1042
1043
1044 HAPI int page_scroller_get_page_no(Evas_Object* scroller, Evas_Object *page)
1045 {
1046         Evas_Object *item;
1047         Evas_Object *box;
1048         register int idx = 0;
1049         const Eina_List *page_list;
1050         const Eina_List *pos;
1051
1052         box = evas_object_data_get(scroller, "box");
1053         retv_if(NULL == box, 0);
1054
1055         page_list = elm_box_children_get(box);
1056         EINA_LIST_FOREACH(page_list, pos, item) {
1057                 if (!item) {
1058                         _D("page list contains nil item");
1059                         continue;
1060                 }
1061
1062                 item = mapbuf_get_page(item);
1063                 if (item == page) {
1064                         return idx;
1065                 }
1066
1067                 idx ++;
1068         }
1069
1070         return -1;
1071 }
1072
1073
1074
1075 HAPI Evas_Object *page_scroller_find_item_by_package(Evas_Object *scroller, const char *package, int *page_no)
1076 {
1077         register int i;
1078         register int j;
1079         Evas_Object *page;
1080         Evas_Object *item;
1081         const char *tmp;
1082         int local_page_no;
1083         int page_max_app;
1084
1085         if (!page_no) page_no = &local_page_no;
1086
1087         retv_if(NULL == package, NULL);
1088
1089         page_max_app = (int) evas_object_data_get(scroller, "page_max_app");
1090         for (i = 0; i < page_scroller_count_page(scroller); i ++) {
1091                 page = page_scroller_get_page_at(scroller, i);
1092                 if (!page) continue;
1093
1094                 for (j = 0; j < page_max_app; j ++) {
1095                         item = page_get_item_at(page, j);
1096                         if (!item) continue;
1097
1098                         tmp = item_get_package(item);
1099                         if (!tmp) {
1100                                 _D("Something goes wrong, this package has no name?");
1101                                 continue;
1102                         }
1103
1104                         if (!strcmp(tmp, package)) {
1105                                 *page_no = i;
1106                                 return item;
1107                         }
1108                 }
1109         }
1110
1111         return NULL;
1112 }
1113
1114
1115
1116 HAPI void page_scroller_trim_items(Evas_Object *scroller)
1117 {
1118         register unsigned int i;
1119         register unsigned int j;
1120         int page_max_app;
1121         int pos = 0;
1122
1123         Evas_Object *page;
1124         Evas_Object *item;
1125         Eina_List *list = NULL;
1126
1127         page_max_app = (int) evas_object_data_get(scroller, "page_max_app");
1128         for (i = 0; i < MAX_PAGE_NO; i ++) {
1129                 page = page_scroller_get_page_at(scroller, i);
1130                 if (!page) break;
1131
1132                 for (j = 0; j < page_max_app; j++) {
1133                         item = page_unpack_item_at(page, j);
1134                         if (item) {
1135                                 list = eina_list_append(list, item);
1136                                 _D("LIST APPEND : %s", item_get_package(item));
1137                         }
1138                 }
1139
1140         }
1141
1142         for (i = 0; i < eina_list_count(list); i++) {
1143                 if (i % page_max_app == 0) {
1144                         page = page_scroller_get_page_at(scroller, i / page_max_app);
1145                         _D("PAGE GET : 0x%x", page);
1146                         if (NULL == page) {
1147                                 _E("Cannot get page");
1148                                 break;
1149                         }
1150                 }
1151
1152                 item = eina_list_nth(list, i);
1153                 if (NULL == item) {
1154                         _E("Cannot get item");
1155                         break;
1156                 }
1157                 _D("LIST GET : [%d] %s", pos, item_get_package(item));
1158
1159                 page_pack_item(page, pos % page_max_app, item);
1160                 pos++;
1161         }
1162
1163         for (i = pos / page_max_app; i < MAX_PAGE_NO; i++) {
1164                 int count;
1165
1166                 page = page_scroller_get_page_at(scroller, i);
1167                 if (NULL == page) {
1168                         break;
1169                 }
1170                 count = page_count_item(page);
1171                 if (count == 0) {
1172                         Evas_Coord w;
1173                         Evas_Coord h;
1174
1175                         _D("PAGE IS EMPTY : 0x%x", page);
1176
1177                         page_destroy(scroller, page);
1178                         evas_object_geometry_get(scroller, NULL, NULL, &w, &h);
1179                         elm_scroller_region_show(scroller, 0, 0, w, h);
1180                 }
1181         }
1182         pos --;
1183         eina_list_free(list);
1184 }
1185
1186
1187
1188 HAPI void page_scroller_edit(Evas_Object *scroller)
1189 {
1190         Evas_Object *page;
1191         Evas_Object *item;
1192         register unsigned int page_no;
1193         register unsigned int position_no;
1194         unsigned int nr_of_pages;
1195         int page_max_app;
1196
1197         nr_of_pages = page_scroller_count_page(scroller);
1198         page_max_app = (int) evas_object_data_get(scroller, "page_max_app");
1199         for (page_no = 0; page_no < nr_of_pages; page_no ++) {
1200                 page = page_scroller_get_page_at(scroller, page_no);
1201                 ret_if(NULL == page);
1202
1203                 for (position_no = 0; position_no < page_max_app; position_no ++) {
1204                         item = page_get_item_at(page, position_no);
1205                         if (!item) {
1206                                 continue;
1207                         }
1208
1209                         item_edit(item);
1210                 }
1211         }
1212         evas_object_data_set(scroller, "is_edited", (void *) true);
1213 }
1214
1215
1216
1217 HAPI void page_scroller_unedit(Evas_Object *scroller)
1218 {
1219         Evas_Object *all_apps;
1220         Evas_Object *page;
1221         Evas_Object *item;
1222         register int page_no;
1223         register unsigned int position_no;
1224         unsigned int nr_of_pages;
1225         int page_max_app;
1226
1227         ret_if(NULL == scroller);
1228
1229         all_apps = evas_object_data_get(scroller, "tab");
1230         ret_if(NULL == all_apps);
1231
1232         nr_of_pages = page_scroller_count_page(scroller);
1233         page_max_app = (int) evas_object_data_get(scroller, "page_max_app");
1234
1235         for (page_no = nr_of_pages - 1; page_no >= 0; page_no --) {
1236                 int count;
1237
1238                 page = page_scroller_get_page_at(scroller, page_no);
1239                 if (NULL == page) break;
1240                 count = page_count_item(page);
1241
1242                 page_scroller_trim_items(scroller);
1243
1244                 for (position_no = 0; position_no < page_max_app; position_no ++) {
1245                         item = page_get_item_at(page, position_no);
1246                         if (!item) {
1247                                 break;
1248                         }
1249
1250                         item_unedit(item);
1251                 }
1252         }
1253
1254         evas_object_data_set(scroller, "is_edited", (void *) false);
1255 }
1256
1257
1258
1259 HAPI bool page_scroller_is_edited(Evas_Object *scroller)
1260 {
1261         return (bool) evas_object_data_get(scroller, "is_edited");
1262 }
1263
1264
1265
1266 // End of a file