2 #include <Elementary.h>
3 #include <Elementary_Cursor.h>
5 #include "elm_widget_genlist.h"
7 #define GROUP_ITEMS_FEATURE 0
8 // internally allocated
9 #define CLASS_ALLOCATED 0x3a70f11f
11 #define MAX_ITEMS_PER_BLOCK 32
12 #define REORDER_EFFECT_TIME 0.1
13 #define FX_MOVE_TIME 0.5
14 #define FX_TRANSIT_FOCAL 2000
15 #define FX_ZOOM_TOLERANCE 0.4
16 #define ITEM_HIGHLIGHT_TIMER 0.1
18 EAPI const char ELM_GENLIST_SMART_NAME[] = "elm_genlist";
19 EAPI const char ELM_GENLIST_PAN_SMART_NAME[] = "elm_genlist_pan";
21 #define ERR_ABORT(_msg) \
24 if (getenv("ELM_ERROR_ABORT")) abort(); \
27 #define GL_IT(_it) (_it->item)
29 #define IS_ROOT_PARENT_IT(_it) \
30 ((_it->group) || ((GL_IT(_it)->items && GL_IT(_it)->expanded_depth == 0) \
31 &&(!(GL_IT(_it)->type & ELM_GENLIST_ITEM_TREE)))) \
33 static const Evas_Smart_Interface *_smart_interfaces[] =
35 (Evas_Smart_Interface *)&ELM_SCROLLABLE_IFACE, NULL
38 static const char SIG_ACTIVATED[] = "activated";
39 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
40 static const char SIG_SELECTED[] = "selected";
41 static const char SIG_UNSELECTED[] = "unselected";
42 static const char SIG_EXPANDED[] = "expanded";
43 static const char SIG_CONTRACTED[] = "contracted";
44 static const char SIG_EXPAND_REQUEST[] = "expand,request";
45 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
46 static const char SIG_REALIZED[] = "realized";
47 static const char SIG_UNREALIZED[] = "unrealized";
48 static const char SIG_DRAG_START_UP[] = "drag,start,up";
49 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
50 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
51 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
52 static const char SIG_DRAG_STOP[] = "drag,stop";
53 static const char SIG_DRAG[] = "drag";
54 static const char SIG_LONGPRESSED[] = "longpressed";
55 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
56 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
57 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
58 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
59 static const char SIG_SCROLL[] = "scroll";
60 static const char SIG_EDGE_TOP[] = "edge,top";
61 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
62 static const char SIG_EDGE_LEFT[] = "edge,left";
63 static const char SIG_EDGE_RIGHT[] = "edge,right";
64 static const char SIG_VBAR_DRAG[] = "vbar,drag";
65 static const char SIG_VBAR_PRESS[] = "vbar,press";
66 static const char SIG_VBAR_UNPRESS[] = "vbar,unpress";
67 static const char SIG_HBAR_DRAG[] = "hbar,drag";
68 static const char SIG_HBAR_PRESS[] = "hbar,press";
69 static const char SIG_HBAR_UNPRESS[] = "hbar,unpress";
70 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
71 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
72 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
73 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
74 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
75 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
76 static const char SIG_SWIPE[] = "swipe";
77 static const char SIG_MOVED[] = "moved";
78 static const char SIG_MOVED_AFTER[] = "moved,after";
79 static const char SIG_MOVED_BEFORE[] = "moved,before";
80 static const char SIG_INDEX_UPDATE[] = "index,update";
81 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
82 static const char SIG_HIGHLIGHTED[] = "highlighted";
83 static const char SIG_UNHIGHLIGHTED[] = "unhighlighted";
84 static const char SIG_LANG_CHANGED[] = "language,changed";
85 static const char SIG_PRESSED[] = "pressed";
86 static const char SIG_RELEASED[] = "released";
87 static const char SIG_FOCUSED[] = "item,focused";
88 static const char SIG_UNFOCUSED[] = "item,unfocused";
89 static const char SIG_ACCESS_CHANGED[] = "access,changed";
91 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
92 {SIG_CLICKED_DOUBLE, ""},
98 {SIG_EXPAND_REQUEST, ""},
99 {SIG_CONTRACT_REQUEST, ""},
101 {SIG_UNREALIZED, ""},
102 {SIG_DRAG_START_UP, ""},
103 {SIG_DRAG_START_DOWN, ""},
104 {SIG_DRAG_START_LEFT, ""},
105 {SIG_DRAG_START_RIGHT, ""},
108 {SIG_LONGPRESSED, ""},
110 {SIG_SCROLL_ANIM_START, ""},
111 {SIG_SCROLL_ANIM_STOP, ""},
112 {SIG_SCROLL_DRAG_START, ""},
113 {SIG_SCROLL_DRAG_STOP, ""},
115 {SIG_EDGE_BOTTOM, ""},
117 {SIG_EDGE_RIGHT, ""},
119 {SIG_VBAR_PRESS, ""},
120 {SIG_VBAR_UNPRESS, ""},
122 {SIG_HBAR_PRESS, ""},
123 {SIG_HBAR_UNPRESS, ""},
124 {SIG_MULTI_SWIPE_LEFT, ""},
125 {SIG_MULTI_SWIPE_RIGHT, ""},
126 {SIG_MULTI_SWIPE_UP, ""},
127 {SIG_MULTI_SWIPE_DOWN, ""},
128 {SIG_MULTI_PINCH_OUT, ""},
129 {SIG_MULTI_PINCH_IN, ""},
132 {SIG_MOVED_AFTER, ""},
133 {SIG_MOVED_BEFORE, ""},
134 {SIG_TREE_EFFECT_FINISHED, ""},
135 {SIG_HIGHLIGHTED, ""},
136 {SIG_UNHIGHLIGHTED, ""},
137 {SIG_LANG_CHANGED, ""},
140 {SIG_ACCESS_CHANGED, ""},
152 EVAS_SMART_SUBCLASS_IFACE_NEW
153 (ELM_GENLIST_SMART_NAME, _elm_genlist, Elm_Genlist_Smart_Class,
154 Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks,
157 ELM_INTERNAL_SMART_SUBCLASS_NEW
158 (ELM_GENLIST_PAN_SMART_NAME, _elm_genlist_pan, Elm_Genlist_Pan_Smart_Class,
159 Elm_Pan_Smart_Class, elm_pan_smart_class_get, NULL);
161 static void _calc_job(void *);
162 static Eina_Bool _item_block_recalc(Item_Block *, int, Eina_Bool);
163 static void _item_mouse_callbacks_add(Elm_Gen_Item *, Evas_Object *);
164 static void _item_mouse_callbacks_del(Elm_Gen_Item *, Evas_Object *);
165 static void _access_activate_cb(void *data __UNUSED__,
166 Evas_Object *part_obj __UNUSED__,
167 Elm_Object_Item *item);
168 static void _item_select(Elm_Gen_Item *it);
170 static void _expand_toggle_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
171 static void _expand_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
172 static void _contract_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
173 static void _decorate_item_unrealize(Elm_Gen_Item *it);
174 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
175 static void _decorate_item_set(Elm_Gen_Item *it);
176 static void _item_queue(Elm_Genlist_Smart_Data *sd, Elm_Gen_Item *it, Eina_Compare_Cb cb, Eina_Bool direct);
178 #if GENLIST_FX_SUPPORT
179 static Eina_Bool _elm_genlist_fx_capture(Evas_Object *obj, int level);
180 static void _elm_genlist_fx_play(Evas_Object *obj);
181 static void _elm_genlist_fx_clear(Evas_Object *obj, Eina_Bool force);
182 static void _elm_genlist_proxy_item_del(Proxy_Item *pi);
185 #if GENLIST_PINCH_ZOOM_SUPPORT
186 EAPI Eina_Bool elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Elm_Gen_Pinch_Zoom_Mode mode);
189 typedef struct _Size_Cache {
195 _item_event_del(Elm_Gen_Item *it)
199 ecore_timer_del(it->long_timer);
200 it->long_timer = NULL;
202 if (it->item->swipe_timer)
204 ecore_timer_del(it->item->swipe_timer);
205 it->item->swipe_timer = NULL;
210 _item_cache_all_free(Elm_Genlist_Smart_Data *sd)
212 // It would be better not to use
213 // EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
214 while (sd->item_cache)
216 Item_Cache *ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
217 if (ic->spacer) evas_object_del(ic->spacer);
218 if (ic->base_view) evas_object_del(ic->base_view);
219 if (ic->item_style) eina_stringshare_del(ic->item_style);
220 sd->item_cache = eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
221 // Free should be performed after inlist is poped
224 sd->item_cache = NULL;
225 sd->item_cache_count = 0;
229 _item_cache_push(Elm_Gen_Item *it)
231 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
232 Item_Cache *ic = NULL;
234 if (sd->item_cache_count >= sd->item_cache_max)
236 ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
237 if (ic->spacer) evas_object_del(ic->spacer);
238 if (ic->base_view) evas_object_del(ic->base_view);
239 eina_stringshare_del(ic->item_style);
240 sd->item_cache = eina_inlist_remove(sd->item_cache,
241 sd->item_cache->last);
242 sd->item_cache_count--;
243 // Free should be performed after inlist is poped
246 //evas_event_freeze(evas_object_evas_get(obj));
248 edje_object_mirrored_set(VIEW(it),
249 elm_widget_mirrored_get(WIDGET(it)));
250 edje_object_scale_set(VIEW(it),
251 elm_widget_scale_get(WIDGET(it))
252 * elm_config_scale_get());
254 // FIXME: other callbacks?
255 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand,toggle",
256 "elm", _expand_toggle_signal_cb, it);
257 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand", "elm",
258 _expand_signal_cb, it);
259 edje_object_signal_callback_del_full(VIEW(it), "elm,action,contract", "elm",
260 _contract_signal_cb, it);
261 _item_mouse_callbacks_del(it, VIEW(it));
263 #if GENLIST_FX_SUPPORT
264 if ((it->item->nocache_once) || (it->item->nocache) || (sd->pending_del_items))
266 if ((it->item->nocache_once) || (it->item->nocache))
269 if (VIEW(it)) evas_object_del(VIEW(it));
270 if (it->spacer) evas_object_del(it->spacer);
273 ic = ELM_NEW(Item_Cache);
276 if (VIEW(it)) evas_object_del(VIEW(it));
277 if (it->spacer) evas_object_del(it->spacer);
282 // set item's state as default before pushing item into cache.
283 edje_object_signal_emit(VIEW(it),"elm,state,default", "elm");
285 ic->base_view = VIEW(it);
286 ic->spacer = it->spacer;
287 ic->item_style = eina_stringshare_add(it->itc->item_style);
288 if (it->item->type & ELM_GENLIST_ITEM_TREE) ic->tree = 1;
290 ic->expanded = it->item->expanded;
291 if (it->item->type & ELM_GENLIST_ITEM_TREE) ic->tree = 1;
292 ic->multiline = it->item->multiline;
293 evas_object_hide(ic->base_view);
295 sd->item_cache = eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(ic));
296 sd->item_cache_count++;
301 it->realized = EINA_FALSE;
302 it->want_unrealize = EINA_FALSE;
304 //evas_event_thaw(evas_object_evas_get(obj));
305 //evas_event_thaw_eval(evas_object_evas_get(obj));
309 _item_cache_pop(Elm_Gen_Item *it)
311 Item_Cache *ic = NULL;
314 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
316 if (it->item->nocache_once) {
317 it->item->nocache_once = EINA_FALSE;
320 if (it->item->nocache) return EINA_FALSE;
322 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
323 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, ic)
325 if (ic->expanded) continue;
327 if ((ic->tree == tree) &&
328 (((!it->itc->item_style) && (!ic->item_style)) ||
329 (it->itc->item_style && ic->item_style &&
330 (!strcmp(it->itc->item_style, ic->item_style)))))
333 eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
334 sd->item_cache_count--;
336 VIEW(it) = ic->base_view;
337 it->spacer = ic->spacer;
338 it->item->multiline = ic->multiline;
340 edje_object_signal_callback_add
341 (VIEW(it), "elm,action,expand,toggle", "elm",
342 _expand_toggle_signal_cb, it);
343 edje_object_signal_callback_add
344 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
345 edje_object_signal_callback_add
346 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
347 _item_mouse_callbacks_add(it, VIEW(it));
349 eina_stringshare_del(ic->item_style);
359 _elm_genlist_pan_smart_pos_set(Evas_Object *obj,
365 ELM_GENLIST_PAN_DATA_GET(obj, psd);
367 if ((x == psd->wsd->pan_x) && (y == psd->wsd->pan_y)) return;
371 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
373 if ((itb->y + itb->h) > y)
378 EINA_LIST_FOREACH(itb->items, l2, it)
380 if ((itb->y + it->y) >= y)
382 psd->wsd->anchor_item = it;
383 psd->wsd->anchor_y = -(itb->y + it->y - y);
390 if (!psd->wsd->reorder_move_animator) evas_object_smart_changed(obj);
394 _elm_genlist_pan_smart_pos_get(const Evas_Object *obj,
398 ELM_GENLIST_PAN_DATA_GET(obj, psd);
400 if (x) *x = psd->wsd->pan_x;
401 if (y) *y = psd->wsd->pan_y;
405 _elm_genlist_pan_smart_pos_max_get(const Evas_Object *obj,
411 ELM_GENLIST_PAN_DATA_GET(obj, psd);
413 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
414 ow = psd->wsd->minw - ow;
416 oh = psd->wsd->minh - oh;
421 #if GENLIST_PINCH_ZOOM_SUPPORT
422 if (psd->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
424 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
425 if (psd->wsd->pinch_zoom_h > oh)
426 *y = psd->wsd->pinch_zoom_h - oh;
433 _elm_genlist_pan_smart_pos_min_get(const Evas_Object *obj __UNUSED__,
442 _elm_genlist_pan_smart_content_size_get(const Evas_Object *obj,
446 ELM_GENLIST_PAN_DATA_GET(obj, psd);
448 if (w) *w = psd->wsd->minw;
449 if (h) *h = psd->wsd->minh;
453 _elm_genlist_pan_smart_add(Evas_Object *obj)
455 /* here just to allocate our extended data */
456 EVAS_SMART_DATA_ALLOC(obj, Elm_Genlist_Pan_Smart_Data);
458 ELM_PAN_CLASS(_elm_genlist_pan_parent_sc)->base.add(obj);
462 _elm_genlist_pan_smart_del(Evas_Object *obj)
464 ELM_GENLIST_PAN_DATA_GET(obj, psd);
468 ecore_job_del(psd->resize_job);
469 psd->resize_job = NULL;
472 _elm_genlist_pan_parent_sc->base.del(obj);
476 _elm_genlist_pan_smart_move(Evas_Object *obj,
477 Evas_Coord x __UNUSED__,
478 Evas_Coord y __UNUSED__)
480 ELM_GENLIST_PAN_DATA_GET(obj, psd);
482 psd->wsd->pan_changed = EINA_TRUE;
483 evas_object_smart_changed(obj);
484 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
485 psd->wsd->calc_job = NULL;
489 _elm_genlist_pan_smart_resize(Evas_Object *obj,
491 Evas_Coord h __UNUSED__)
493 ELM_GENLIST_PAN_DATA_GET(obj, psd);
495 if (psd->wsd->mode == ELM_LIST_COMPRESS &&
496 psd->wsd->prev_viewport_w != w)
500 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
503 EINA_LIST_FOREACH(itb->items, l, it)
505 if (!it->item->multiline) continue;
506 it->item->mincalcd = EINA_FALSE;
507 _item_queue(psd->wsd, it, NULL, EINA_FALSE);
511 psd->wsd->prev_viewport_w = w;
513 psd->wsd->pan_changed = EINA_TRUE;
514 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
515 psd->wsd->calc_job = ecore_job_add(_calc_job, psd->wsd);
519 _item_scroll(Elm_Genlist_Smart_Data *sd)
522 Elm_Gen_Item *it = NULL;
523 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
525 if (!sd->show_item) return;
527 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &oh);
529 dx = it->x + it->item->block->x;
530 dy = it->y + it->item->block->y;
531 dw = it->item->block->w;
534 switch (sd->scroll_to_type)
536 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
537 if (it->item->group_item) gith = it->item->group_item->item->h;
541 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
542 dy += ((it->item->h / 2) - (oh / 2));
545 case ELM_GENLIST_ITEM_SCROLLTO_IN:
547 if ((sd->expanded_item) &&
548 ((sd->show_item->y + sd->show_item->item->block->y
549 + sd->show_item->item->h) -
550 (sd->expanded_item->y + sd->expanded_item->item->block->y) > oh))
552 it = sd->expanded_item;
553 if (it->item->group_item) gith = it->item->group_item->item->h;
554 dx = it->x + it->item->block->x;
555 dy = it->y + it->item->block->y - gith;
556 dw = it->item->block->w;
560 if ((it->item->group_item) &&
561 (sd->pan_y > (it->y + it->item->block->y)))
562 gith = it->item->group_item->item->h;
569 sd->s_iface->region_bring_in(ELM_WIDGET_DATA(sd)->obj, dx, dy, dw, dh);
571 sd->s_iface->content_region_show
572 (ELM_WIDGET_DATA(sd)->obj, dx, dy, dw, dh);
574 it->item->show_me = EINA_FALSE;
575 sd->show_item = NULL;
576 sd->auto_scroll_enabled = EINA_FALSE;
577 sd->check_scroll = EINA_FALSE;
581 _item_text_realize(Elm_Gen_Item *it,
585 if (it->itc->func.text_get)
590 source = elm_widget_stringlist_get
591 (edje_object_data_get(target, "texts"));
592 EINA_LIST_FREE(source, key)
594 if (parts && fnmatch(parts, key, FNM_PERIOD))
597 char *s = it->itc->func.text_get
598 ((void *)it->base.data, WIDGET(it), key);
602 edje_object_part_text_escaped_set(target, key, s);
607 edje_object_part_text_set(target, key, "");
613 #if GENLIST_ENTRY_SUPPORT
615 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
617 Elm_Gen_Item *it = data;
619 if (it->want_unrealize) return;
620 it->item->mincalcd = EINA_FALSE;
621 _item_queue(GL_IT(it)->wsd, it, NULL, EINA_FALSE);
625 // FIXME: There are applications which do not use elm_win as top widget.
626 // This is workaround! Those could not use focus!
627 static Eina_Bool _focus_enabled(Evas_Object *obj)
629 if (!elm_widget_focus_get(obj)) return EINA_FALSE;
631 const Evas_Object *win = elm_widget_top_get(obj);
632 const char *type = evas_object_type_get(win);
634 if (type && !strcmp(type, "elm_win"))
636 return elm_win_focus_highlight_enabled_get(win);
642 _item_content_realize(Elm_Gen_Item *it,
651 EINA_LIST_FREE(contents, c)
654 if (it->itc->func.content_get)
657 Evas_Object *ic = NULL;
660 source = elm_widget_stringlist_get
661 (edje_object_data_get(target, src));
663 EINA_LIST_FREE(source, key)
665 if (parts && fnmatch(parts, key, FNM_PERIOD))
668 Evas_Object *old = edje_object_part_swallow_get(target, key);
671 contents = eina_list_remove(contents, old);
672 evas_object_del(old);
675 if (it->itc->func.content_get)
676 ic = it->itc->func.content_get
677 ((void *)it->base.data, WIDGET(it), key);
680 if (!edje_object_part_swallow(target, key, ic))
682 WRN("%s (%p) can not be swallowed into %s",
683 evas_object_type_get(ic), ic, key);
687 if (elm_widget_item_disabled_get(it))
688 elm_widget_disabled_set(ic, EINA_TRUE);
689 evas_object_show(ic);
690 contents = eina_list_append(contents, ic);
691 #if GENLIST_ENTRY_SUPPORT
692 // For entry or editfield
693 // 1. Add resize callback for multiline entry.
694 // 2. Do not unrealize it for focus issue
695 // ps. Only for entry because of performnace
696 if (!strcmp("elm_entry", evas_object_type_get(ic)))
698 if (!elm_entry_single_line_get(ic))
699 evas_object_event_callback_add
700 (ic, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
701 _changed_size_hints, it);
702 it->item->unrealize_disabled = EINA_TRUE;
713 _item_state_realize(Elm_Gen_Item *it,
717 if (it->itc->func.state_get)
723 src = elm_widget_stringlist_get
724 (edje_object_data_get(target, "states"));
725 EINA_LIST_FREE(src, key)
727 if (parts && fnmatch(parts, key, FNM_PERIOD))
730 Eina_Bool on = it->itc->func.state_get
731 ((void *)it->base.data, WIDGET(it), key);
735 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
736 edje_object_signal_emit(target, buf, "elm");
740 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
741 edje_object_signal_emit(target, buf, "elm");
748 _view_create(Elm_Gen_Item *it, Evas_Object **view, const char *style)
751 const char *stacking_even;
752 const char *stacking;
757 *view = edje_object_add(evas_object_evas_get(WIDGET(it)));
758 evas_object_smart_member_add(*view, GL_IT(it)->wsd->pan_obj);
759 elm_widget_sub_object_add(WIDGET(it), *view);
760 edje_object_scale_set(*view, elm_widget_scale_get(WIDGET(it)) *
761 elm_config_scale_get());
764 if (it->item->type & ELM_GENLIST_ITEM_TREE)
765 snprintf(buf, sizeof(buf), "tree%s/%s",
766 GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS ? "_compress" : "",
767 style ? : "default");
769 snprintf(buf, sizeof(buf), "item%s/%s",
770 GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS ? "_compress" : "",
771 style ? : "default");
772 elm_widget_theme_object_set
773 (WIDGET(it), *view, "genlist", buf,
774 elm_widget_style_get(WIDGET(it)));
776 stacking_even = edje_object_data_get(*view, "stacking_even");
777 if (!stacking_even) stacking_even = "above";
778 it->item->stacking_even = !!strcmp("above", stacking_even);
780 stacking = edje_object_data_get(*view, "stacking");
781 if (!stacking) stacking = "yes";
782 it->item->nostacking = !!strcmp("yes", stacking);
784 Eina_List *txts = elm_widget_stringlist_get
785 (edje_object_data_get(*view, "texts"));
786 EINA_LIST_FREE(txts, key)
788 const Evas_Object *txt_obj = NULL;
789 const char *type = NULL;
790 txt_obj = edje_object_part_object_get(*view, key);
791 if (txt_obj) type = evas_object_type_get(txt_obj);
793 if (type && strcmp(type, "textblock")) continue;
795 const Evas_Textblock_Style *tb_style =
796 evas_object_textblock_style_get(txt_obj);
799 const char *str = evas_textblock_style_get(tb_style);
802 if (!strstr(str, "ellipsis="))
804 it->item->multiline = EINA_TRUE;
811 edje_object_mirrored_set(*view, elm_widget_mirrored_get(WIDGET(it)));
815 _view_inflate(Evas_Object *view, Elm_Gen_Item *it, Eina_List **contents)
818 _item_text_realize(it, view, NULL);
819 _item_state_realize(it, view, NULL);
820 *contents = _item_content_realize(it, view, *contents,
822 _item_state_realize(it, view, NULL);
826 _view_clear(Evas_Object *view, Eina_List **contents)
831 Eina_List *texts = elm_widget_stringlist_get
832 (edje_object_data_get(view, "texts"));
833 EINA_LIST_FREE(texts, part)
834 edje_object_part_text_set(view, part, NULL);
835 EINA_LIST_FREE(*contents, c)
837 // FIXME: For animation, befor del, processing edc.
838 if (evas_object_smart_type_check(c, "elm_layout"))
839 edje_object_message_signal_process(elm_layout_edje_get(c));
840 // FIXME: If parent-child relationship was broken before 'ic'
841 // is deleted, freeze_pop will not be called. ex) elm_slider
842 // If layout is used instead of edje, this problme can be
844 if (0 != elm_widget_scroll_freeze_get(c))
845 elm_widget_scroll_freeze_pop(c);
851 _item_min_calc(Elm_Gen_Item *it, Eina_Bool *width_changed, Eina_Bool *height_changed)
853 if (it->item->mincalcd) return;
855 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
856 Evas_Coord mw = 0, mh = 0;
857 Size_Cache *size = NULL;
860 size = eina_hash_find(GL_IT(it)->wsd->size_caches,
861 it->itc->item_style);
870 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
872 mw = sd->finger_minw;
873 mh = sd->finger_minh;
875 if ((sd->mode == ELM_LIST_COMPRESS) && (sd->prev_viewport_w != 0) &&
876 (mw < sd->prev_viewport_w))
877 mw = sd->prev_viewport_w;
878 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
882 size = ELM_NEW(Size_Cache);
885 eina_hash_add(sd->size_caches, it->itc->item_style, size);
889 if (it->item->minw != mw)
892 if (it->item->block->minw > mw)
893 it->item->block->minw = it->item->block->w = mw;
895 it->item->w = it->item->minw = mw;
896 if (width_changed) *width_changed = EINA_TRUE;
898 if (it->item->minh != mh)
901 it->item->block->minh += (mh - it->item->minh);
903 it->item->h = it->item->minh = mh;
904 it->item->block->changed = EINA_TRUE;
905 if (height_changed) *height_changed = EINA_TRUE;
907 it->item->mincalcd = EINA_TRUE;
911 _elm_genlist_item_decorate_state_update(Elm_Gen_Item *it)
913 if (GL_IT(it)->wsd->decorate_all_mode)
915 edje_object_signal_emit
916 (VIEW(it), "elm,state,decorate,enabled", "elm");
917 if (it->deco_all_view)
918 edje_object_signal_emit
919 (it->deco_all_view, "elm,state,decorate,enabled", "elm");
924 _elm_genlist_item_reorder_state_update(Elm_Gen_Item *it)
926 if (GL_IT(it)->wsd->reorder_mode)
928 edje_object_signal_emit
929 (VIEW(it), "elm,state,reorder,mode_set", "elm");
930 if (it->deco_all_view)
931 edje_object_signal_emit
932 (it->deco_all_view, "elm,state,reorder,mode_set", "elm");
937 _elm_genlist_item_normal_state_update(Elm_Gen_Item *it)
939 if (elm_widget_item_disabled_get(it))
941 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
942 if (it->deco_all_view)
943 edje_object_signal_emit
944 (it->deco_all_view, "elm,state,disabled", "elm");
948 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
949 if (it->deco_all_view)
950 edje_object_signal_emit
951 (it->deco_all_view, "elm,state,selected", "elm");
952 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
954 if (it->item->expanded)
956 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
957 if (it->deco_all_view)
958 edje_object_signal_emit
959 (it->deco_all_view, "elm,state,expanded", "elm");
963 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
964 if (GL_IT(it)->wsd->decorate_all_mode)
965 edje_object_signal_emit
966 (it->deco_all_view, "elm,state,flip,enabled", "elm");
967 else if (it->item->deco_it_view)
968 edje_object_signal_emit
969 (it->item->deco_it_view, "elm,state,flip,enabled", "elm");
971 if (it->item->expanded_depth > 0)
972 edje_object_signal_emit(VIEW(it), "bg_color_change", "elm");
974 if (_focus_enabled(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj) &&
975 (it == GL_IT(it)->wsd->focused))
977 edje_object_signal_emit(VIEW(it), "elm,state,focused", "elm");
982 _elm_genlist_item_state_update(Elm_Gen_Item *it)
984 _elm_genlist_item_decorate_state_update(it);
985 _elm_genlist_item_reorder_state_update(it);
986 _elm_genlist_item_normal_state_update(it);
990 _elm_genlist_item_index_update(Elm_Gen_Item *it)
992 if (it->position_update || it->item->block->position_update)
994 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
995 it->position_update = EINA_FALSE;
1000 _item_access_highlight(Elm_Gen_Item *it)
1002 if (!it) return EINA_FALSE;
1003 Evas_Object *acc = elm_object_item_access_object_get((Elm_Object_Item *)it);
1006 const Eina_List *l = elm_object_item_access_order_get((Elm_Object_Item *)it);
1007 // FIXME: Currenlty only first access order is processed.
1008 if (l) acc = eina_list_nth(l, 0);
1010 if (!acc) return EINA_FALSE;
1012 _elm_access_highlight_set(acc, EINA_FALSE);
1013 GL_IT(it)->wsd->access_it = it;
1018 _item_access_show(Elm_Gen_Item *it)
1020 GL_IT(it)->wsd->access_bring_it = it;
1021 elm_genlist_item_bring_in((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_IN);
1025 _item_access_next(Elm_Gen_Item *it, Elm_Focus_Direction dir)
1027 if (!it) return EINA_FALSE;
1030 if (!_item_access_highlight(it))
1032 Elm_Gen_Item *next = it;
1033 if (dir == ELM_FOCUS_NEXT)
1037 next = (Elm_Gen_Item *)elm_genlist_item_next_get
1038 ((Elm_Object_Item *)next);
1041 if (next->realized && _item_access_highlight(next))
1043 else if (!next->realized)
1045 _item_access_show(next);
1056 next = (Elm_Gen_Item *)elm_genlist_item_prev_get
1057 ((Elm_Object_Item *)next);
1060 if (next->realized && _item_access_highlight(next))
1062 else if (!next->realized)
1064 _item_access_show(next);
1073 else _item_access_show(it);
1078 _item_unrealize(Elm_Gen_Item *it,
1081 Evas_Object *content;
1083 if (!it->realized) return;
1084 if (GL_IT(it)->wsd->reorder_it == it) return;
1086 #if GENLIST_FX_SUPPORT
1087 if ((GL_IT(it)->has_proxy_it) && (!GL_IT(it)->wsd->genlist_clearing))
1089 if (!eina_list_data_find(GL_IT(it)->wsd->pending_unrealized_items, it))
1090 GL_IT(it)->wsd->pending_unrealized_items =
1091 eina_list_append(GL_IT(it)->wsd->pending_unrealized_items, it);
1095 #if GENLIST_ENTRY_SUPPORT
1096 if (it->item->unrealize_disabled)
1098 evas_object_hide(VIEW(it));
1104 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
1106 _item_event_del(it);
1107 _view_clear(VIEW(it), &(it->content_objs));
1108 EINA_LIST_FREE(it->item->flip_content_objs, content)
1109 evas_object_del(content);
1112 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON && !calc)
1114 if (GL_IT(it)->wsd->access_it == it)
1116 GL_IT(it)->wsd->access_it = NULL;
1117 GL_IT(it)->wsd->access_unrealize_it = it;
1119 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1122 _decorate_item_unrealize(it);
1123 _decorate_all_item_unrealize(it);
1125 _item_cache_push(it);
1126 it->realized = EINA_FALSE;
1127 it->want_unrealize = EINA_FALSE;
1129 #if GENLIST_ENTRY_SUPPORT
1130 it->item->unrealize_disabled = EINA_FALSE;
1135 _item_block_unrealize(Item_Block *itb)
1139 Eina_Bool dragging = EINA_FALSE;
1141 if (!itb->realized) return;
1142 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
1144 EINA_LIST_FOREACH(itb->items, l, it)
1148 dragging = EINA_TRUE;
1149 it->want_unrealize = EINA_TRUE;
1152 _item_unrealize(it, EINA_FALSE);
1156 itb->realized = EINA_FALSE;
1157 itb->want_unrealize = EINA_TRUE;
1160 itb->want_unrealize = EINA_FALSE;
1161 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
1162 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
1166 _must_recalc_idler(void *data)
1168 Elm_Genlist_Smart_Data *sd = data;
1170 if (sd->calc_job) ecore_job_del(sd->calc_job);
1171 sd->calc_job = ecore_job_add(_calc_job, sd);
1172 sd->must_recalc_idler = NULL;
1173 return ECORE_CALLBACK_CANCEL;
1177 _calc_job(void *data)
1180 Item_Block *itb, *chb = NULL;
1181 Evas_Coord pan_w = 0, pan_h = 0;
1182 Elm_Genlist_Smart_Data *sd = data;
1183 Eina_Bool minw_change = EINA_FALSE;
1184 Eina_Bool did_must_recalc = EINA_FALSE;
1185 Evas_Coord minw = -1, minh = 0, y = 0, dy = 0, vw = 0;
1187 sd->calc_job = NULL;
1190 WRN("This should not be happened! Something wrong");
1193 sd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(sd)->obj, &sd->w, &sd->h);
1195 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1196 EINA_INLIST_FOREACH(sd->blocks, itb)
1198 Eina_Bool show_me = EINA_FALSE;
1201 show_me = itb->show_me;
1202 itb->show_me = EINA_FALSE;
1205 if (itb->realized) _item_block_unrealize(itb);
1207 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
1209 if (itb->must_recalc)
1214 EINA_LIST_FOREACH(itb->items, l, it)
1215 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
1216 itb->changed = EINA_TRUE;
1217 did_must_recalc = EINA_TRUE;
1218 if (itb->realized) _item_block_unrealize(itb);
1219 itb->must_recalc = EINA_FALSE;
1221 show_me = _item_block_recalc(itb, in, EINA_FALSE);
1227 if (minw == -1) minw = itb->minw;
1228 else if ((!itb->must_recalc) && (minw < itb->minw))
1231 minw_change = EINA_TRUE;
1233 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
1236 minw_change = EINA_TRUE;
1242 if ((show_me) && (sd->show_item) && (!sd->show_item->item->queued))
1243 sd->check_scroll = EINA_TRUE;
1247 EINA_INLIST_FOREACH(sd->blocks, itb)
1253 if ((chb) && (EINA_INLIST_GET(chb)->next))
1255 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
1257 if (itb->realized) _item_block_unrealize(itb);
1260 sd->realminw = minw;
1261 if (minw < sd->w) minw = sd->w;
1262 if ((minw != sd->minw) || (minh != sd->minh))
1266 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
1267 elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
1271 it = sd->reorder_it;
1274 if ((sd->anchor_item) && (sd->anchor_item->item->block)
1275 && (!sd->auto_scroll_enabled))
1280 it = sd->anchor_item;
1281 it_y = sd->anchor_y;
1282 sd->s_iface->content_pos_set
1283 (ELM_WIDGET_DATA(sd)->obj, sd->pan_x, it->item->block->y
1284 + it->y + it_y, EINA_TRUE);
1285 sd->anchor_item = it;
1286 sd->anchor_y = it_y;
1289 if (did_must_recalc)
1291 if (!sd->must_recalc_idler)
1292 sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, sd);
1294 if (sd->check_scroll && sd->show_item && sd->show_item->item->block)
1296 _elm_genlist_pan_smart_content_size_get(sd->pan_obj, &pan_w, &pan_h);
1297 if (sd->items && (EINA_INLIST_GET(sd->show_item) == sd->items->last))
1298 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
1300 if (sd->scroll_to_type == ELM_GENLIST_ITEM_SCROLLTO_TOP)
1304 else if (sd->scroll_to_type == ELM_GENLIST_ITEM_SCROLLTO_MIDDLE)
1313 if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
1314 && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
1321 evas_object_smart_changed(sd->pan_obj);
1322 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1323 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1327 _elm_genlist_smart_sizing_eval(Evas_Object *obj)
1329 Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1, vw = 0;
1331 ELM_GENLIST_DATA_GET(obj, sd);
1333 /* parent class' early call */
1334 if (!sd->s_iface) return;
1335 if (sd->on_sub_del) return;;
1337 evas_object_size_hint_min_get(obj, &minw, NULL);
1338 evas_object_size_hint_max_get(obj, &maxw, &maxh);
1339 edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
1341 sd->s_iface->content_viewport_size_get(obj, &vw, NULL);
1342 if (vw != 0) sd->prev_viewport_w = vw;
1344 if (sd->mode == ELM_LIST_LIMIT)
1347 minw = minw + sd->realminw;
1350 evas_object_size_hint_min_set(obj, minw, minh);
1351 evas_object_size_hint_max_set(obj, maxw, maxh);
1355 _item_position(Elm_Gen_Item *it,
1362 evas_object_resize(view, it->item->w, it->item->h);
1363 evas_object_move(view, it_x, it_y);
1364 evas_object_show(view);
1368 _item_sub_items_clear(Elm_Gen_Item *it)
1371 Elm_Object_Item *it2;
1373 EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, it2)
1374 elm_widget_item_del(it2);
1378 _item_auto_scroll(Elm_Genlist_Smart_Data *sd)
1380 Elm_Gen_Item *tmp_item = NULL;
1382 #if GENLIST_FX_SUPPORT
1383 if (sd->fx_first_captured) return;
1385 if ((sd->expanded_item) && (sd->auto_scroll_enabled))
1387 tmp_item = eina_list_data_get
1388 (eina_list_last(sd->expanded_item->item->items));
1389 if (!tmp_item) return;
1390 sd->show_item = tmp_item;
1391 sd->bring_in = EINA_TRUE;
1392 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
1393 if ((sd->show_item->item->queued) || (!sd->show_item->item->mincalcd))
1395 sd->show_item->item->show_me = EINA_TRUE;
1396 sd->auto_scroll_enabled = EINA_FALSE;
1404 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1406 if (!it->item->nostacking)
1408 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1410 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1411 else evas_object_lower(VIEW(it));
1415 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1416 else evas_object_raise(VIEW(it));
1420 if (it->item->order_num_in & 0x1)
1422 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1423 if (it->deco_all_view)
1424 edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1428 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1429 if (it->deco_all_view)
1430 edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1435 _item_order_update(const Eina_Inlist *l,
1438 Elm_Gen_Item *it, *it2;
1440 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next,
1441 it = ELM_GEN_ITEM_FROM_INLIST(l))
1443 it->item->order_num_in = start++;
1444 _elm_genlist_item_odd_even_update(it);
1445 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
1446 if (it2 && (it->item->order_num_in != it2->item->order_num_in))
1452 _decorate_item_unrealize(Elm_Gen_Item *it)
1454 if (!it->item->deco_it_view) return;
1456 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
1457 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
1458 _item_mouse_callbacks_add(it, VIEW(it));
1460 _item_mouse_callbacks_del(it, it->item->deco_it_view);
1461 _view_clear(it->item->deco_it_view, &(it->item->deco_it_contents));
1462 evas_object_del(it->item->deco_it_view);
1463 it->item->deco_it_view = NULL;
1467 _decorate_all_item_realize(Elm_Gen_Item *it)
1469 if (it->deco_all_view || !it->itc->decorate_all_item_style) return;
1471 _view_create(it, &(it->deco_all_view), it->itc->decorate_all_item_style);
1472 _view_inflate(it->deco_all_view, it, &(it->item->deco_all_contents));
1473 _item_mouse_callbacks_add(it, it->deco_all_view);
1475 _item_mouse_callbacks_del(it, VIEW(it));
1476 evas_object_smart_member_del(VIEW(it));
1477 edje_object_part_swallow
1478 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1480 it->want_unrealize = EINA_FALSE;
1482 // FIXME: Belows are needed? _decorate_item_realize do not
1483 _elm_genlist_item_odd_even_update(it);
1484 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->scrl_y);
1485 evas_object_show(it->deco_all_view);
1489 _expand_toggle_signal_cb(void *data,
1490 Evas_Object *obj __UNUSED__,
1491 const char *emission __UNUSED__,
1492 const char *source __UNUSED__)
1494 Elm_Gen_Item *it = data;
1496 if (it->item->expanded)
1497 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1499 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1503 _expand_signal_cb(void *data,
1504 Evas_Object *obj __UNUSED__,
1505 const char *emission __UNUSED__,
1506 const char *source __UNUSED__)
1508 Elm_Gen_Item *it = data;
1510 if (!it->item->expanded)
1511 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1515 _contract_signal_cb(void *data,
1516 Evas_Object *obj __UNUSED__,
1517 const char *emission __UNUSED__,
1518 const char *source __UNUSED__)
1520 Elm_Gen_Item *it = data;
1522 if (it->item->expanded)
1523 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1527 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
1532 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1533 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1535 buf = eina_strbuf_new();
1537 if (it->itc->func.text_get)
1544 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1546 EINA_LIST_FOREACH(texts, l, key)
1548 char *s = it->itc->func.text_get
1549 ((void *)it->base.data, WIDGET(it), key);
1551 s = _elm_util_mkup_to_text(s);
1555 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1556 eina_strbuf_append(buf, s);
1562 ret = eina_strbuf_string_steal(buf);
1563 eina_strbuf_free(buf);
1568 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
1570 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1571 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1573 if (it->base.disabled)
1574 return strdup(E_("State: Disabled"));
1580 _access_on_highlight_cb(void *data)
1582 Evas_Coord x, y, w, h, cx, cy, cw, ch;
1583 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1584 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1586 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
1588 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
1589 evas_object_geometry_get(WIDGET(it), &cx, &cy, &cw, &ch);
1590 // XXX There would be a reason.
1591 if ((w == 0) && (h == 0)) return;
1594 sd->access_bring_it = NULL;
1595 sd->access_unrealize_it = NULL;
1596 if (!ELM_RECTS_INTERSECT(x, y - h, w, h, cx, cy, cw, ch) ||
1597 !ELM_RECTS_INTERSECT(x, y + h, w, h, cx, cy, cw, ch))
1598 elm_genlist_item_bring_in((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_IN);
1602 _access_widget_item_register(Elm_Gen_Item *it)
1604 Elm_Access_Info *ai;
1606 _elm_access_widget_item_register((Elm_Widget_Item *)it);
1608 ai = _elm_access_object_get(it->base.access_obj);
1610 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1611 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1612 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
1613 _elm_access_activate_callback_set(ai, _access_activate_cb, it);
1617 _item_realize(Elm_Gen_Item *it,
1621 const char *treesize;
1626 if (it->item->order_num_in != in)
1628 _item_order_update(EINA_INLIST_GET(it), in);
1629 _elm_genlist_item_state_update(it);
1630 _elm_genlist_item_index_update(it);
1634 it->item->order_num_in = in;
1636 if (it->item->nocache_once || it->item->nocache ||
1637 it->item->type == ELM_GENLIST_ITEM_TREE || it->parent ||
1638 !_item_cache_pop(it))
1640 _view_create(it, &(VIEW(it)), it->itc->item_style);
1642 edje_object_signal_callback_add
1643 (VIEW(it), "elm,action,expand,toggle", "elm",
1644 _expand_toggle_signal_cb, it);
1645 edje_object_signal_callback_add
1646 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1647 edje_object_signal_callback_add
1648 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1649 _item_mouse_callbacks_add(it, VIEW(it));
1652 _item_order_update(EINA_INLIST_GET(it), in);
1653 _elm_genlist_item_index_update(it);
1655 treesize = edje_object_data_get(VIEW(it), "treesize");
1656 if (treesize) tsize = atoi(treesize);
1657 if (it->parent && GL_IT(it->parent)->type == ELM_GENLIST_ITEM_TREE &&
1658 !it->spacer && treesize)
1661 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1662 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1666 evas_object_size_hint_min_set
1667 (it->spacer, (it->item->expanded_depth * tsize) *
1668 elm_config_scale_get(), 1);
1669 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1671 if (!calc || !it->item->mincalcd)
1673 _view_clear(VIEW(it), &(it->content_objs));
1674 _view_inflate(VIEW(it), it, &it->content_objs);
1676 if (GL_IT(it)->wsd->decorate_all_mode &&
1677 it->itc->decorate_all_item_style)
1679 if (!it->deco_all_view)
1680 _decorate_all_item_realize(it);
1683 if (it->decorate_it_set && it->itc->decorate_item_style)
1685 if (!it->item->deco_it_view)
1686 _decorate_item_set(it);
1690 it->item->flip_content_objs =
1691 _item_content_realize(it, VIEW(it), it->item->flip_content_objs,
1695 // FIXME: Is this needed?
1696 evas_object_show(VIEW(it));
1698 _item_min_calc(it, NULL, NULL);
1699 _elm_genlist_item_state_update(it);
1701 if (it->tooltip.content_cb)
1703 elm_widget_item_tooltip_content_cb_set
1704 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
1705 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1706 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1709 if (it->mouse_cursor)
1710 elm_widget_item_cursor_set(it, it->mouse_cursor);
1712 it->realized = EINA_TRUE;
1713 it->want_unrealize = EINA_FALSE;
1715 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON && !calc)
1717 /* access: unregister item which have no text and content */
1718 Eina_List *texts = elm_widget_stringlist_get
1719 (edje_object_data_get(VIEW(it), "texts"));
1720 Eina_List *contents = elm_widget_stringlist_get
1721 (edje_object_data_get(VIEW(it), "contents"));
1722 if (_elm_config->access_mode && !texts && !contents)
1723 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1725 if (_elm_config->access_mode) _access_widget_item_register(it);
1726 eina_list_free(texts);
1727 eina_list_free(contents);
1730 if (!calc || it->item->unrealize_disabled)
1731 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1733 // FIXME: this should be after realized callback because app can reset
1734 // the access objects
1735 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON && !calc &&
1736 (GL_IT(it)->wsd->access_bring_it == it))
1738 _item_access_highlight(it);
1739 GL_IT(it)->wsd->access_bring_it = NULL;
1741 edje_object_message_signal_process(VIEW(it));
1742 if (it->deco_all_view)
1743 edje_object_message_signal_process(it->deco_all_view);
1746 #if GENLIST_PINCH_ZOOM_SUPPORT
1748 _pinch_items_recalc(void *data)
1750 Elm_Genlist_Smart_Data *sd = data;
1755 Evas_Coord tot_y = 0, ox, oy;
1756 evas_object_geometry_get(sd->pan_obj, &ox, &oy, NULL, NULL);
1758 EINA_INLIST_FOREACH(sd->blocks, itb)
1760 EINA_LIST_FOREACH(itb->items, l, it)
1763 if (IS_ROOT_PARENT_IT(it))
1765 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
1767 if (!it->realized) _item_realize(it, 0, EINA_FALSE);
1768 it->item->scrl_y = oy + tot_y - sd->pan_y;
1769 evas_object_resize(VIEW(it), sd->minw, it->item->h);
1770 evas_object_move(VIEW(it), it->item->scrl_x, it->item->scrl_y);
1771 evas_object_show(VIEW(it));
1772 evas_object_raise(VIEW(it));
1773 tot_y += it->item->h;
1774 sd->pinch_zoom_h = tot_y;
1777 else if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND)
1779 evas_object_resize(VIEW(it), sd->minw, it->item->h);
1780 it->item->scrl_y = oy + it->item->pan_scrl_y - sd->pan_y;
1781 evas_object_move(VIEW(it), it->item->scrl_x, it->item->scrl_y);
1790 #if GROUP_ITEMS_FEATURE
1792 _group_items_recalc(void *data)
1796 Elm_Genlist_Smart_Data *sd = data;
1798 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1799 EINA_LIST_FOREACH(sd->group_items, l, git)
1801 if (git->item->want_realize)
1803 if (!git->realized) _item_realize(git, 0, EINA_FALSE);
1804 evas_object_resize(VIEW(git), sd->minw, git->item->h);
1805 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
1806 evas_object_show(VIEW(git));
1807 evas_object_raise(VIEW(git));
1809 else if (!git->item->want_realize)
1812 _item_unrealize(git, EINA_FALSE);
1815 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1816 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1821 _reorder_move_animator_cb(void *data)
1824 Elm_Gen_Item *it = data;
1825 Eina_Bool down = EINA_FALSE;
1828 dy = 20 * elm_config_scale_get();
1829 t = ((0.0 > (t = ecore_loop_time_get()
1830 - GL_IT(it)->wsd->start_time)) ? 0.0 : t);
1832 if (t <= REORDER_EFFECT_TIME)
1833 y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
1836 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
1837 if (diff < dy) y = diff;
1839 if (it->item->old_scrl_y < it->item->scrl_y)
1841 it->item->old_scrl_y += y;
1844 else if (it->item->old_scrl_y > it->item->scrl_y)
1846 it->item->old_scrl_y -= y;
1850 if (it->deco_all_view)
1852 (it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
1853 else if (it->item->deco_it_view)
1855 (it, it->item->deco_it_view, it->item->scrl_x, it->item->old_scrl_y);
1857 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
1859 if ((GL_IT(it)->wsd->reorder_pan_move) ||
1860 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
1861 (!down && it->item->old_scrl_y <= it->item->scrl_y))
1863 it->item->old_scrl_y = it->item->scrl_y;
1864 it->item->move_effect_enabled = EINA_FALSE;
1865 GL_IT(it)->wsd->reorder_move_animator = NULL;
1866 return ECORE_CALLBACK_CANCEL;
1869 return ECORE_CALLBACK_RENEW;
1873 _reorder_item_space_get(Elm_Gen_Item *it)
1875 Elm_Gen_Item *reorder_it = GL_IT(it)->wsd->reorder_it;
1876 Evas_Coord rox, roy, row, roh, oy, oh;
1877 Eina_Bool top = EINA_FALSE;
1879 if (!reorder_it) return 0;
1880 if(it->deco_all_view) evas_object_lower(it->deco_all_view);
1882 evas_object_geometry_get(GL_IT(it)->wsd->pan_obj, NULL, &oy, NULL, &oh);
1883 evas_object_geometry_get
1884 (GL_IT(it)->wsd->VIEW(reorder_it), &rox, &roy, &row, &roh);
1886 if ((GL_IT(it)->wsd->reorder_start_y < it->item->block->y) &&
1887 (roy - oy + (roh / 2) >= it->item->block->y - GL_IT(it)->wsd->pan_y))
1889 it->item->block->reorder_offset =
1890 GL_IT(it)->wsd->reorder_it->item->h * -1;
1891 if (it->item->block->count == 1)
1892 GL_IT(it)->wsd->reorder_rel = it;
1894 else if ((GL_IT(it)->wsd->reorder_start_y >= it->item->block->y) &&
1895 (roy - oy + (roh / 2) <= it->item->block->y -
1896 GL_IT(it)->wsd->pan_y))
1898 it->item->block->reorder_offset = GL_IT(it)->wsd->reorder_it->item->h;
1901 it->item->block->reorder_offset = 0;
1903 it->item->scrl_y += it->item->block->reorder_offset;
1905 top = (ELM_RECTS_INTERSECT
1906 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
1907 rox, roy + (roh / 2), row, 1));
1910 GL_IT(it)->wsd->reorder_rel = it;
1911 it->item->scrl_y += GL_IT(it)->wsd->reorder_it->item->h;
1912 return GL_IT(it)->wsd->reorder_it->item->h;
1919 _item_block_position(Item_Block *itb,
1925 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
1927 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
1928 evas_object_geometry_get(itb->sd->pan_obj, &ox, &oy, &ow, &oh);
1929 evas_output_viewport_get
1930 (evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj),
1931 &cvx, &cvy, &cvw, &cvh);
1933 EINA_LIST_FOREACH(itb->items, l, it)
1935 if ((GL_IT(it)->wsd->reorder_it == it) && it->highlighted) continue;
1939 it->item->w = itb->w;
1940 it->item->scrl_x = itb->x + it->x - GL_IT(it)->wsd->pan_x + ox;
1941 it->item->scrl_y = itb->y + it->y - GL_IT(it)->wsd->pan_y + oy;
1943 if ((ELM_RECTS_INTERSECT
1944 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
1945 cvx, cvy, cvw, cvh))
1946 #if GENLIST_ENTRY_SUPPORT
1947 || it->item->unrealize_disabled
1951 if (itb->realized && !(it->realized))
1952 _item_realize(it, in, EINA_FALSE);
1953 #if GENLIST_ENTRY_SUPPORT
1954 evas_object_show(VIEW(it));
1956 if (GL_IT(it)->wsd->reorder_mode &&
1957 GL_IT(it)->wsd->reorder_it &&
1958 GL_IT(it)->wsd->reorder_it->highlighted)
1959 y += _reorder_item_space_get(it);
1960 git = it->item->group_item;
1963 if (git->item->scrl_y < oy)
1964 git->item->scrl_y = oy;
1965 if ((git->item->scrl_y + git->item->h) >
1966 (it->item->scrl_y + it->item->h))
1967 git->item->scrl_y = (it->item->scrl_y +
1968 it->item->h) - git->item->h;
1969 git->item->scrl_x = it->item->scrl_x;
1970 git->item->want_realize = EINA_TRUE;
1972 if ((GL_IT(it)->wsd->reorder_it) &&
1973 GL_IT(it)->wsd->reorder_it->highlighted &&
1974 (it->item->old_scrl_y != it->item->scrl_y))
1976 if (!it->item->move_effect_enabled)
1978 it->item->move_effect_enabled = EINA_TRUE;
1979 GL_IT(it)->wsd->reorder_move_animator =
1980 ecore_animator_add(_reorder_move_animator_cb, it);
1983 if (!it->item->move_effect_enabled)
1985 if ((GL_IT(it)->wsd->decorate_all_mode) &&
1986 (it->itc->decorate_all_item_style))
1987 _item_position(it, it->deco_all_view,
1988 it->item->scrl_x, it->item->scrl_y);
1991 if (it->item->deco_it_view)
1993 (it, it->item->deco_it_view,
1998 (it, VIEW(it), it->item->scrl_x,
2001 it->item->old_scrl_y = it->item->scrl_y;
2002 #if GENLIST_PINCH_ZOOM_SUPPORT
2003 if (((GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
2004 && (!IS_ROOT_PARENT_IT(it))) || (GL_IT(it)->wsd->sorting))
2006 if (it->deco_all_view) evas_object_hide(it->deco_all_view);
2007 else evas_object_hide(VIEW(it));
2012 else if (it->realized && !(it->dragging))
2014 if ((GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
2015 && (!IS_ROOT_PARENT_IT(it)))
2017 if (it->deco_all_view) evas_object_hide(it->deco_all_view);
2018 else evas_object_hide(VIEW(it));
2021 _item_unrealize(it, EINA_FALSE);
2027 // FIXME: diffrence from upstream
2028 minh += it->item->minh;
2032 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
2033 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
2037 _item_block_realize(Item_Block *itb)
2039 if (itb->realized) return;
2041 itb->realized = EINA_TRUE;
2042 itb->want_unrealize = EINA_FALSE;
2048 Elm_Genlist_Smart_Data *sd = data;
2049 _elm_genlist_fx_play(ELM_WIDGET_DATA(sd)->obj);
2054 _item_block_calc(Item_Block *itb)
2058 Evas_Coord minh = 0;
2062 EINA_LIST_FOREACH(itb->items, l, it)
2066 _item_realize(it, in, EINA_TRUE);
2067 _item_unrealize(it, EINA_TRUE);
2070 _item_min_calc(it, NULL, NULL);
2073 minh += it->item->minh;
2074 if (itb->minw > it->item->minw) itb->minw = it->item->minw;
2077 itb->changed = EINA_FALSE;
2078 itb->position_update = EINA_FALSE;
2082 _elm_genlist_pan_smart_calculate(Evas_Object *obj)
2084 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2085 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
2089 ELM_GENLIST_PAN_DATA_GET(obj, psd);
2091 //evas_event_freeze(evas_object_evas_get(obj));
2093 #if GENLIST_FX_SUPPORT
2094 if (psd->wsd->fx_playing) return;
2096 if (psd->wsd->pan_changed)
2098 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
2099 _calc_job(psd->wsd);
2100 psd->wsd->pan_changed = EINA_FALSE;
2103 #if GROUP_ITEMS_FEATURE
2104 EINA_LIST_FOREACH(psd->wsd->group_items, l, git)
2105 git->item->want_realize = EINA_FALSE;
2108 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2109 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2110 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
2112 itb->w = psd->wsd->minw;
2113 if (ELM_RECTS_INTERSECT(itb->x - psd->wsd->pan_x + ox,
2114 itb->y - psd->wsd->pan_y + oy,
2116 cvx, cvy, cvw, cvh))
2118 if ((!itb->realized) || (itb->changed))
2120 _item_block_realize(itb);
2122 _item_block_position(itb, in);
2124 else if (itb->realized)
2126 _item_block_unrealize(itb);
2130 #if GENLIST_PINCH_ZOOM_SUPPORT
2131 if (psd->wsd->pinch_zoom_mode) _pinch_items_recalc(psd->wsd);
2134 #if GROUP_ITEMS_FEATURE
2135 if ((!psd->wsd->reorder_it) || (psd->wsd->reorder_pan_move))
2136 _group_items_recalc(psd->wsd);
2138 if ((psd->wsd->reorder_mode) && (psd->wsd->reorder_it))
2140 if (psd->wsd->pan_y != psd->wsd->reorder_old_pan_y)
2141 psd->wsd->reorder_pan_move = EINA_TRUE;
2142 else psd->wsd->reorder_pan_move = EINA_FALSE;
2144 evas_object_raise(psd->wsd->VIEW(reorder_it));
2145 psd->wsd->reorder_old_pan_y = psd->wsd->pan_y;
2146 psd->wsd->start_time = ecore_loop_time_get();
2148 _item_auto_scroll(psd->wsd);
2150 psd->wsd->s_iface->content_pos_get(ELM_WIDGET_DATA(psd->wsd)->obj, &vx, &vy);
2151 psd->wsd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(psd->wsd)->obj,
2154 if (psd->wsd->reorder_fast == 1)
2155 psd->wsd->s_iface->content_region_show(ELM_WIDGET_DATA(psd->wsd)->obj,
2156 vx,vy - 10, vw, vh);
2157 else if (psd->wsd->reorder_fast == -1)
2158 psd->wsd->s_iface->content_region_show(ELM_WIDGET_DATA(psd->wsd)->obj,
2159 vx, vy + 10, vw, vh);
2161 #if GENLIST_FX_SUPPORT
2162 psd->wsd->rendered = EINA_TRUE;
2163 if ((psd->wsd->fx_mode) && (!psd->wsd->queue))
2165 _elm_genlist_fx_capture(ELM_WIDGET_DATA(psd->wsd)->obj, 1);
2166 if (psd->wsd->fx_job) ecore_job_del(psd->wsd->fx_job);
2167 psd->wsd->fx_job = ecore_job_add(_fx_job, psd->wsd);
2170 #if GENLIST_PINCH_ZOOM_SUPPORT
2171 if (psd->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND)
2172 psd->wsd->pinch_zoom_mode = ELM_GEN_PINCH_ZOOM_NONE;
2174 //evas_event_thaw(evas_object_evas_get(obj));
2175 //evas_event_thaw_eval(evas_object_evas_get(obj));
2179 _elm_genlist_pan_smart_set_user(Elm_Genlist_Pan_Smart_Class *sc)
2181 ELM_PAN_CLASS(sc)->base.add = _elm_genlist_pan_smart_add;
2182 ELM_PAN_CLASS(sc)->base.del = _elm_genlist_pan_smart_del;
2183 ELM_PAN_CLASS(sc)->base.move = _elm_genlist_pan_smart_move;
2184 ELM_PAN_CLASS(sc)->base.resize = _elm_genlist_pan_smart_resize;
2185 ELM_PAN_CLASS(sc)->base.calculate = _elm_genlist_pan_smart_calculate;
2187 ELM_PAN_CLASS(sc)->pos_set = _elm_genlist_pan_smart_pos_set;
2188 ELM_PAN_CLASS(sc)->pos_get = _elm_genlist_pan_smart_pos_get;
2189 ELM_PAN_CLASS(sc)->pos_max_get = _elm_genlist_pan_smart_pos_max_get;
2190 ELM_PAN_CLASS(sc)->pos_min_get = _elm_genlist_pan_smart_pos_min_get;
2191 ELM_PAN_CLASS(sc)->content_size_get =
2192 _elm_genlist_pan_smart_content_size_get;
2196 _item_multi_select_up(Elm_Genlist_Smart_Data *sd)
2198 Elm_Object_Item *prev;
2200 if (!sd->selected) return EINA_FALSE;
2201 if (!sd->multi) return EINA_FALSE;
2203 prev = elm_genlist_item_prev_get(sd->last_selected_item);
2204 if (!prev) return EINA_TRUE;
2206 if (elm_genlist_item_selected_get(prev))
2208 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2209 sd->last_selected_item = prev;
2210 elm_genlist_item_show
2211 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2215 elm_genlist_item_selected_set(prev, EINA_TRUE);
2216 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2222 _item_multi_select_down(Elm_Genlist_Smart_Data *sd)
2224 Elm_Object_Item *next;
2226 if (!sd->selected) return EINA_FALSE;
2227 if (!sd->multi) return EINA_FALSE;
2229 next = elm_genlist_item_next_get(sd->last_selected_item);
2230 if (!next) return EINA_TRUE;
2232 if (elm_genlist_item_selected_get(next))
2234 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2235 sd->last_selected_item = next;
2236 elm_genlist_item_show
2237 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2241 elm_genlist_item_selected_set(next, EINA_TRUE);
2242 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2249 _all_items_deselect(Elm_Genlist_Smart_Data *sd)
2251 if (!sd->selected) return EINA_FALSE;
2253 while (sd->selected)
2254 elm_genlist_item_selected_set(sd->selected->data, EINA_FALSE);
2260 _item_single_select_up(Elm_Genlist_Smart_Data *sd)
2266 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2268 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2271 prev = (Elm_Gen_Item *)elm_genlist_item_prev_get
2272 (sd->last_selected_item);
2274 if (!prev) return EINA_FALSE;
2276 _all_items_deselect(sd);
2278 elm_genlist_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
2279 elm_genlist_item_show((Elm_Object_Item *)prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2284 _item_single_select_down(Elm_Genlist_Smart_Data *sd)
2290 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2292 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2295 next = (Elm_Gen_Item *)elm_genlist_item_next_get
2296 (sd->last_selected_item);
2298 if (!next) return EINA_FALSE;
2300 _all_items_deselect(sd);
2302 elm_genlist_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
2303 elm_genlist_item_show
2304 ((Elm_Object_Item *)next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2309 static void _item_unfocused(Elm_Gen_Item *it)
2312 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2313 if (!sd->focused) return;
2315 if (sd->focused_content)
2317 elm_object_focus_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
2318 elm_object_focus_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
2319 sd->focused_content = NULL;
2321 edje_object_signal_emit
2322 (VIEW(sd->focused), "elm,state,unfocused", "elm");
2323 if (sd->focused->deco_all_view)
2324 edje_object_signal_emit
2325 (sd->focused->deco_all_view, "elm,state,unfocused", "elm");
2326 if (it == sd->focused) sd->focused = NULL;
2329 static void _item_focused(Elm_Gen_Item *it)
2332 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2333 Evas_Coord x, y, w, h, sx, sy, sw, sh;
2335 if (sd->focused && (it != sd->focused)) _item_unfocused(sd->focused);
2336 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
2337 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
2338 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
2340 elm_genlist_item_bring_in((Elm_Object_Item *)it,
2341 ELM_GENLIST_ITEM_SCROLLTO_IN);
2344 if (_focus_enabled(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj))
2346 if (it->deco_all_view)
2347 edje_object_signal_emit
2348 (it->deco_all_view, "elm,state,focused", "elm");
2350 edje_object_signal_emit
2351 (VIEW(it), "elm,state,focused", "elm");
2357 _item_highlight(Elm_Gen_Item *it)
2359 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2361 if (elm_widget_item_disabled_get(it)) return;
2362 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2363 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2364 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2365 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2368 if (!sd->highlight || it->highlighted) return;
2369 #if GENLIST_PINCH_ZOOM_SUPPORT
2370 if (sd->pinch_zoom_mode) return;
2373 it->highlighted = EINA_TRUE;
2375 if (it->deco_all_view)
2376 edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
2377 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
2379 //***************** TIZEN Only
2381 Evas_Object *content;
2382 if (sd->decorate_all_mode)
2384 EINA_LIST_FOREACH(it->item->deco_all_contents, l, content)
2386 const char *type = elm_widget_type_get(content);
2387 if (type && !strcmp(type, "elm_check"))
2388 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
2393 EINA_LIST_FOREACH(it->content_objs, l, content)
2395 const char *type = elm_widget_type_get(content);
2396 if (type && !strcmp(type, "elm_check"))
2397 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
2400 //****************************
2401 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
2405 _item_unhighlight(Elm_Gen_Item *it)
2407 if (!it->highlighted) return;
2409 if (!it->item->nostacking)
2411 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
2413 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
2414 else evas_object_lower(VIEW(it));
2418 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2419 else evas_object_raise(VIEW(it));
2422 it->highlighted = EINA_FALSE;
2424 if (it->deco_all_view)
2425 edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
2426 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
2427 //******************** TIZEN Only
2429 Evas_Object *content;
2430 if (GL_IT(it)->wsd->decorate_all_mode)
2432 EINA_LIST_FOREACH(it->item->deco_all_contents, l, content)
2434 const char *type = elm_widget_type_get(content);
2435 if (type && !strcmp(type, "elm_check"))
2436 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
2441 EINA_LIST_FOREACH(it->content_objs, l, content)
2443 const char *type = elm_widget_type_get(content);
2444 if (type && !strcmp(type, "elm_check"))
2445 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
2448 //*******************************
2449 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it);
2453 _item_unselect(Elm_Gen_Item *it)
2455 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2456 _item_unhighlight(it);
2457 if (!it->selected) return;
2459 it->selected = EINA_FALSE;
2460 sd->selected = eina_list_remove(sd->selected, it);
2461 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
2465 _item_select(Elm_Gen_Item *it)
2467 Evas_Object *obj = WIDGET(it);
2468 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2469 if (elm_widget_item_disabled_get(it)) return;
2470 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2471 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
2472 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2473 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
2476 #if GENLIST_PINCH_ZOOM_SUPPORT
2477 if (IS_ROOT_PARENT_IT(it) && (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
2479 elm_genlist_pinch_zoom_mode_set(obj, ELM_GEN_PINCH_ZOOM_EXPAND);
2480 elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
2485 // Do not check selected because always select mode can be used
2486 _item_highlight(it);
2489 it->selected = EINA_TRUE;
2490 sd->selected = eina_list_append(sd->selected, it);
2492 sd->last_selected_item = (Elm_Object_Item *)it;
2495 // FIXME: after evas_object_raise, mouse event callbacks(ex, UP, DOWN)
2496 // can be called again eventhough already received it.
2497 const char *selectraise = edje_object_data_get(VIEW(it), "selectraise");
2498 if ((selectraise) && (!strcmp(selectraise, "on")))
2500 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2501 else evas_object_raise(VIEW(it));
2502 if ((it->item->group_item) && (it->item->group_item->realized))
2503 evas_object_raise(it->item->VIEW(group_item));
2506 if (it->func.func) it->func.func((void *)it->func.data, obj, it);
2507 if (!EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC))
2510 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
2514 _item_select_unselect(Elm_Gen_Item *it, Eina_Bool selected)
2516 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2517 Evas_Object *obj = ELM_WIDGET_DATA(sd)->obj;
2518 //if (elm_widget_item_disabled_get(it)) return;
2520 evas_object_ref(obj);
2523 const Eina_List *l, *ll;
2525 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
2526 if (it2 != it) _item_unselect(it2);
2528 if (selected) _item_select(it);
2529 else _item_unselect(it);
2530 evas_object_unref(obj);
2534 _highlight_timer(void *data)
2536 Elm_Gen_Item *it = data;
2537 it->item->highlight_timer = NULL;
2538 _item_highlight(it);
2543 _highlight_timer_disable(Elm_Gen_Item *it)
2545 if (it->item->highlight_timer)
2547 ecore_timer_del(it->item->highlight_timer);
2548 it->item->highlight_timer = NULL;
2553 _highlight_timer_enable(Elm_Gen_Item *it)
2555 if (it->item->highlight_timer) ecore_timer_del(it->item->highlight_timer);
2556 it->item->highlight_timer =
2557 ecore_timer_add(ITEM_HIGHLIGHT_TIMER, _highlight_timer, it);
2561 _unhighlight_timer(void *data)
2563 Elm_Gen_Item *it = data;
2564 it->item->highlight_timer = NULL;
2566 if ((GL_IT(it)->wsd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
2567 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
2568 _item_select_unselect(it, EINA_TRUE);
2569 else _item_select_unselect(it, !it->selected);
2575 _unhighlight_timer_enable(Elm_Gen_Item *it)
2577 if (it->item->highlight_timer) ecore_timer_del(it->item->highlight_timer);
2578 it->item->highlight_timer =
2579 ecore_timer_add(ITEM_HIGHLIGHT_TIMER, _unhighlight_timer, it);
2582 static Elm_Gen_Item *_item_focusable_search(Elm_Gen_Item *it, int dir)
2584 if (!it) return NULL;
2585 Elm_Gen_Item *tmp = it;
2590 if (!elm_object_item_disabled_get((Elm_Object_Item *)tmp) &&
2591 ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DEFAULT) ||
2592 (tmp->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS)))
2594 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
2601 if (!elm_object_item_disabled_get((Elm_Object_Item *)tmp) &&
2602 ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DEFAULT) ||
2603 (tmp->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS)))
2605 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2611 static Eina_Bool _item_focus_next(Elm_Genlist_Smart_Data *sd, Focus_Dir dir)
2613 Elm_Gen_Item *it = NULL;
2614 Elm_Gen_Item *old_focused = sd->focused;
2616 if (dir == FOCUS_DIR_DOWN || dir == FOCUS_DIR_UP)
2618 if (dir == FOCUS_DIR_DOWN)
2622 it = ELM_GEN_ITEM_FROM_INLIST
2623 (EINA_INLIST_GET(sd->focused)->next);
2624 _item_unfocused(sd->focused);
2626 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2627 it = _item_focusable_search(it, 1);
2629 else if (dir == FOCUS_DIR_UP)
2633 it = ELM_GEN_ITEM_FROM_INLIST
2634 (EINA_INLIST_GET(sd->focused)->prev);
2635 _item_unfocused(sd->focused);
2637 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2638 it = _item_focusable_search(it, -1);
2642 _item_focused(old_focused);
2647 else if (dir == FOCUS_DIR_LEFT || dir == FOCUS_DIR_RIGHT)
2649 Evas_Object *obj = NULL;
2650 Eina_List *l = NULL;
2652 if (!sd->focused) return EINA_FALSE;
2653 if (sd->focused_content)
2655 l = eina_list_data_find_list(sd->focused->content_objs,
2656 sd->focused_content);
2657 obj = sd->focused_content;
2660 if (dir == FOCUS_DIR_LEFT)
2662 if (l) l = eina_list_prev(l);
2663 else l = eina_list_last(sd->focused->content_objs);
2667 obj = eina_list_data_get(l);
2668 if (obj && elm_object_focus_allow_get(obj))
2671 l = eina_list_prev(l);
2674 else if (dir == FOCUS_DIR_RIGHT)
2676 if (l) l = eina_list_next(l);
2677 else l = sd->focused->content_objs;
2680 obj = eina_list_data_get(l);
2681 if (obj && elm_object_focus_allow_get(obj))
2684 l = eina_list_next(l);
2689 sd->focused_content = obj;
2690 elm_object_focus_set(obj, EINA_TRUE);
2694 sd->focused_content = NULL;
2698 else return EINA_FALSE;
2704 _elm_genlist_smart_event(Evas_Object *obj,
2705 Evas_Object *src __UNUSED__,
2706 Evas_Callback_Type type,
2713 Evas_Coord step_x = 0;
2714 Evas_Coord step_y = 0;
2715 Evas_Coord page_x = 0;
2716 Evas_Coord page_y = 0;
2717 Evas_Event_Key_Down *ev = event_info;
2718 Evas_Coord pan_max_x = 0, pan_max_y = 0;
2720 ELM_GENLIST_DATA_GET(obj, sd);
2722 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2723 if (!sd->items) return EINA_FALSE;
2724 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
2725 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
2727 sd->s_iface->content_pos_get(obj, &x, &y);
2728 sd->s_iface->step_size_get(obj, &step_x, &step_y);
2729 sd->s_iface->page_size_get(obj, &page_x, &page_y);
2730 sd->s_iface->content_viewport_size_get(obj, &v_w, &v_h);
2732 if ((!strcmp(ev->keyname, "Left")) ||
2733 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
2735 if (sd->select_on_focus_enabled) x -= step_x;
2738 return _item_focus_next(sd, FOCUS_DIR_LEFT);
2741 else if ((!strcmp(ev->keyname, "Right")) ||
2742 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
2744 if (sd->select_on_focus_enabled) x += step_x;
2747 return _item_focus_next(sd, FOCUS_DIR_LEFT);
2750 else if ((!strcmp(ev->keyname, "Up")) ||
2751 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
2753 if (sd->select_on_focus_enabled)
2755 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
2756 (_item_multi_select_up(sd))) || (_item_single_select_up(sd)))
2758 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2764 if (_item_focus_next(sd, FOCUS_DIR_UP))
2766 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2773 else if ((!strcmp(ev->keyname, "Down")) ||
2774 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
2776 if (sd->select_on_focus_enabled)
2778 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
2779 (_item_multi_select_down(sd))) ||
2780 (_item_single_select_down(sd)))
2782 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2788 if (_item_focus_next(sd, FOCUS_DIR_DOWN))
2790 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2797 else if ((!strcmp(ev->keyname, "Home")) ||
2798 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
2800 if (sd->select_on_focus_enabled)
2802 Elm_Object_Item *it = elm_genlist_first_item_get(obj);
2803 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
2804 elm_genlist_item_selected_set(it, EINA_TRUE);
2805 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2809 _item_unfocused(sd->focused);
2810 _item_focus_next(sd, FOCUS_DIR_DOWN);
2811 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2815 else if ((!strcmp(ev->keyname, "End")) ||
2816 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
2818 if (sd->select_on_focus_enabled)
2820 Elm_Object_Item *it = elm_genlist_last_item_get(obj);
2821 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
2822 elm_genlist_item_selected_set(it, EINA_TRUE);
2823 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2827 _item_unfocused(sd->focused);
2828 sd->focused = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2829 _item_focus_next(sd, FOCUS_DIR_UP);
2830 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2834 else if ((!strcmp(ev->keyname, "Prior")) ||
2835 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
2838 y -= -(page_y * v_h) / 100;
2842 else if ((!strcmp(ev->keyname, "Next")) ||
2843 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
2846 y += -(page_y * v_h) / 100;
2850 else if (!strcmp(ev->keyname, "Escape"))
2852 if (!_all_items_deselect(sd)) return EINA_FALSE;
2853 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2856 else if (!strcmp(ev->keyname, "Return") ||
2857 !strcmp(ev->keyname, "KP_Enter") ||
2858 !strcmp(ev->keyname, "space"))
2862 Elm_Gen_Item *it = sd->focused;
2863 _item_select_unselect(it, EINA_TRUE);
2864 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
2868 else return EINA_FALSE;
2870 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2871 _elm_genlist_pan_smart_pos_max_get(sd->pan_obj, &pan_max_x, &pan_max_y);
2873 if (x > pan_max_x) x = pan_max_x;
2875 if (y > pan_max_y) y = pan_max_y;
2877 sd->s_iface->content_pos_set(obj, x, y, EINA_TRUE);
2883 _elm_genlist_smart_sub_object_add(Evas_Object *obj,
2886 Elm_Widget_Smart_Class *parent_parent;
2888 parent_parent = (Elm_Widget_Smart_Class *)((Evas_Smart_Class *)
2889 _elm_genlist_parent_sc)->parent;
2891 /* skipping layout's code, which registers size hint changing
2892 * callback on sub objects. this is here because items'
2893 * content_get() routines may change hints on the objects after
2894 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
2895 * not needed at here anyway, so let's skip listening to those
2897 if (!parent_parent->sub_object_add(obj, sobj))
2904 _elm_genlist_smart_sub_object_del(Evas_Object *obj,
2907 ELM_GENLIST_DATA_GET(obj, sd);
2909 /* XXX: hack -- also skipping sizing recalculation on
2910 * sub-object-del. genlist's crazy code paths (like groups and
2911 * such) seem to issue a whole lot of deletions and Evas bitches
2912 * about too many recalculations */
2913 sd->on_sub_del = EINA_TRUE;
2915 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->sub_object_del(obj, sobj))
2918 sd->on_sub_del = EINA_FALSE;
2924 _elm_genlist_smart_on_focus(Evas_Object *obj)
2926 ELM_GENLIST_DATA_GET(obj, sd);
2928 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->on_focus(obj))
2931 if ((sd->items) && (sd->selected) && (!sd->last_selected_item))
2932 sd->last_selected_item = eina_list_data_get(sd->selected);
2934 if (sd->select_on_focus_enabled) return EINA_TRUE;
2935 if (elm_widget_focus_get(obj))
2937 if (_focus_enabled(obj))
2940 _item_focused(sd->focused);
2942 _item_focus_next(sd, FOCUS_DIR_DOWN);
2949 edje_object_signal_emit
2950 (VIEW(sd->focused), "elm,state,unfocused", "elm");
2951 if (sd->focused->deco_all_view)
2952 edje_object_signal_emit
2953 (sd->focused->deco_all_view, "elm,state,unfocused", "elm");
2961 _elm_genlist_smart_focus_next(const Evas_Object *obj,
2962 Elm_Focus_Direction dir,
2965 ELM_GENLIST_CHECK(obj) EINA_FALSE;
2966 ELM_GENLIST_DATA_GET(obj, sd);
2967 Elm_Gen_Item *it = NULL;
2969 // FIXME: If item is unhighligted, this reset sd->access_it.
2970 if (!elm_widget_highlight_get(obj))
2972 sd->access_it = NULL;
2980 if (dir == ELM_FOCUS_NEXT)
2982 if (!it) it = (Elm_Gen_Item *)elm_genlist_first_item_get(obj);
2983 else it = (Elm_Gen_Item *)elm_genlist_item_next_get
2984 ((Elm_Object_Item *)it);
2986 else if (dir == ELM_FOCUS_PREVIOUS)
2988 if (!it) it = (Elm_Gen_Item *)elm_genlist_last_item_get(obj);
2989 else it = (Elm_Gen_Item *)elm_genlist_item_prev_get
2990 ((Elm_Object_Item *)it);
2992 if (_item_access_next(it, dir))
2994 *next = (Evas_Object *)obj;
2998 sd->access_it = NULL;
2999 sd->access_bring_it = NULL;
3000 sd->access_unrealize_it = NULL;
3006 _mirrored_set(Evas_Object *obj,
3009 ELM_GENLIST_DATA_GET(obj, sd);
3011 sd->s_iface->mirrored_set(obj, rtl);
3015 _elm_genlist_smart_theme(Evas_Object *obj)
3019 ELM_GENLIST_DATA_GET(obj, sd);
3021 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->theme(obj))
3024 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
3025 _item_cache_all_free(sd);
3026 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3029 // FIXME: difference from opensource
3030 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
3032 eina_hash_free_buckets(sd->size_caches);
3033 sd->minw = sd->minh = sd->realminw = 0;
3034 EINA_INLIST_FOREACH(sd->blocks, itb)
3039 if (itb->realized) _item_block_unrealize(itb);
3040 EINA_LIST_FOREACH(itb->items, l, it)
3041 it->item->mincalcd = EINA_FALSE;
3043 itb->changed = EINA_TRUE;
3045 if (sd->calc_job) ecore_job_del(sd->calc_job);
3046 sd->calc_job = NULL;
3047 elm_layout_sizing_eval(obj);
3048 sd->pan_changed = EINA_TRUE;
3049 evas_object_smart_changed(sd->pan_obj);
3050 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
3051 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
3056 /* FIXME: take off later. maybe this show region coords belong in the
3057 * interface (new api functions, set/get)? */
3059 _show_region_hook(void *data,
3062 Evas_Coord x, y, w, h;
3064 ELM_GENLIST_DATA_GET(data, sd);
3066 elm_widget_show_region_get(obj, &x, &y, &w, &h);
3067 //x & y are screen coordinates, Add with pan coordinates
3070 sd->s_iface->content_region_show(obj, x, y, w, h);
3074 _elm_genlist_smart_translate(Evas_Object *obj)
3076 evas_object_smart_callback_call(obj, "language,changed", NULL);
3082 _item_block_position_update(Eina_Inlist *list,
3087 EINA_INLIST_FOREACH(list, tmp)
3089 tmp->position = idx++;
3090 tmp->position_update = EINA_TRUE;
3095 _item_position_update(Eina_List *list,
3101 EINA_LIST_FOREACH(list, l, it)
3103 it->position = idx++;
3104 it->position_update = EINA_TRUE;
3109 _item_block_merge(Item_Block *left,
3115 EINA_LIST_FOREACH(right->items, l, it2)
3117 it2->item->block = left;
3119 left->changed = EINA_TRUE;
3121 left->items = eina_list_merge(left->items, right->items);
3125 _item_block_del(Elm_Gen_Item *it)
3128 Item_Block *itb = it->item->block;
3129 Eina_Bool block_changed = EINA_FALSE;
3131 itb->items = eina_list_remove(itb->items, it);
3133 itb->changed = EINA_TRUE;
3134 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
3135 GL_IT(it)->wsd->calc_job = ecore_job_add(_calc_job, GL_IT(it)->wsd);
3140 il = EINA_INLIST_GET(itb);
3141 itbn = (Item_Block *)(il->next);
3143 it->parent->item->items =
3144 eina_list_remove(it->parent->item->items, it);
3147 _item_block_position_update(il->next, itb->position);
3149 GL_IT(it)->wsd->blocks =
3150 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
3153 if (itbn) itbn->changed = EINA_TRUE;
3157 if (itb->count < (itb->sd->max_items_per_block / 2))
3162 il = EINA_INLIST_GET(itb);
3163 itbp = (Item_Block *)(il->prev);
3164 itbn = (Item_Block *)(il->next);
3166 /* merge block with previous */
3168 ((itbp->count + itb->count) <
3169 (itb->sd->max_items_per_block +
3170 (itb->sd->max_items_per_block / 2))))
3172 _item_block_merge(itbp, itb);
3173 _item_block_position_update
3174 (EINA_INLIST_GET(itb)->next, itb->position);
3175 GL_IT(it)->wsd->blocks = eina_inlist_remove
3176 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
3178 block_changed = EINA_TRUE;
3180 /* merge block with next */
3182 ((itbn->count + itb->count) <
3183 (itb->sd->max_items_per_block +
3184 (itb->sd->max_items_per_block / 2))))
3186 _item_block_merge(itb, itbn);
3187 _item_block_position_update
3188 (EINA_INLIST_GET(itbn)->next, itbn->position);
3189 GL_IT(it)->wsd->blocks =
3190 eina_inlist_remove(GL_IT(it)->wsd->blocks,
3191 EINA_INLIST_GET(itbn));
3193 block_changed = EINA_TRUE;
3200 GL_IT(it)->wsd->pan_changed = EINA_TRUE;
3201 evas_object_smart_changed(GL_IT(it)->wsd->pan_obj);
3202 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
3203 GL_IT(it)->wsd->calc_job = NULL;
3205 #if GENLIST_FX_SUPPORT
3206 it->item->block = NULL;
3211 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3213 if (!it->deco_all_view) return;
3215 #if GENLIST_FX_SUPPORT
3216 if ((GL_IT(it)->has_proxy_it) && (!GL_IT(it)->wsd->genlist_clearing))
3218 if (!eina_list_data_find(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it))
3219 GL_IT(it)->wsd->pending_unrealized_decorate_all_items =
3220 eina_list_append(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it);
3225 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3226 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
3227 _item_mouse_callbacks_add(it, VIEW(it));
3229 _item_mouse_callbacks_del(it, it->deco_all_view);
3230 _view_clear(it->deco_all_view, &(it->item->deco_all_contents));
3231 evas_object_del(it->deco_all_view);
3232 it->deco_all_view = NULL;
3234 // FIXME: Belows are needed? _decorate_item_realize do not
3235 _elm_genlist_item_odd_even_update(it);
3240 _item_mouse_move_cb(void *data,
3241 Evas *evas __UNUSED__,
3245 EINA_SAFETY_ON_NULL_RETURN(data);
3246 Elm_Gen_Item *it = data;
3247 Elm_Genlist_Smart_Data *sd;
3248 Evas_Event_Mouse_Move *ev = event_info;
3249 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
3250 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
3252 sd = GL_IT(it)->wsd;
3254 if (it->down) _highlight_timer_disable(it);
3255 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3257 if (!sd->on_hold) _item_unselect(it);
3258 sd->on_hold = EINA_TRUE;
3260 if (sd->multi_touched)
3262 sd->cur_x = ev->cur.canvas.x;
3263 sd->cur_y = ev->cur.canvas.y;
3266 if ((it->dragging) && (it->down))
3268 if (sd->movements == SWIPE_MOVES)
3269 sd->swipe = EINA_TRUE;
3272 sd->history[sd->movements].x = ev->cur.canvas.x;
3273 sd->history[sd->movements].y = ev->cur.canvas.y;
3274 if (abs((sd->history[sd->movements].x -
3275 sd->history[0].x)) > 40)
3276 sd->swipe = EINA_TRUE;
3282 ecore_timer_del(it->long_timer);
3283 it->long_timer = NULL;
3285 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
3288 if ((!it->down) || (sd->longpressed))
3292 ecore_timer_del(it->long_timer);
3293 it->long_timer = NULL;
3295 if ((sd->reorder_mode) && (sd->reorder_it))
3297 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3299 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
3300 sd->reorder_fast = 1;
3301 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
3302 sd->reorder_fast = -1;
3303 else sd->reorder_fast = 0;
3305 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
3307 if (!sd->reorder_start_y)
3308 sd->reorder_start_y = it->item->block->y + it->y;
3312 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
3313 y_pos = oy + oh - sd->reorder_it->item->h;
3317 if (it->deco_all_view)
3318 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
3319 else if (it->item->deco_it_view)
3321 (it, it->item->deco_it_view, it->item->scrl_x, y_pos);
3323 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
3325 if (sd->calc_job) ecore_job_del(sd->calc_job);
3326 sd->calc_job = ecore_job_add(_calc_job, sd);
3330 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3332 minw = GL_IT(it)->wsd->finger_minw;
3333 minh = GL_IT(it)->wsd->finger_minh;
3336 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3337 x = ev->cur.canvas.x - x;
3338 y = ev->cur.canvas.y - y;
3341 if (adx < 0) adx = -dx;
3345 if (ady < 0) ady = -dy;
3349 if ((adx > minw) || (ady > minh))
3351 it->dragging = EINA_TRUE;
3354 ecore_timer_del(it->long_timer);
3355 it->long_timer = NULL;
3360 evas_object_smart_callback_call
3361 (WIDGET(it), SIG_DRAG_START_UP, it);
3365 evas_object_smart_callback_call
3366 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3368 evas_object_smart_callback_call
3369 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3375 evas_object_smart_callback_call
3376 (WIDGET(it), SIG_DRAG_START_DOWN, it);
3380 evas_object_smart_callback_call
3381 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3383 evas_object_smart_callback_call
3384 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3391 _long_press_cb(void *data)
3393 Elm_Gen_Item *it = data, *it2;
3394 Elm_Genlist_Smart_Data *sd;
3397 sd = GL_IT(it)->wsd;
3399 it->long_timer = NULL;
3400 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
3401 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3402 return ECORE_CALLBACK_CANCEL;
3404 GL_IT(it)->wsd->longpressed = EINA_TRUE;
3405 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
3406 if ((GL_IT(it)->wsd->reorder_mode) && (!it->group))
3408 GL_IT(it)->wsd->reorder_it = it;
3409 GL_IT(it)->wsd->reorder_start_y = 0;
3410 if (it->deco_all_view)
3411 evas_object_raise(it->deco_all_view);
3413 evas_object_raise(VIEW(it));
3415 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
3416 sd->s_iface->bounce_allow_set
3417 (ELM_WIDGET_DATA(sd)->obj, EINA_FALSE, EINA_FALSE);
3419 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
3421 if (it != it2) _item_unselect(it2);
3424 // FIXME: difference from opensource
3425 if (it->item->items)
3427 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
3429 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
3431 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
3433 return ECORE_CALLBACK_RENEW;
3438 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
3440 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
3441 return ECORE_CALLBACK_RENEW;
3444 if (!GL_IT(it)->wsd->decorate_all_mode)
3445 edje_object_signal_emit
3446 (VIEW(it), "elm,state,reorder,enabled", "elm");
3449 return ECORE_CALLBACK_CANCEL;
3453 _swipe_do(Elm_Gen_Item *it)
3458 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3459 elm_widget_item_disabled_get(it)) return;
3461 GL_IT(it)->wsd->swipe = EINA_FALSE;
3462 for (i = 0; i < GL_IT(it)->wsd->movements; i++)
3464 sum += GL_IT(it)->wsd->history[i].x;
3465 if (abs(GL_IT(it)->wsd->history[0].y -
3466 GL_IT(it)->wsd->history[i].y) > 10) return;
3469 sum /= GL_IT(it)->wsd->movements;
3470 if (abs(sum - GL_IT(it)->wsd->history[0].x) <= 10) return;
3471 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
3475 _swipe_cancel(void *data)
3477 Elm_Gen_Item *it = data;
3479 if (!it) return ECORE_CALLBACK_CANCEL;
3480 GL_IT(it)->wsd->swipe = EINA_FALSE;
3481 GL_IT(it)->wsd->movements = 0;
3483 return ECORE_CALLBACK_RENEW;
3487 _multi_cancel(void *data)
3489 Elm_Genlist_Smart_Data *sd = data;
3491 sd->multi_timeout = EINA_TRUE;
3493 return ECORE_CALLBACK_RENEW;
3497 _multi_touch_gesture_eval(void *data)
3499 Elm_Gen_Item *it = data;
3500 Evas_Coord minw = 0, minh = 0;
3501 Evas_Coord off_x, off_y, off_mx, off_my;
3503 GL_IT(it)->wsd->multi_touched = EINA_FALSE;
3504 if (GL_IT(it)->wsd->multi_timer)
3506 ecore_timer_del(GL_IT(it)->wsd->multi_timer);
3507 GL_IT(it)->wsd->multi_timer = NULL;
3509 if (GL_IT(it)->wsd->multi_timeout)
3511 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3515 minw = GL_IT(it)->wsd->finger_minw;
3516 minh = GL_IT(it)->wsd->finger_minh;
3518 off_x = abs(GL_IT(it)->wsd->cur_x - GL_IT(it)->wsd->prev_x);
3519 off_y = abs(GL_IT(it)->wsd->cur_y - GL_IT(it)->wsd->prev_y);
3520 off_mx = abs(GL_IT(it)->wsd->cur_mx - GL_IT(it)->wsd->prev_mx);
3521 off_my = abs(GL_IT(it)->wsd->cur_my - GL_IT(it)->wsd->prev_my);
3523 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
3524 || (off_my > minh)))
3526 if ((off_x + off_mx) > (off_y + off_my))
3528 if ((GL_IT(it)->wsd->cur_x > GL_IT(it)->wsd->prev_x)
3529 && (GL_IT(it)->wsd->cur_mx > GL_IT(it)->wsd->prev_mx))
3530 evas_object_smart_callback_call
3531 (WIDGET(it), SIG_MULTI_SWIPE_RIGHT, it);
3532 else if ((GL_IT(it)->wsd->cur_x < GL_IT(it)->wsd->prev_x)
3533 && (GL_IT(it)->wsd->cur_mx < GL_IT(it)->wsd->prev_mx))
3534 evas_object_smart_callback_call
3535 (WIDGET(it), SIG_MULTI_SWIPE_LEFT, it);
3539 if ((GL_IT(it)->wsd->cur_y > GL_IT(it)->wsd->prev_y)
3540 && (GL_IT(it)->wsd->cur_my > GL_IT(it)->wsd->prev_my))
3541 evas_object_smart_callback_call
3542 (WIDGET(it), SIG_MULTI_SWIPE_DOWN, it);
3543 else if ((GL_IT(it)->wsd->cur_y < GL_IT(it)->wsd->prev_y)
3544 && (GL_IT(it)->wsd->cur_my < GL_IT(it)->wsd->prev_my))
3545 evas_object_smart_callback_call
3546 (WIDGET(it), SIG_MULTI_SWIPE_UP, it);
3550 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3554 _item_multi_down_cb(void *data,
3555 Evas *evas __UNUSED__,
3556 Evas_Object *obj __UNUSED__,
3559 Elm_Gen_Item *it = data;
3560 Evas_Event_Multi_Down *ev = event_info;
3562 if ((GL_IT(it)->wsd->multi_device != 0) || (GL_IT(it)->wsd->multi_touched)
3563 || (GL_IT(it)->wsd->multi_timeout))
3566 GL_IT(it)->wsd->multi_device = ev->device;
3567 GL_IT(it)->wsd->multi_down = EINA_TRUE;
3568 GL_IT(it)->wsd->multi_touched = EINA_TRUE;
3569 GL_IT(it)->wsd->prev_mx = ev->canvas.x;
3570 GL_IT(it)->wsd->prev_my = ev->canvas.y;
3573 it->dragging = EINA_FALSE;
3574 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
3576 _item_event_del(it);
3578 GL_IT(it)->wsd->longpressed = EINA_FALSE;
3579 if (GL_IT(it)->wsd->on_hold)
3581 GL_IT(it)->wsd->swipe = EINA_FALSE;
3582 GL_IT(it)->wsd->movements = 0;
3583 GL_IT(it)->wsd->on_hold = EINA_FALSE;
3588 _item_multi_up_cb(void *data,
3589 Evas *evas __UNUSED__,
3590 Evas_Object *obj __UNUSED__,
3593 Elm_Gen_Item *it = data;
3594 Evas_Event_Multi_Up *ev = event_info;
3596 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3597 GL_IT(it)->wsd->multi_device = 0;
3598 GL_IT(it)->wsd->multi_down = EINA_FALSE;
3599 if (GL_IT(it)->wsd->mouse_down) return;
3600 _multi_touch_gesture_eval(data);
3604 _item_multi_move_cb(void *data,
3605 Evas *evas __UNUSED__,
3606 Evas_Object *obj __UNUSED__,
3609 Elm_Gen_Item *it = data;
3610 Evas_Event_Multi_Move *ev = event_info;
3612 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3613 GL_IT(it)->wsd->cur_mx = ev->cur.canvas.x;
3614 GL_IT(it)->wsd->cur_my = ev->cur.canvas.y;
3618 _item_mouse_down_cb(void *data,
3619 Evas *evas __UNUSED__,
3623 Evas_Event_Mouse_Down *ev = event_info;
3624 Elm_Gen_Item *it = data;
3625 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
3628 if (ev->button != 1) return;
3630 it->down = EINA_TRUE;
3631 it->dragging = EINA_FALSE;
3632 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3633 it->dx = ev->canvas.x - x;
3634 it->dy = ev->canvas.y - y;
3635 sd->mouse_down = EINA_TRUE;
3636 if (!sd->multi_touched)
3638 sd->prev_x = ev->canvas.x;
3639 sd->prev_y = ev->canvas.y;
3640 sd->multi_timeout = EINA_FALSE;
3641 if (sd->multi_timer) ecore_timer_del(sd->multi_timer);
3642 sd->multi_timer = ecore_timer_add(1, _multi_cancel, sd);
3644 sd->longpressed = EINA_FALSE;
3645 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3647 sd->on_hold = EINA_TRUE;
3650 else sd->on_hold = EINA_FALSE;
3652 _highlight_timer_enable(it);
3654 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
3655 if ((!elm_widget_item_disabled_get(it)) &&
3656 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3658 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
3659 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
3661 evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, it);
3663 _item_event_del(it);
3664 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
3666 it->long_timer = ecore_timer_add
3667 (sd->longpress_timeout, _long_press_cb, it);
3669 sd->swipe = EINA_FALSE;
3675 _item_block_new(Elm_Genlist_Smart_Data *sd,
3680 itb = calloc(1, sizeof(Item_Block));
3681 if (!itb) return NULL;
3685 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
3686 _item_block_position_update(sd->blocks, 0);
3690 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3691 itb->position_update = EINA_TRUE;
3692 if (sd->blocks != EINA_INLIST_GET(itb))
3695 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
3707 _item_block_add(Elm_Genlist_Smart_Data *sd,
3710 Item_Block *itb = NULL;
3711 if (it->item->block) return EINA_TRUE;
3718 itb = calloc(1, sizeof(Item_Block));
3719 if (!itb) return EINA_FALSE;
3721 if (!it->item->rel->item->block)
3724 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3725 itb->items = eina_list_append(itb->items, it);
3726 itb->position_update = EINA_TRUE;
3727 it->position = eina_list_count(itb->items);
3728 it->position_update = EINA_TRUE;
3730 if (sd->blocks != EINA_INLIST_GET(itb))
3734 (EINA_INLIST_GET(itb)->prev))->position + 1;
3745 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3746 if (it->item->before)
3748 sd->blocks = eina_inlist_prepend_relative
3749 (sd->blocks, EINA_INLIST_GET(itb),
3750 EINA_INLIST_GET(it->item->rel->item->block));
3752 eina_list_prepend_relative_list(itb->items, it, tmp);
3754 /* Update index from where we prepended */
3755 _item_position_update
3756 (eina_list_prev(tmp), it->item->rel->position);
3757 _item_block_position_update
3758 (EINA_INLIST_GET(itb),
3759 it->item->rel->item->block->position);
3763 sd->blocks = eina_inlist_append_relative
3764 (sd->blocks, EINA_INLIST_GET(itb),
3765 EINA_INLIST_GET(it->item->rel->item->block));
3767 eina_list_append_relative_list(itb->items, it, tmp);
3769 /* Update block index from where we appended */
3770 _item_position_update
3771 (eina_list_next(tmp), it->item->rel->position + 1);
3772 _item_block_position_update
3773 (EINA_INLIST_GET(itb),
3774 it->item->rel->item->block->position + 1);
3780 if (it->item->before)
3784 itb = (Item_Block *)(sd->blocks);
3785 if (itb->count >= sd->max_items_per_block)
3787 itb = _item_block_new(sd, EINA_TRUE);
3788 if (!itb) return EINA_FALSE;
3793 itb = _item_block_new(sd, EINA_TRUE);
3794 if (!itb) return EINA_FALSE;
3796 itb->items = eina_list_prepend(itb->items, it);
3798 _item_position_update(itb->items, 0);
3804 itb = (Item_Block *)(sd->blocks->last);
3805 if (itb->count >= sd->max_items_per_block)
3807 itb = _item_block_new(sd, EINA_FALSE);
3808 if (!itb) return EINA_FALSE;
3813 itb = _item_block_new(sd, EINA_FALSE);
3814 if (!itb) return EINA_FALSE;
3816 itb->items = eina_list_append(itb->items, it);
3817 it->position = eina_list_count(itb->items);
3826 if ((!GL_IT(it)->wsd->sorting) && (it->item->rel->item->queued))
3828 /* NOTE: for a strange reason eina_list and eina_inlist
3829 don't have the same property on sorted insertion
3830 order, so the queue is not always ordered like the
3831 item list. This lead to issue where we depend on an
3832 item that is not yet created. As a quick work around,
3833 we reschedule the calc of the item and stop reordering
3834 the list to prevent any nasty issue to show up here.
3836 sd->queue = eina_list_append(sd->queue, it);
3837 sd->requeued = EINA_TRUE;
3838 it->item->queued = EINA_TRUE;
3843 itb = it->item->rel->item->block;
3844 if (!itb) goto newblock;
3845 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3846 if (it->item->before)
3848 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3849 _item_position_update
3850 (eina_list_prev(tmp), it->item->rel->position);
3854 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3855 _item_position_update
3856 (eina_list_next(tmp), it->item->rel->position + 1);
3861 itb->changed = EINA_TRUE;
3862 it->item->block = itb;
3863 if (itb->sd->calc_job) ecore_job_del(itb->sd->calc_job);
3864 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd);
3866 if (itb->count > itb->sd->max_items_per_block)
3871 Eina_Bool done = EINA_FALSE;
3873 newc = itb->count / 2;
3875 if (EINA_INLIST_GET(itb)->prev)
3877 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3879 if (itbp->count + newc < sd->max_items_per_block / 2)
3881 /* moving items to previous block */
3882 while ((itb->count > newc) && (itb->items))
3884 it2 = eina_list_data_get(itb->items);
3885 itb->items = eina_list_remove_list
3886 (itb->items, itb->items);
3889 itbp->items = eina_list_append(itbp->items, it2);
3890 it2->item->block = itbp;
3898 if (!done && EINA_INLIST_GET(itb)->next)
3900 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3902 if (itbn->count + newc < sd->max_items_per_block / 2)
3904 /* moving items to next block */
3905 while ((itb->count > newc) && (itb->items))
3909 l = eina_list_last(itb->items);
3910 it2 = eina_list_data_get(l);
3911 itb->items = eina_list_remove_list(itb->items, l);
3914 itbn->items = eina_list_prepend(itbn->items, it2);
3915 it2->item->block = itbn;
3925 /* moving items to new block */
3926 itb2 = calloc(1, sizeof(Item_Block));
3927 if (!itb2) return EINA_FALSE;
3930 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
3931 EINA_INLIST_GET(itb));
3932 itb2->changed = EINA_TRUE;
3933 while ((itb->count > newc) && (itb->items))
3937 l = eina_list_last(itb->items);
3939 itb->items = eina_list_remove_list(itb->items, l);
3942 itb2->items = eina_list_prepend(itb2->items, it2);
3943 it2->item->block = itb2;
3953 _item_process(Elm_Genlist_Smart_Data *sd,
3956 if (!_item_block_add(sd, it)) return EINA_FALSE;
3958 _item_block_realize(it->item->block);
3960 if (_item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE))
3962 it->item->block->show_me = EINA_TRUE;
3963 it->item->block->changed = EINA_FALSE;
3966 /* when prepending, move the scroller along with the first selected
3967 * * item to create the illusion that we're watching the selected
3968 * * item this prevents the selected item being scrolled off the
3971 if (sd->selected && it->item->before)
3976 it2 = sd->selected->data;
3977 if (it2->item->block)
3979 sd->s_iface->content_pos_get(ELM_WIDGET_DATA(sd)->obj, NULL, &y);
3980 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
3981 if ((it->y + it->item->block->y > y + h) ||
3982 (it->y + it->item->block->y + it->item->h < y))
3983 /* offscreen, just update */
3984 sd->s_iface->content_region_show
3985 (ELM_WIDGET_DATA(sd)->obj, it2->x + it2->item->block->x, y,
3986 it2->item->block->w, h);
3988 sd->s_iface->content_region_show
3989 (ELM_WIDGET_DATA(sd)->obj, it->x + it->item->block->x,
3990 y + it->item->h, it->item->block->w, h);
3997 _queue_process(Elm_Genlist_Smart_Data *sd)
4002 ft = ecore_animator_frametime_get();
4003 t0 = ecore_loop_time_get();
4004 for (n = 0; (sd->queue) && (n < 128); n++)
4008 it = eina_list_data_get(sd->queue);
4009 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
4010 it->item->queued = EINA_FALSE;
4011 if (!_item_process(sd, it)) continue;
4012 t = ecore_time_get();
4013 /* same as eina_inlist_count > 1 */
4014 if (sd->blocks && sd->blocks->next)
4016 if ((t - t0) > ft) break;
4023 _item_idle_enterer(void *data)
4025 Elm_Genlist_Smart_Data *sd = data;
4027 sd->processed_sizes = 0;
4028 if (sd->prev_viewport_w == 0) return ECORE_CALLBACK_RENEW;
4029 if (_queue_process(sd) > 0)
4032 // Job always be alive because idle_enterer should be alive
4033 if (sd->calc_job) ecore_job_del(sd->calc_job);
4034 sd->calc_job = ecore_job_add(_calc_job, sd);
4038 sd->queue_idle_enterer = NULL;
4039 return ECORE_CALLBACK_CANCEL;
4042 #if GENLIST_FX_SUPPORT
4043 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4045 return ECORE_CALLBACK_RENEW;
4049 _item_queue(Elm_Genlist_Smart_Data *sd,
4055 if (it->item->queued) return;
4057 if (sd->queue_idle_enterer)
4058 ecore_idle_enterer_del(sd->queue_idle_enterer);
4059 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd);
4062 // Job always be alive because idle_enterer should be alive
4063 if (sd->calc_job) ecore_job_del(sd->calc_job);
4064 sd->calc_job = ecore_job_add(_calc_job, sd);
4066 sd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(sd)->obj, NULL, &vh);
4067 if (!sd->queue && direct && sd->prev_viewport_w &&
4068 (sd->processed_sizes < vh))
4070 _item_process(sd, it);
4071 sd->processed_sizes += it->item->minh;
4075 it->item->queued = EINA_TRUE;
4076 if (cb && !sd->requeued)
4077 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
4079 sd->queue = eina_list_append(sd->queue, it);
4082 /* If the application wants to know the relative item, use
4083 * elm_genlist_item_prev_get(it)*/
4085 _item_move_after(Elm_Gen_Item *it,
4086 Elm_Gen_Item *after)
4090 if (it == after) return;
4092 GL_IT(it)->wsd->items =
4093 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
4094 if (it->item->block) _item_block_del(it);
4096 GL_IT(it)->wsd->items = eina_inlist_append_relative
4097 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4100 it->item->rel->item->rel_revs =
4101 eina_list_remove(it->item->rel->item->rel_revs, it);
4102 it->item->rel = after;
4103 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
4104 it->item->before = EINA_FALSE;
4105 if (after->item->group_item) it->item->group_item = after->item->group_item;
4106 _item_queue(GL_IT(it)->wsd, it, NULL, EINA_TRUE);
4108 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4112 _access_activate_cb(void *data __UNUSED__,
4113 Evas_Object *part_obj __UNUSED__,
4114 Elm_Object_Item *item)
4116 _item_select_unselect((Elm_Gen_Item *)item, EINA_TRUE);
4119 /* If the application wants to know the relative item, use
4120 * elm_genlist_item_next_get(it)*/
4122 _item_move_before(Elm_Gen_Item *it,
4123 Elm_Gen_Item *before)
4126 if (!before) return;
4127 if (it == before) return;
4129 GL_IT(it)->wsd->items =
4130 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
4131 if (it->item->block) _item_block_del(it);
4132 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
4133 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4136 it->item->rel->item->rel_revs =
4137 eina_list_remove(it->item->rel->item->rel_revs, it);
4138 it->item->rel = before;
4139 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
4140 it->item->before = EINA_TRUE;
4141 if (before->item->group_item)
4142 it->item->group_item = before->item->group_item;
4143 _item_queue(GL_IT(it)->wsd, it, NULL, EINA_TRUE);
4145 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4149 _item_mouse_up_cb(void *data,
4150 Evas *evas __UNUSED__,
4151 Evas_Object *obj __UNUSED__,
4154 Evas_Event_Mouse_Up *ev = event_info;
4155 Eina_Bool dragged = EINA_FALSE;
4156 Elm_Genlist_Smart_Data *sd;
4157 Elm_Gen_Item *it = data;
4159 if (ev->button != 1) return;
4160 it->down = EINA_FALSE;
4161 sd = GL_IT(it)->wsd;
4163 _highlight_timer_disable(it);
4164 sd->mouse_down = EINA_FALSE;
4165 evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, it);
4166 if (sd->multi_touched)
4168 if ((!sd->multi) && (!it->selected))
4170 _item_unhighlight(it);
4172 if (sd->multi_down) return;
4173 _multi_touch_gesture_eval(data);
4178 it->dragging = EINA_FALSE;
4179 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
4182 _item_event_del(it);
4183 if (sd->multi_timer)
4185 ecore_timer_del(sd->multi_timer);
4186 sd->multi_timer = NULL;
4187 sd->multi_timeout = EINA_FALSE;
4189 sd->on_hold = EINA_FALSE;
4190 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4192 if (sd->swipe) _swipe_do(data);
4193 sd->longpressed = EINA_FALSE;
4196 if ((sd->reorder_mode) && (sd->reorder_it))
4198 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
4199 sd->reorder_fast = 0;
4201 if (sd->reorder_rel &&
4202 (sd->reorder_it->parent == sd->reorder_rel->parent))
4204 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
4205 _item_move_before(sd->reorder_it, sd->reorder_rel);
4207 _item_move_after(sd->reorder_it, sd->reorder_rel);
4208 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4212 if (sd->calc_job) ecore_job_del(sd->calc_job);
4213 sd->calc_job = ecore_job_add(_calc_job, sd);
4215 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
4216 sd->reorder_it = sd->reorder_rel = NULL;
4217 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4218 sd->s_iface->bounce_allow_set
4219 (ELM_WIDGET_DATA(sd)->obj, sd->h_bounce, sd->v_bounce);
4223 if (it->want_unrealize && !(it->item->unrealize_disabled))
4225 _item_unrealize(it, EINA_FALSE);
4226 if (it->item->block->want_unrealize)
4227 _item_block_unrealize(it->item->block);
4232 if (sd->longpressed)
4234 _item_unhighlight(it);
4238 _item_highlight(it);
4239 _unhighlight_timer_enable(it);
4244 _item_mouse_callbacks_add(Elm_Gen_Item *it,
4247 evas_object_event_callback_add
4248 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4249 evas_object_event_callback_add
4250 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4251 evas_object_event_callback_add
4252 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4253 evas_object_event_callback_add
4254 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4255 evas_object_event_callback_add
4256 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4257 evas_object_event_callback_add
4258 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4262 _item_mouse_callbacks_del(Elm_Gen_Item *it,
4265 evas_object_event_callback_del_full
4266 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4267 evas_object_event_callback_del_full
4268 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4269 evas_object_event_callback_del_full
4270 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4271 evas_object_event_callback_del_full
4272 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4273 evas_object_event_callback_del_full
4274 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4275 evas_object_event_callback_del_full
4276 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4280 _scroll_hold_timer_cb(void *data)
4282 Elm_Genlist_Smart_Data *sd = data;
4284 if (!sd) return ECORE_CALLBACK_CANCEL;
4285 sd->scr_hold_timer = NULL;
4287 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4289 return ECORE_CALLBACK_CANCEL;
4293 _decorate_item_finished_signal_cb(void *data,
4295 const char *emission __UNUSED__,
4296 const char *source __UNUSED__)
4298 Elm_Gen_Item *it = data;
4301 if (!data || !obj) return;
4302 if ((!it->realized) || (!it->item->deco_it_view)) return;
4304 it->item->nocache_once = EINA_FALSE;
4305 _decorate_item_unrealize(it);
4306 // FIXME: what is below?
4307 if (it->item->group_item)
4308 evas_object_raise(it->item->VIEW(group_item));
4310 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
4311 GL_IT(it)->wsd->decorate_it_type);
4312 edje_object_signal_callback_del_full
4313 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
4317 _item_block_recalc(Item_Block *itb,
4321 const Eina_List *l, *ll;
4323 Evas_Coord minw = 0, minh = 0;
4324 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
4328 EINA_LIST_FOREACH_SAFE(itb->items, l, ll, it)
4330 show_me |= it->item->show_me;
4333 if (!it->item->mincalcd)
4335 changed = EINA_TRUE;
4336 if (it->realized) _item_min_calc(it, NULL, NULL);
4339 _item_realize(it, in, EINA_TRUE);
4340 _item_unrealize(it, EINA_TRUE);
4348 if (itb->sd->homogeneous)
4350 Size_Cache *size = eina_hash_find
4351 (itb->sd->size_caches,
4352 it->itc->item_style);
4355 it->item->w = it->item->minw = size->minw;
4356 it->item->h = it->item->minh = size->minh;
4360 _item_realize(it, in, EINA_TRUE);
4361 _item_unrealize(it, EINA_TRUE);
4366 _item_realize(it, in, EINA_TRUE);
4367 _item_unrealize(it, EINA_TRUE);
4372 if (!it->item->mincalcd) changed = EINA_TRUE;
4373 _item_realize(it, in, EINA_FALSE);
4376 minh += it->item->minh;
4377 if (minw < it->item->minw) minw = it->item->minw;
4381 #if GENLIST_PINCH_ZOOM_SUPPORT
4382 if (IS_ROOT_PARENT_IT(it))
4383 it->item->pan_scrl_y = itb->y + it->y;
4389 itb->sd->pan_changed = changed;
4390 // evas_object_smart_changed(itb->sd->pan_obj);
4394 itb->changed = EINA_FALSE;
4395 itb->position_update = EINA_FALSE;
4401 _item_update(Elm_Gen_Item *it)
4404 if (!it->realized) return;
4406 _view_clear(VIEW(it), &(it->content_objs));
4407 _view_clear(it->item->deco_it_view, &(it->item->deco_it_contents));
4408 _view_clear(it->deco_all_view, &(it->item->deco_all_contents));
4409 EINA_LIST_FREE(it->item->flip_content_objs, c)
4412 _view_inflate(VIEW(it), it, &(it->content_objs));
4413 if (GL_IT(it)->wsd->decorate_all_mode)
4414 _view_inflate(it->deco_all_view, it, &(it->item->deco_all_contents));
4415 else if (it->item->deco_it_view)
4416 _view_inflate(it->item->deco_it_view, it, &(it->item->deco_it_contents));
4419 it->item->flip_content_objs =
4420 _item_content_realize(it, VIEW(it), it->item->flip_content_objs,
4424 _elm_genlist_item_state_update(it);
4428 _update_job(void *data)
4430 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
4431 Elm_Genlist_Smart_Data *sd = data;
4436 sd->update_job = NULL;
4439 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4440 EINA_INLIST_FOREACH(sd->blocks, itb)
4442 Evas_Coord itminw, itminh;
4449 _item_block_position(itb, num);
4453 recalc = EINA_FALSE;
4454 EINA_LIST_FOREACH(itb->items, l2, it)
4456 if (it->item->updateme)
4458 itminw = it->item->minw;
4459 itminh = it->item->minh;
4461 it->item->updateme = EINA_FALSE;
4465 position = EINA_TRUE;
4469 #if GENLIST_ENTRY_SUPPORT
4470 it->item->unrealize_disabled = EINA_FALSE;
4472 _item_realize(it, num, EINA_TRUE);
4473 _item_unrealize(it, EINA_TRUE);
4475 if ((it->item->minw != itminw) || (it->item->minh != itminh))
4480 itb->updateme = EINA_FALSE;
4483 position = EINA_TRUE;
4484 itb->changed = EINA_TRUE;
4485 _item_block_recalc(itb, num0, EINA_FALSE);
4486 _item_block_position(itb, num0);
4491 if (sd->calc_job) ecore_job_del(sd->calc_job);
4492 sd->calc_job = ecore_job_add(_calc_job, sd);
4494 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4495 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4499 _scroll_animate_start_cb(Evas_Object *obj,
4500 void *data __UNUSED__)
4502 ELM_GENLIST_DATA_GET(obj, sd);
4503 #if GENLIST_FX_SUPPORT
4504 _elm_genlist_fx_clear(obj, EINA_FALSE);
4505 sd->scrolling = EINA_TRUE;
4507 if (sd->queue_idle_enterer)
4509 ecore_idle_enterer_del(sd->queue_idle_enterer);
4510 sd->queue_idle_enterer = NULL;
4512 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
4516 _scroll_animate_stop_cb(Evas_Object *obj,
4517 void *data __UNUSED__)
4519 ELM_GENLIST_DATA_GET(obj, sd);
4520 #if GENLIST_FX_SUPPORT
4521 _elm_genlist_fx_clear(obj, EINA_FALSE);
4522 sd->scrolling = EINA_FALSE;
4524 if (sd->access_unrealize_it)
4526 Elm_Gen_Item *it1, *it2;
4527 Eina_List *l = elm_genlist_realized_items_get(obj);
4530 int idx = 0, idx1 = 0, idx2 = 0;
4531 idx = elm_genlist_item_index_get((Elm_Object_Item *)sd->access_unrealize_it);
4532 it1 = eina_list_nth(l, 0);
4533 it2 = eina_list_nth(l, eina_list_count(l)-1);
4534 if (it1) idx1= elm_genlist_item_index_get((Elm_Object_Item *)it1);
4535 if (it2) idx2= elm_genlist_item_index_get((Elm_Object_Item *)it2);
4536 if (idx < idx1) _item_access_highlight(it1);
4537 else if (idx > idx2) _item_access_highlight(it2);
4539 sd->access_unrealize_it = NULL;
4541 if (!sd->queue_idle_enterer)
4542 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd);
4543 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
4547 _scroll_drag_start_cb(Evas_Object *obj,
4548 void *data __UNUSED__)
4550 #if GENLIST_FX_SUPPORT
4551 ELM_GENLIST_DATA_GET(obj, sd);
4552 sd->scrolling = EINA_TRUE;
4555 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
4559 _scroll_cb(Evas_Object *obj,
4560 void *data __UNUSED__)
4562 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
4566 _scroll_drag_stop_cb(Evas_Object *obj,
4567 void *data __UNUSED__)
4569 #if GENLIST_FX_SUPPORT
4570 ELM_GENLIST_DATA_GET(obj, sd);
4571 sd->scrolling = EINA_FALSE;
4573 if (sd->access_unrealize_it)
4575 Elm_Gen_Item *it1, *it2;
4576 Eina_List *l = elm_genlist_realized_items_get(obj);
4579 int idx = 0, idx1 = 0, idx2 = 0;
4580 idx = elm_genlist_item_index_get((Elm_Object_Item *)sd->access_unrealize_it);
4581 it1 = eina_list_nth(l, 0);
4582 it2 = eina_list_nth(l, eina_list_count(l)-1);
4583 if (it1) idx1= elm_genlist_item_index_get((Elm_Object_Item *)it1);
4584 if (it2) idx2= elm_genlist_item_index_get((Elm_Object_Item *)it2);
4585 if (idx < idx1) _item_access_highlight(it1);
4586 else if (idx > idx2) _item_access_highlight(it2);
4588 sd->access_unrealize_it = NULL;
4590 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
4594 _edge_left_cb(Evas_Object *obj,
4595 void *data __UNUSED__)
4597 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
4601 _edge_right_cb(Evas_Object *obj,
4602 void *data __UNUSED__)
4604 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
4608 _edge_top_cb(Evas_Object *obj,
4609 void *data __UNUSED__)
4611 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
4615 _edge_bottom_cb(Evas_Object *obj,
4616 void *data __UNUSED__)
4618 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
4622 _vbar_drag_cb(Evas_Object *obj,
4623 void *data __UNUSED__)
4625 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
4629 _vbar_press_cb(Evas_Object *obj,
4630 void *data __UNUSED__)
4632 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
4636 _vbar_unpress_cb(Evas_Object *obj,
4637 void *data __UNUSED__)
4639 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
4643 _hbar_drag_cb(Evas_Object *obj,
4644 void *data __UNUSED__)
4646 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
4650 _hbar_press_cb(Evas_Object *obj,
4651 void *data __UNUSED__)
4653 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
4657 _hbar_unpress_cb(Evas_Object *obj,
4658 void *data __UNUSED__)
4660 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
4664 _decorate_item_realize(Elm_Gen_Item *it)
4666 if (it->item->deco_it_view) return;
4668 _view_create(it, &(it->item->deco_it_view), it->itc->decorate_item_style);
4669 _view_inflate(it->item->deco_it_view, it, &(it->item->deco_it_contents));
4670 _item_mouse_callbacks_add(it, it->item->deco_it_view);
4672 _item_mouse_callbacks_del(it, VIEW(it));
4673 evas_object_smart_member_del(VIEW(it));
4674 edje_object_part_swallow
4675 (it->item->deco_it_view,
4676 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
4678 it->want_unrealize = EINA_FALSE;
4682 _decorate_item_set(Elm_Gen_Item *it)
4684 Elm_Genlist_Smart_Data *sd;
4689 sd = GL_IT(it)->wsd;
4692 it->item->nocache_once = EINA_TRUE;
4694 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
4695 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
4696 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
4698 _decorate_item_realize(it);
4699 if (it->item->group_item)
4700 evas_object_raise(it->item->VIEW(group_item));
4702 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
4704 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
4705 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4706 edje_object_signal_emit(VIEW(it), buf, "elm");
4710 _decorate_item_unset(Elm_Genlist_Smart_Data *sd)
4712 char buf[1024], buf2[1024];
4715 if (!sd->mode_item) return;
4718 it->item->nocache_once = EINA_TRUE;
4720 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
4721 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
4722 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
4724 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
4725 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4726 edje_object_signal_emit(VIEW(it), buf, "elm");
4728 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
4729 sd->decorate_it_type);
4730 edje_object_signal_callback_add
4731 (it->item->deco_it_view, buf2, "elm",
4732 _decorate_item_finished_signal_cb, it);
4734 sd->mode_item = NULL;
4738 // FIXME: difference from upstream
4740 _mouse_down_scroller(void *data,
4741 Evas *evas __UNUSED__,
4742 Evas_Object *obj __UNUSED__,
4743 void *event_info __UNUSED__)
4745 Widget_Data *wd = elm_widget_data_get(data);
4748 wd->drag_started = EINA_FALSE;
4752 _mouse_up_scroller(void *data,
4753 Evas *evas __UNUSED__,
4754 Evas_Object *obj __UNUSED__,
4755 void *event_info __UNUSED__)
4757 Widget_Data *wd = elm_widget_data_get(data);
4760 wd->drag_started = EINA_FALSE;
4764 _mouse_move_scroller(void *data,
4765 Evas *evas __UNUSED__,
4766 Evas_Object *obj __UNUSED__,
4769 Widget_Data *wd = elm_widget_data_get(data);
4770 Evas_Event_Mouse_Move *ev = event_info;
4771 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
4774 if (wd->drag_started) return;
4776 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4777 dx = ev->cur.canvas.x - ev->prev.canvas.x;
4778 dy = ev->cur.canvas.y - ev->prev.canvas.y;
4781 if (adx < 0) adx = -dx;
4782 if (ady < 0) ady = -dy;
4783 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
4787 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
4788 wd->drag_started = EINA_TRUE;
4792 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
4793 wd->drag_started = EINA_TRUE;
4800 _size_cache_free(void *data)
4802 if (data) free(data);
4805 static Evas_Event_Flags
4806 _pinch_zoom_cb(void *data, void *event_info)
4808 Elm_Genlist_Smart_Data *sd = data;
4809 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
4811 if (!sd->down_it) return EVAS_EVENT_FLAG_NONE;
4812 if (p->zoom > 1.0 + FX_ZOOM_TOLERANCE)
4814 evas_object_smart_callback_call(WIDGET(sd->down_it), SIG_MULTI_PINCH_OUT, sd->down_it);
4815 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
4817 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(sd)->obj, ELM_GEN_PINCH_ZOOM_EXPAND);
4818 elm_genlist_item_show((Elm_Object_Item *)sd->down_it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
4821 else if (p->zoom < 1.0 - FX_ZOOM_TOLERANCE)
4823 evas_object_smart_callback_call(WIDGET(sd->down_it), SIG_MULTI_PINCH_IN, sd->down_it);
4824 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_NONE)
4825 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(sd)->obj, ELM_GEN_PINCH_ZOOM_CONTRACT);
4828 return EVAS_EVENT_FLAG_NONE;
4832 _elm_genlist_smart_add(Evas_Object *obj)
4834 Evas_Coord minw, minh;
4835 Elm_Genlist_Pan_Smart_Data *pan_data;
4837 EVAS_SMART_DATA_ALLOC(obj, Elm_Genlist_Smart_Data);
4839 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.add(obj);
4841 priv->finger_minw = 0;
4842 priv->finger_minh = 0;
4843 elm_coords_finger_size_adjust(1, &priv->finger_minw, 1, &priv->finger_minh);
4845 priv->size_caches = eina_hash_string_small_new(_size_cache_free);
4846 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
4847 evas_object_smart_member_add(priv->hit_rect, obj);
4848 elm_widget_sub_object_add(obj, priv->hit_rect);
4850 /* common scroller hit rectangle setup */
4851 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
4852 evas_object_show(priv->hit_rect);
4853 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
4855 elm_widget_can_focus_set(obj, EINA_TRUE);
4856 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
4858 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
4860 /* interface's add() routine issued AFTER the object's smart_add() */
4861 priv->s_iface = evas_object_smart_interface_get
4862 (obj, ELM_SCROLLABLE_IFACE_NAME);
4864 priv->s_iface->objects_set
4865 (obj, ELM_WIDGET_DATA(priv)->resize_obj, priv->hit_rect);
4867 priv->s_iface->bounce_allow_set
4868 (obj, EINA_FALSE, _elm_config->thumbscroll_bounce_enable);
4869 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
4871 priv->s_iface->animate_start_cb_set(obj, _scroll_animate_start_cb);
4872 priv->s_iface->animate_stop_cb_set(obj, _scroll_animate_stop_cb);
4873 priv->s_iface->scroll_cb_set(obj, _scroll_cb);
4874 priv->s_iface->drag_start_cb_set(obj, _scroll_drag_start_cb);
4875 priv->s_iface->drag_stop_cb_set(obj, _scroll_drag_stop_cb);
4876 priv->s_iface->edge_left_cb_set(obj, _edge_left_cb);
4877 priv->s_iface->edge_right_cb_set(obj, _edge_right_cb);
4878 priv->s_iface->edge_top_cb_set(obj, _edge_top_cb);
4879 priv->s_iface->edge_bottom_cb_set(obj, _edge_bottom_cb);
4880 priv->s_iface->vbar_drag_cb_set(obj, _vbar_drag_cb);
4881 priv->s_iface->vbar_press_cb_set(obj, _vbar_press_cb);
4882 priv->s_iface->vbar_unpress_cb_set(obj, _vbar_unpress_cb);
4883 priv->s_iface->hbar_drag_cb_set(obj, _hbar_drag_cb);
4884 priv->s_iface->hbar_press_cb_set(obj, _hbar_press_cb);
4885 priv->s_iface->hbar_unpress_cb_set(obj, _hbar_unpress_cb);
4887 priv->mode = ELM_LIST_SCROLL;
4888 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
4889 priv->item_cache_max = priv->max_items_per_block * 2;
4890 priv->longpress_timeout = _elm_config->longpress_timeout;
4891 priv->highlight = EINA_TRUE;
4893 #if GENLIST_FX_SUPPORT
4894 priv->fx_mode = EINA_FALSE;
4895 priv->rendered = EINA_FALSE;
4896 priv->fx_first_captured = EINA_FALSE;
4897 priv->fx_playing = EINA_FALSE;
4898 priv->fx_items_deleted = EINA_FALSE;
4899 priv->genlist_clearing = EINA_FALSE;
4900 priv->scrolling = EINA_FALSE;
4901 priv->down_it = NULL;
4904 priv->pan_obj = evas_object_smart_add
4905 (evas_object_evas_get(obj), _elm_genlist_pan_smart_class_new());
4906 pan_data = evas_object_smart_data_get(priv->pan_obj);
4907 pan_data->wsd = priv;
4910 // FIXME: difference from upstream
4911 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
4912 _mouse_down_scroller, obj);
4913 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
4914 _mouse_up_scroller, obj);
4915 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
4916 _mouse_move_scroller, obj);
4919 priv->s_iface->extern_pan_set(obj, priv->pan_obj);
4921 edje_object_size_min_calc(ELM_WIDGET_DATA(priv)->resize_obj, &minw, &minh);
4922 evas_object_size_hint_min_set(obj, minw, minh);
4924 _item_cache_all_free(priv);
4925 _mirrored_set(obj, elm_widget_mirrored_get(obj));
4927 const char *str = edje_object_data_get(ELM_WIDGET_DATA(priv)->resize_obj,
4929 if ((str) && (!strcmp(str, "on")))
4930 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
4932 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
4933 priv->select_on_focus_enabled = EINA_FALSE;
4935 priv->g_layer = elm_gesture_layer_add(obj);
4936 if (!priv->g_layer) ERR("elm_gesture_layer_add() failed");
4937 elm_gesture_layer_attach(priv->g_layer, priv->hit_rect);
4938 elm_gesture_layer_cb_set
4939 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
4940 _pinch_zoom_cb, priv);
4941 elm_layout_sizing_eval(obj);
4945 _elm_genlist_smart_del(Evas_Object *obj)
4947 ELM_GENLIST_DATA_GET(obj, sd);
4949 elm_genlist_clear(obj);
4950 if (sd->size_caches) eina_hash_free(sd->size_caches);
4951 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
4953 evas_object_del(sd->pan_obj);
4954 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.del(obj);
4958 _elm_genlist_smart_move(Evas_Object *obj,
4962 ELM_GENLIST_DATA_GET(obj, sd);
4964 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.move(obj, x, y);
4966 evas_object_move(sd->hit_rect, x, y);
4970 _elm_genlist_smart_resize(Evas_Object *obj,
4974 ELM_GENLIST_DATA_GET(obj, sd);
4976 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.resize(obj, w, h);
4978 evas_object_resize(sd->hit_rect, w, h);
4982 _elm_genlist_smart_member_add(Evas_Object *obj,
4983 Evas_Object *member)
4985 ELM_GENLIST_DATA_GET(obj, sd);
4987 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.member_add(obj, member);
4990 evas_object_raise(sd->hit_rect);
4994 _access_obj_process(Elm_Genlist_Smart_Data *sd, Eina_Bool is_access)
4997 Eina_Bool done = EINA_FALSE;
4999 EINA_INLIST_FOREACH(sd->blocks, itb)
5007 EINA_LIST_FOREACH(itb->items, l, it)
5009 if (!it->realized) continue;
5010 if (is_access) _access_widget_item_register(it);
5012 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
5015 else if (done) break;
5020 _elm_genlist_smart_access(Evas_Object *obj, Eina_Bool is_access)
5022 ELM_GENLIST_CHECK(obj);
5023 ELM_GENLIST_DATA_GET(obj, sd);
5026 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
5027 _elm_genlist_smart_focus_next;
5029 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
5030 _access_obj_process(sd, is_access);
5032 evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
5036 _elm_genlist_smart_set_user(Elm_Genlist_Smart_Class *sc)
5038 ELM_WIDGET_CLASS(sc)->base.add = _elm_genlist_smart_add;
5039 ELM_WIDGET_CLASS(sc)->base.del = _elm_genlist_smart_del;
5040 ELM_WIDGET_CLASS(sc)->base.move = _elm_genlist_smart_move;
5041 ELM_WIDGET_CLASS(sc)->base.resize = _elm_genlist_smart_resize;
5042 ELM_WIDGET_CLASS(sc)->base.member_add = _elm_genlist_smart_member_add;
5044 ELM_WIDGET_CLASS(sc)->sub_object_add = _elm_genlist_smart_sub_object_add;
5045 ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_genlist_smart_sub_object_del;
5046 ELM_WIDGET_CLASS(sc)->on_focus = _elm_genlist_smart_on_focus;
5047 ELM_WIDGET_CLASS(sc)->theme = _elm_genlist_smart_theme;
5048 ELM_WIDGET_CLASS(sc)->event = _elm_genlist_smart_event;
5049 ELM_WIDGET_CLASS(sc)->translate = _elm_genlist_smart_translate;
5051 /* not a 'focus chain manager' */
5052 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
5053 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
5055 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_genlist_smart_sizing_eval;
5058 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
5059 ELM_WIDGET_CLASS(sc)->focus_next = _elm_genlist_smart_focus_next;
5061 ELM_WIDGET_CLASS(sc)->access = _elm_genlist_smart_access;
5064 EAPI const Elm_Genlist_Smart_Class *
5065 elm_genlist_smart_class_get(void)
5067 static Elm_Genlist_Smart_Class _sc =
5068 ELM_GENLIST_SMART_CLASS_INIT_NAME_VERSION(ELM_GENLIST_SMART_NAME);
5069 static const Elm_Genlist_Smart_Class *class = NULL;
5070 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
5075 _elm_genlist_smart_set(&_sc);
5076 esc->callbacks = _smart_callbacks;
5083 elm_genlist_add(Evas_Object *parent)
5087 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
5089 obj = elm_widget_add(_elm_genlist_smart_class_new(), parent);
5090 if (!obj) return NULL;
5092 if (!elm_widget_sub_object_add(parent, obj))
5093 ERR("could not add %p as sub object of %p", obj, parent);
5099 static Evas_Object *
5100 _item_content_get_hook(Elm_Gen_Item *it,
5103 Evas_Object *ret = NULL;
5104 if (it->deco_all_view)
5105 ret = edje_object_part_swallow_get(it->deco_all_view, part);
5106 else if (it->decorate_it_set)
5107 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
5109 ret = edje_object_part_swallow_get(VIEW(it), part);
5114 _item_text_get_hook(Elm_Gen_Item *it,
5117 if (!it->itc->func.text_get) return NULL;
5118 const char *ret = NULL;
5119 if (it->deco_all_view)
5120 ret = edje_object_part_text_get(it->deco_all_view, part);
5121 else if (it->decorate_it_set)
5122 ret = edje_object_part_text_get(it->item->deco_it_view, part);
5124 ret = edje_object_part_text_get(VIEW(it), part);
5129 _item_disable_hook(Elm_Object_Item *item)
5133 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5137 _item_select_unselect(it, EINA_FALSE);
5139 if (it == GL_IT(it)->wsd->focused) _item_unfocused(it);
5140 _highlight_timer_disable(it);
5144 if (elm_widget_item_disabled_get(it))
5146 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
5147 if (it->deco_all_view)
5148 edje_object_signal_emit
5149 (it->deco_all_view, "elm,state,disabled", "elm");
5153 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
5154 if (it->deco_all_view)
5155 edje_object_signal_emit
5156 (it->deco_all_view, "elm,state,enabled", "elm");
5158 EINA_LIST_FOREACH(it->content_objs, l, obj)
5159 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(it));
5164 _item_free_common(Elm_Gen_Item *it)
5166 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5167 if (it->item->block) _item_block_del(it);
5169 it->parent->item->items =
5170 eina_list_remove(it->parent->item->items, it);
5171 if (it->item->queued) sd->queue = eina_list_remove(sd->queue, it);
5172 if (it->group) sd->group_items = eina_list_remove(sd->group_items, it);
5174 // FIXME: relative will be better to be fixed. it is too harsh.
5176 it->item->rel->item->rel_revs =
5177 eina_list_remove(it->item->rel->item->rel_revs, it);
5178 if (it->item->rel_revs)
5181 EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
5183 _item_sub_items_clear(it);
5185 #if GENLIST_ENTRY_SUPPORT
5186 it->item->unrealize_disabled = EINA_FALSE;
5191 sd->selected = eina_list_remove(sd->selected, it);
5192 it->selected = EINA_FALSE;
5194 if (sd->show_item == it) sd->show_item = NULL;
5195 if (sd->anchor_item == it)
5198 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5199 if (!sd->anchor_item) sd->anchor_item =
5200 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5202 if (sd->expanded_item == it) sd->expanded_item = NULL;
5203 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
5204 if (sd->state) eina_inlist_sorted_state_free(sd->state);
5206 if (sd->last_selected_item == (Elm_Object_Item *)it)
5207 sd->last_selected_item = NULL;
5209 if (sd->mode_item) sd->mode_item = NULL;
5210 if (it == sd->focused) _item_unfocused(it);
5211 if (it == sd->access_it) sd->access_it = NULL;
5212 if (it == sd->access_bring_it) sd->access_bring_it = NULL;
5213 if (it == sd->access_unrealize_it) sd->access_unrealize_it = NULL;
5214 _highlight_timer_disable(it);
5216 _item_event_del(it);
5218 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
5223 _item_free(Elm_Gen_Item *it)
5225 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5227 elm_widget_item_pre_notify_del(it);
5228 if (it->itc->func.del)
5229 it->itc->func.del((void *)it->base.data, WIDGET(it));
5230 if (it->tooltip.del_cb)
5231 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5232 _item_free_common(it);
5234 _item_unrealize(it, EINA_FALSE);
5235 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
5239 if (sd->calc_job) ecore_job_del(sd->calc_job);
5240 sd->calc_job = ecore_job_add(_calc_job, sd);
5243 #if GENLIST_FX_SUPPORT
5245 _item_del_post_process(Elm_Gen_Item *it)
5247 if ((!it) || (!GL_IT(it))) return;
5248 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5252 GL_IT(it)->has_proxy_it = EINA_FALSE;
5254 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
5258 sd->capture_before_items = eina_list_remove(sd->capture_before_items, pi);
5259 _elm_genlist_proxy_item_del(pi);
5263 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
5267 sd->capture_after_items = eina_list_remove(sd->capture_after_items, pi);
5268 _elm_genlist_proxy_item_del(pi);
5272 _item_unrealize(it, EINA_FALSE);
5274 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
5275 if (it->item) free(it->item);
5278 _elm_widget_item_free((Elm_Widget_Item *)it);
5279 if (sd->calc_job) ecore_job_del(sd->calc_job);
5280 sd->calc_job = ecore_job_add(_calc_job, sd);
5284 _item_del_pre_process(Elm_Gen_Item *it)
5286 if ((!it) || (!GL_IT(it))) return;
5287 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5289 sd->fx_items_deleted = EINA_TRUE;
5290 if (!sd->genlist_clearing)
5292 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5293 if (!eina_list_data_find(sd->pending_del_items, it))
5294 sd->pending_del_items = eina_list_append(sd->pending_del_items, it);
5297 elm_widget_item_pre_notify_del(it);
5298 if (it->itc->func.del)
5299 it->itc->func.del((void *)it->base.data, WIDGET(it));
5300 if (it->tooltip.del_cb)
5301 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5302 _item_free_common(it);
5306 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand,toggle",
5307 "elm", _expand_toggle_signal_cb, it);
5308 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand", "elm",
5309 _expand_signal_cb, it);
5310 edje_object_signal_callback_del_full(VIEW(it), "elm,action,contract", "elm",
5311 _contract_signal_cb, it);
5312 _item_mouse_callbacks_del(it, VIEW(it));
5314 if (sd->genlist_clearing) _item_del_post_process(it);
5319 _item_del_pre_hook(Elm_Object_Item *item)
5321 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5323 #if GENLIST_FX_SUPPORT
5324 if (GL_IT(it)->wsd->fx_mode)
5326 _item_del_pre_process(it);
5335 _item_signal_emit_hook(Elm_Object_Item *it,
5336 const char *emission,
5339 edje_object_signal_emit(VIEW(it), emission, source);
5342 static Elm_Gen_Item *
5343 _elm_genlist_item_new(Elm_Genlist_Smart_Data *sd,
5344 const Elm_Genlist_Item_Class *itc,
5346 Elm_Gen_Item *parent,
5347 Elm_Genlist_Item_Type type,
5349 const void *func_data)
5351 Elm_Gen_Item *it, *it2;
5354 if (!itc) return NULL;
5356 it = elm_widget_item_new(ELM_WIDGET_DATA(sd)->obj, Elm_Gen_Item);
5357 if (!it) return NULL;
5360 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
5362 it->base.data = data;
5363 it->parent = parent;
5364 it->func.func = func;
5365 it->func.data = func_data;
5367 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
5368 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
5369 elm_widget_item_disable_hook_set(it, _item_disable_hook);
5370 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
5371 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
5373 #if 0 // FIXME: difference from upstream
5374 it->can_focus = EINA_TRUE;
5376 //it->del_cb = (Ecore_Cb)_item_free;
5377 //it->highlight_cb = (Ecore_Cb)_item_highlight;
5378 //it->unhighlight_cb = (Ecore_Cb)_item_unhighlight;
5379 //it->sel_cb = (Ecore_Cb)_item_select;
5380 //it->unsel_cb = (Ecore_Cb)_item_unselect;
5381 //it->unrealize_cb = (Ecore_Cb)_item_unrealize_cb;
5383 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
5384 GL_IT(it)->wsd = sd;
5385 GL_IT(it)->type = type;
5386 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
5390 if (it->parent->group)
5391 GL_IT(it)->group_item = parent;
5392 else if (GL_IT(it->parent)->group_item)
5393 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
5395 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
5397 if (!it2->parent->group) depth += 1;
5399 GL_IT(it)->expanded_depth = depth;
5402 #if GENLIST_FX_SUPPORT
5403 it->item->num = sd->item_count;
5406 sd->fx_items_deleted = EINA_FALSE;
5407 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5414 _elm_genlist_item_compare(const void *data,
5417 const Elm_Gen_Item *it, *item1;
5419 it = ELM_GEN_ITEM_FROM_INLIST(data);
5420 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
5421 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5425 _elm_genlist_item_list_compare(const void *data,
5428 const Elm_Gen_Item *it = data;
5429 const Elm_Gen_Item *item1 = data1;
5431 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5435 elm_genlist_items_count(const Evas_Object *obj)
5437 ELM_GENLIST_CHECK(obj) 0;
5438 ELM_GENLIST_DATA_GET(obj, sd);
5440 return sd->item_count;
5443 EAPI Elm_Object_Item *
5444 elm_genlist_item_append(Evas_Object *obj,
5445 const Elm_Genlist_Item_Class *itc,
5447 Elm_Object_Item *parent,
5448 Elm_Genlist_Item_Type type,
5450 const void *func_data)
5454 ELM_GENLIST_CHECK(obj) NULL;
5455 ELM_GENLIST_DATA_GET(obj, sd);
5457 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(((Elm_Widget_Item *)parent),NULL);
5459 it = _elm_genlist_item_new
5460 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5461 if (!it) return NULL;
5466 sd->group_items = eina_list_append(sd->group_items, it);
5467 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
5468 it->item->rel = NULL;
5472 Elm_Gen_Item *it2 = NULL;
5473 Eina_List *ll = eina_list_last(it->parent->item->items);
5475 if (ll) it2 = ll->data;
5476 it->parent->item->items =
5477 eina_list_append(it->parent->item->items, it);
5478 if (!it2) it2 = it->parent;
5479 sd->items = eina_inlist_append_relative
5480 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5481 it->item->rel = it2;
5482 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5484 it->item->before = EINA_FALSE;
5485 _item_queue(sd, it, NULL, EINA_TRUE);
5487 return (Elm_Object_Item *)it;
5490 EAPI Elm_Object_Item *
5491 elm_genlist_item_prepend(Evas_Object *obj,
5492 const Elm_Genlist_Item_Class *itc,
5494 Elm_Object_Item *parent,
5495 Elm_Genlist_Item_Type type,
5497 const void *func_data)
5501 ELM_GENLIST_CHECK(obj) NULL;
5502 ELM_GENLIST_DATA_GET(obj, sd);
5503 it = _elm_genlist_item_new
5504 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5505 if (!it) return NULL;
5510 sd->group_items = eina_list_prepend(sd->group_items, it);
5511 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
5512 it->item->rel = NULL;
5516 Elm_Gen_Item *it2 = NULL;
5517 Eina_List *ll = it->parent->item->items;
5519 if (ll) it2 = ll->data;
5520 it->parent->item->items =
5521 eina_list_prepend(it->parent->item->items, it);
5522 if (!it2) it2 = it->parent;
5523 sd->items = eina_inlist_prepend_relative
5524 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5525 it->item->rel = it2;
5526 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5528 it->item->before = EINA_TRUE;
5529 _item_queue(sd, it, NULL, EINA_TRUE);
5531 return (Elm_Object_Item *)it;
5534 EAPI Elm_Object_Item *
5535 elm_genlist_item_insert_after(Evas_Object *obj,
5536 const Elm_Genlist_Item_Class *itc,
5538 Elm_Object_Item *parent,
5539 Elm_Object_Item *after_it,
5540 Elm_Genlist_Item_Type type,
5542 const void *func_data)
5544 Elm_Gen_Item *after = (Elm_Gen_Item *)after_it;
5547 ELM_GENLIST_CHECK(obj) NULL;
5548 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
5549 ELM_GENLIST_DATA_GET(obj, sd);
5551 /* It makes no sense to insert after in an empty list with after !=
5552 * NULL, something really bad is happening in your app. */
5553 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5555 it = _elm_genlist_item_new
5556 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5557 if (!it) return NULL;
5561 if ((it->group) && (after->group))
5562 sd->group_items = eina_list_append_relative
5563 (sd->group_items, it, after);
5567 it->parent->item->items =
5568 eina_list_append_relative(it->parent->item->items, it, after);
5570 sd->items = eina_inlist_append_relative
5571 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5573 it->item->rel = after;
5574 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5575 it->item->before = EINA_FALSE;
5576 _item_queue(sd, it, NULL, EINA_TRUE);
5578 return (Elm_Object_Item *)it;
5581 EAPI Elm_Object_Item *
5582 elm_genlist_item_insert_before(Evas_Object *obj,
5583 const Elm_Genlist_Item_Class *itc,
5585 Elm_Object_Item *parent,
5586 Elm_Object_Item *before_it,
5587 Elm_Genlist_Item_Type type,
5589 const void *func_data)
5591 Elm_Gen_Item *before = (Elm_Gen_Item *)before_it;
5594 ELM_GENLIST_CHECK(obj) NULL;
5595 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
5596 ELM_GENLIST_DATA_GET(obj, sd);
5598 /* It makes no sense to insert before in an empty list with before
5599 * != NULL, something really bad is happening in your app. */
5600 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5602 it = _elm_genlist_item_new
5603 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5604 if (!it) return NULL;
5608 if (it->group && before->group)
5610 eina_list_prepend_relative(sd->group_items, it, before);
5614 it->parent->item->items =
5615 eina_list_prepend_relative(it->parent->item->items, it, before);
5617 sd->items = eina_inlist_prepend_relative
5618 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5620 it->item->rel = before;
5621 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5622 it->item->before = EINA_TRUE;
5623 _item_queue(sd, it, NULL, EINA_TRUE);
5625 return (Elm_Object_Item *)it;
5628 EAPI Elm_Object_Item *
5629 elm_genlist_item_sorted_insert(Evas_Object *obj,
5630 const Elm_Genlist_Item_Class *itc,
5632 Elm_Object_Item *parent,
5633 Elm_Genlist_Item_Type type,
5634 Eina_Compare_Cb comp,
5636 const void *func_data)
5638 Elm_Gen_Item *rel = NULL;
5641 ELM_GENLIST_CHECK(obj) NULL;
5642 ELM_GENLIST_DATA_GET(obj, sd);
5644 it = _elm_genlist_item_new
5645 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5646 if (!it) return NULL;
5648 sd->item_compare_cb = comp;
5655 l = eina_list_search_sorted_near_list
5656 (it->parent->item->items, _elm_genlist_item_list_compare, it,
5660 rel = eina_list_data_get(l);
5664 if (cmp_result >= 0)
5666 it->parent->item->items = eina_list_prepend_relative_list
5667 (it->parent->item->items, it, l);
5668 sd->items = eina_inlist_prepend_relative
5669 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5670 it->item->before = EINA_FALSE;
5672 else if (cmp_result < 0)
5674 it->parent->item->items = eina_list_append_relative_list
5675 (it->parent->item->items, it, l);
5676 sd->items = eina_inlist_append_relative
5677 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5678 it->item->before = EINA_TRUE;
5685 sd->state = eina_inlist_sorted_state_new();
5686 eina_inlist_sorted_state_init(sd->state, sd->items);
5687 sd->requeued = EINA_FALSE;
5691 sd->group_items = eina_list_append(sd->group_items, it);
5693 sd->items = eina_inlist_sorted_state_insert
5694 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
5697 if (EINA_INLIST_GET(it)->next)
5699 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5700 it->item->before = EINA_TRUE;
5702 else if (EINA_INLIST_GET(it)->prev)
5704 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5705 it->item->before = EINA_FALSE;
5711 it->item->rel = rel;
5712 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
5715 _item_queue(sd, it, _elm_genlist_item_list_compare, EINA_TRUE);
5717 return (Elm_Object_Item *)it;
5720 #if GENLIST_FX_SUPPORT
5722 _elm_genlist_fx_clear(Evas_Object *obj, Eina_Bool force)
5724 ELM_GENLIST_DATA_GET(obj, sd);
5726 Elm_Gen_FX_Item *fi;
5730 if ((!force) && (!sd->fx_first_captured)) return;
5732 EINA_LIST_FREE(sd->capture_before_items, pi)
5733 _elm_genlist_proxy_item_del(pi);
5735 EINA_LIST_FREE(sd->capture_after_items, pi)
5736 _elm_genlist_proxy_item_del(pi);
5738 EINA_LIST_FREE(sd->fx_items, fi)
5740 if (fi->trans) elm_transit_del(fi->trans);
5744 EINA_LIST_FREE (sd->pending_unrealized_items, it)
5745 _item_unrealize(it, EINA_FALSE);
5747 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
5748 _decorate_all_item_unrealize(it);
5750 EINA_LIST_FREE (sd->pending_del_items, it)
5751 _item_del_post_process(it);
5753 if (sd->fx_job) ecore_job_del(sd->fx_job);
5755 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5756 sd->alpha_bg = NULL;
5757 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
5758 sd->fx_timer = NULL;
5760 sd->fx_playing = EINA_FALSE;
5761 sd->sorting = EINA_FALSE;
5762 sd->fx_first_captured = EINA_FALSE;
5763 sd->fx_items_deleted = EINA_FALSE;
5768 elm_genlist_clear(Evas_Object *obj)
5770 ELM_GENLIST_CHECK(obj);
5771 ELM_GENLIST_DATA_GET(obj, sd);
5774 eina_hash_free_buckets(sd->size_caches);
5775 _item_unfocused(sd->focused);
5776 if (sd->mode_item) sd->mode_item = NULL;
5777 if (sd->access_it) sd->access_it = NULL;
5778 if (sd->access_bring_it) sd->access_bring_it = NULL;
5779 if (sd->access_unrealize_it) sd->access_unrealize_it = NULL;
5783 eina_inlist_sorted_state_free(sd->state);
5787 #if GENLIST_FX_SUPPORT
5790 _elm_genlist_fx_clear(obj, EINA_TRUE);
5791 sd->genlist_clearing = EINA_TRUE;
5792 sd->rendered = EINA_FALSE;
5794 sd->scrolling = EINA_FALSE;
5796 #if GENLIST_PINCH_ZOOM_SUPPORT
5797 sd->pinch_zoom_h = 0;
5798 sd->realized_top_item = NULL;
5799 sd->pinch_zoom_mode = ELM_GEN_PINCH_ZOOM_NONE;
5803 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5805 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
5806 // because sd->items can be modified inside elm_widget_item_del()
5809 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
5810 it->item->nocache_once = EINA_TRUE;
5811 elm_widget_item_del(it);
5815 _item_cache_all_free(sd);
5817 sd->pan_changed = EINA_TRUE;
5820 sd->selected = eina_list_free(sd->selected);
5821 sd->selected = NULL;
5824 sd->anchor_item = NULL;
5825 sd->show_item = NULL;
5826 sd->reorder_old_pan_y = 0;
5833 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5834 sd->alpha_bg = NULL;
5838 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
5839 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
5841 elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
5842 sd->s_iface->content_region_show(obj, 0, 0, 0, 0);
5844 #if GENLIST_FX_SUPPORT
5845 sd->genlist_clearing = EINA_FALSE;
5848 if (sd->multi_timer)
5850 ecore_timer_del(sd->multi_timer);
5851 sd->multi_timer = NULL;
5855 ecore_job_del(sd->update_job);
5856 sd->update_job = NULL;
5860 ecore_job_del(sd->calc_job);
5861 sd->calc_job = NULL;
5863 if (sd->queue_idle_enterer)
5865 ecore_idle_enterer_del(sd->queue_idle_enterer);
5866 sd->queue_idle_enterer = NULL;
5868 if (sd->must_recalc_idler)
5870 ecore_idler_del(sd->must_recalc_idler);
5871 sd->must_recalc_idler = NULL;
5873 if (sd->scr_hold_timer)
5875 ecore_timer_del(sd->scr_hold_timer);
5876 sd->scr_hold_timer = NULL;
5878 if (sd->reorder_move_animator)
5880 ecore_animator_del(sd->reorder_move_animator);
5881 sd->reorder_move_animator = NULL;
5884 if (sd->queue) sd->queue = eina_list_free(sd->queue);
5885 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5886 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5890 elm_genlist_multi_select_set(Evas_Object *obj,
5893 ELM_GENLIST_CHECK(obj);
5894 ELM_GENLIST_DATA_GET(obj, sd);
5896 sd->multi = !!multi;
5900 elm_genlist_multi_select_get(const Evas_Object *obj)
5902 ELM_GENLIST_CHECK(obj) EINA_FALSE;
5903 ELM_GENLIST_DATA_GET(obj, sd);
5908 EAPI Elm_Object_Item *
5909 elm_genlist_selected_item_get(const Evas_Object *obj)
5911 ELM_GENLIST_CHECK(obj) NULL;
5912 ELM_GENLIST_DATA_GET(obj, sd);
5915 return sd->selected->data;
5921 elm_genlist_selected_items_get(const Evas_Object *obj)
5923 ELM_GENLIST_CHECK(obj) NULL;
5924 ELM_GENLIST_DATA_GET(obj, sd);
5926 return sd->selected;
5930 elm_genlist_realized_items_get(const Evas_Object *obj)
5933 Eina_List *list = NULL;
5934 Eina_Bool done = EINA_FALSE;
5936 ELM_GENLIST_CHECK(obj) NULL;
5937 ELM_GENLIST_DATA_GET(obj, sd);
5939 EINA_INLIST_FOREACH(sd->blocks, itb)
5947 EINA_LIST_FOREACH(itb->items, l, it)
5949 if (it->realized) list = eina_list_append(list, it);
5960 EAPI Elm_Object_Item *
5961 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5966 Evas_Coord ox, oy, ow, oh;
5970 ELM_GENLIST_CHECK(obj) NULL;
5971 ELM_GENLIST_DATA_GET(obj, sd);
5973 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
5975 EINA_INLIST_FOREACH(sd->blocks, itb)
5980 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
5981 oy + itb->y - itb->sd->pan_y,
5982 itb->w, itb->h, x, y, 1, 1))
5984 EINA_LIST_FOREACH(itb->items, l, it)
5986 Evas_Coord itx, ity;
5988 itx = ox + itb->x + it->x - itb->sd->pan_x;
5989 ity = oy + itb->y + it->y - itb->sd->pan_y;
5990 if (ELM_RECTS_INTERSECT
5991 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5995 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5996 else if (y >= (ity + it->item->h - (it->item->h / 4)))
6001 return (Elm_Object_Item *)it;
6003 lasty = ity + it->item->h;
6008 if (y > lasty) *posret = 1;
6015 EAPI Elm_Object_Item *
6016 elm_genlist_first_item_get(const Evas_Object *obj)
6018 Elm_Gen_Item *tit, *it = NULL;
6020 ELM_GENLIST_CHECK(obj) NULL;
6021 ELM_GENLIST_DATA_GET(obj, sd);
6023 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
6025 return (Elm_Object_Item *)it;
6028 EAPI Elm_Object_Item *
6029 elm_genlist_last_item_get(const Evas_Object *obj)
6033 ELM_GENLIST_CHECK(obj) NULL;
6034 ELM_GENLIST_DATA_GET(obj, sd);
6035 if (!sd->items) return NULL;
6037 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
6038 return (Elm_Object_Item *)it;
6041 EAPI Elm_Object_Item *
6042 elm_genlist_item_next_get(const Elm_Object_Item *item)
6046 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6048 it = (Elm_Gen_Item *)item;
6051 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6055 return (Elm_Object_Item *)it;
6058 EAPI Elm_Object_Item *
6059 elm_genlist_item_prev_get(const Elm_Object_Item *item)
6063 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6065 it = (Elm_Gen_Item *)item;
6068 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6072 return (Elm_Object_Item *)it;
6075 EAPI Elm_Object_Item *
6076 elm_genlist_item_parent_get(const Elm_Object_Item *it)
6078 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
6080 return (Elm_Object_Item *)((Elm_Gen_Item *)it)->parent;
6084 elm_genlist_item_subitems_clear(Elm_Object_Item *item)
6086 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6088 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6089 _item_sub_items_clear(it);
6093 elm_genlist_item_selected_set(Elm_Object_Item *item,
6096 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6097 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6099 if (elm_widget_item_disabled_get(it)) return;
6100 selected = !!selected;
6101 if (it->selected == selected) return;
6103 _item_select_unselect(it, selected);
6107 elm_genlist_item_selected_get(const Elm_Object_Item *it)
6109 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6111 return ((Elm_Gen_Item *)it)->selected;
6114 static Elm_Gen_Item *
6115 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
6119 if (it->item->expanded)
6121 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
6125 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
6128 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
6129 it2 = (Elm_Gen_Item *)
6130 elm_genlist_item_next_get((Elm_Object_Item *)it2);
6136 static Evas_Object *
6137 _tray_alpha_bg_create(const Evas_Object *obj)
6139 Evas_Object *bg = NULL;
6140 Evas_Coord ox, oy, ow, oh;
6142 ELM_GENLIST_CHECK(obj) NULL;
6143 ELM_GENLIST_DATA_GET(obj, sd);
6145 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6146 bg = evas_object_rectangle_add
6147 (evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
6148 evas_object_color_set(bg, 0, 0, 0, 0);
6149 evas_object_resize(bg, ow, oh);
6150 evas_object_move(bg, ox, oy);
6156 elm_genlist_item_expanded_set(Elm_Object_Item *item,
6159 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6161 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6163 expanded = !!expanded;
6164 if (it->item->expanded == expanded) return;
6165 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
6166 it->item->expanded = expanded;
6167 GL_IT(it)->wsd->expanded_item = it;
6168 GL_IT(it)->wsd->expanded_next_item =
6169 _elm_genlist_expanded_next_item_get(it);
6171 if (it->item->expanded)
6174 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
6175 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
6176 GL_IT(it)->wsd->auto_scroll_enabled = EINA_TRUE;
6181 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
6182 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
6183 GL_IT(it)->wsd->auto_scroll_enabled = EINA_FALSE;
6188 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
6190 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6192 return ((Elm_Gen_Item *)it)->item->expanded;
6196 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
6198 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
6200 return ((Elm_Gen_Item *)it)->item->expanded_depth;
6204 _elm_genlist_item_coordinates_calc(Elm_Gen_Item *it,
6205 Elm_Genlist_Item_Scrollto_Type type,
6212 Evas_Coord gith = 0;
6214 if ((it->item->queued) || !(it->item->mincalcd))
6216 GL_IT(it)->wsd->show_item = it;
6217 GL_IT(it)->wsd->bring_in = bring_in;
6218 GL_IT(it)->wsd->scroll_to_type = type;
6219 it->item->show_me = EINA_TRUE;
6222 if (GL_IT(it)->wsd->show_item)
6224 GL_IT(it)->wsd->show_item->item->show_me = EINA_FALSE;
6225 GL_IT(it)->wsd->show_item = NULL;
6228 evas_object_geometry_get(GL_IT(it)->wsd->pan_obj, NULL, NULL, w, h);
6231 case ELM_GENLIST_ITEM_SCROLLTO_IN:
6232 if ((it->item->group_item) &&
6233 (GL_IT(it)->wsd->pan_y > (it->y + it->item->block->y)))
6234 gith = it->item->group_item->item->h;
6236 *y = it->y + it->item->block->y - gith;
6239 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
6240 if (it->item->group_item) gith = it->item->group_item->item->h;
6241 *y = it->y + it->item->block->y - gith;
6244 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
6245 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
6252 *x = it->x + it->item->block->x;
6253 *w = it->item->block->w;
6259 elm_genlist_item_promote(Elm_Object_Item *item)
6261 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6262 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6264 (it, (Elm_Gen_Item *)elm_genlist_first_item_get(WIDGET(it)));
6268 elm_genlist_item_demote(Elm_Object_Item *item)
6270 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6271 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6272 _item_move_after(it, (Elm_Gen_Item *)elm_genlist_last_item_get(WIDGET(it)));
6276 elm_genlist_item_show(Elm_Object_Item *item,
6277 Elm_Genlist_Item_Scrollto_Type type)
6279 Evas_Coord x, y, w, h;
6280 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6281 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6283 if (_elm_genlist_item_coordinates_calc
6284 (it, type, EINA_FALSE, &x, &y, &w, &h))
6285 GL_IT(it)->wsd->s_iface->content_region_show(WIDGET(item), x, y, w, h);
6289 elm_genlist_item_bring_in(Elm_Object_Item *item,
6290 Elm_Genlist_Item_Scrollto_Type type)
6292 Evas_Coord x, y, w, h;
6293 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6294 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6296 if (_elm_genlist_item_coordinates_calc
6297 (it, type, EINA_TRUE, &x, &y, &w, &h))
6298 GL_IT(it)->wsd->s_iface->region_bring_in(WIDGET(item), x, y, w, h);
6302 elm_genlist_item_all_contents_unset(Elm_Object_Item *item,
6305 Evas_Object *content;
6307 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6308 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6310 EINA_LIST_FREE (it->content_objs, content)
6312 evas_object_smart_member_del(content);
6313 evas_object_hide(content);
6314 if (l) *l = eina_list_append(*l, content);
6319 elm_genlist_item_update(Elm_Object_Item *item)
6321 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6322 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6324 if (!it->item->block) return;
6325 it->item->mincalcd = EINA_FALSE;
6326 it->item->updateme = EINA_TRUE;
6327 it->item->block->updateme = EINA_TRUE;
6329 #if GENLIST_FX_SUPPORT
6330 _elm_genlist_fx_clear(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj, EINA_FALSE);
6333 if (GL_IT(it)->wsd->update_job) ecore_job_del(GL_IT(it)->wsd->update_job);
6334 GL_IT(it)->wsd->update_job = ecore_job_add(_update_job, GL_IT(it)->wsd);
6338 elm_genlist_item_fields_update(Elm_Object_Item *item,
6340 Elm_Genlist_Item_Field_Type itf)
6342 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6343 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6345 if (!it->item->block) return;
6347 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
6349 _item_text_realize(it, VIEW(it), parts);
6351 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
6353 it->content_objs = _item_content_realize
6354 (it, VIEW(it), it->content_objs, "contents", parts);
6357 it->item->flip_content_objs =
6358 _item_content_realize(it, VIEW(it), it->item->flip_content_objs,
6361 if (it->item->deco_it_view)
6363 it->item->deco_it_contents =
6364 _item_content_realize(it, it->item->deco_it_view,
6365 it->item->deco_it_contents,
6368 if (GL_IT(it)->wsd->decorate_all_mode)
6370 it->item->deco_all_contents =
6371 _item_content_realize(it, it->deco_all_view,
6372 it->item->deco_all_contents,
6377 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
6378 _item_state_realize(it, VIEW(it), parts);
6382 elm_genlist_item_item_class_update(Elm_Object_Item *item,
6383 const Elm_Genlist_Item_Class *itc)
6385 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6386 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6388 EINA_SAFETY_ON_NULL_RETURN(itc);
6391 if (!it->item->block) return;
6392 it->item->nocache_once = EINA_TRUE;
6394 elm_genlist_item_update(item);
6397 EAPI const Elm_Genlist_Item_Class *
6398 elm_genlist_item_item_class_get(const Elm_Object_Item *item)
6400 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6401 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6405 static Evas_Object *
6406 _elm_genlist_item_label_create(void *data,
6407 Evas_Object *obj __UNUSED__,
6408 Evas_Object *tooltip,
6409 void *it __UNUSED__)
6411 Evas_Object *label = elm_label_add(tooltip);
6416 elm_object_style_set(label, "tooltip");
6417 elm_object_text_set(label, data);
6423 _elm_genlist_item_label_del_cb(void *data,
6424 Evas_Object *obj __UNUSED__,
6425 void *event_info __UNUSED__)
6427 eina_stringshare_del(data);
6431 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
6434 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6436 text = eina_stringshare_add(text);
6437 elm_genlist_item_tooltip_content_cb_set
6438 (it, _elm_genlist_item_label_create, text,
6439 _elm_genlist_item_label_del_cb);
6443 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
6444 Elm_Tooltip_Item_Content_Cb func,
6446 Evas_Smart_Cb del_cb)
6448 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6450 ELM_GENLIST_ITEM_CHECK_OR_GOTO(item, error);
6452 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
6455 if (it->tooltip.del_cb)
6456 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6458 it->tooltip.content_cb = func;
6459 it->tooltip.data = data;
6460 it->tooltip.del_cb = del_cb;
6464 elm_widget_item_tooltip_content_cb_set
6465 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
6466 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
6467 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
6473 if (del_cb) del_cb((void *)data, NULL, NULL);
6477 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
6479 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6481 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6483 if ((VIEW(it)) && (it->tooltip.content_cb))
6484 elm_widget_item_tooltip_unset(it);
6486 if (it->tooltip.del_cb)
6487 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6488 it->tooltip.del_cb = NULL;
6489 it->tooltip.content_cb = NULL;
6490 it->tooltip.data = NULL;
6491 it->tooltip.free_size = EINA_FALSE;
6492 if (it->tooltip.style)
6493 elm_genlist_item_tooltip_style_set(item, NULL);
6497 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
6500 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6502 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6504 eina_stringshare_replace(&it->tooltip.style, style);
6505 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
6509 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
6511 return elm_object_item_tooltip_style_get(it);
6515 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
6518 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6520 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
6522 it->tooltip.free_size = disable;
6523 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
6529 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
6531 return elm_object_tooltip_window_mode_get(VIEW(it));
6535 elm_genlist_item_cursor_set(Elm_Object_Item *item,
6538 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6540 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6541 eina_stringshare_replace(&it->mouse_cursor, cursor);
6542 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
6546 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
6548 return elm_widget_item_cursor_get(it);
6552 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
6554 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6556 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6558 if (!it->mouse_cursor) return;
6560 if (VIEW(it)) elm_widget_item_cursor_unset(it);
6562 eina_stringshare_del(it->mouse_cursor);
6563 it->mouse_cursor = NULL;
6567 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
6570 elm_widget_item_cursor_style_set(it, style);
6574 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
6576 return elm_widget_item_cursor_style_get(it);
6580 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
6581 Eina_Bool engine_only)
6583 elm_widget_item_cursor_engine_only_set(it, engine_only);
6587 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
6589 return elm_widget_item_cursor_engine_only_get(it);
6593 elm_genlist_item_index_get(const Elm_Object_Item *item)
6597 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6599 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, -1);
6601 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
6603 if (tmp == it) break;
6610 elm_genlist_mode_set(Evas_Object *obj,
6613 ELM_GENLIST_CHECK(obj);
6614 ELM_GENLIST_DATA_GET(obj, sd);
6616 if (sd->mode == mode) return;
6618 elm_layout_sizing_eval(obj);
6622 elm_genlist_mode_get(const Evas_Object *obj)
6624 ELM_GENLIST_CHECK(obj) ELM_LIST_LAST;
6625 ELM_GENLIST_DATA_GET(obj, sd);
6631 elm_genlist_bounce_set(Evas_Object *obj,
6635 ELM_GENLIST_CHECK(obj);
6636 ELM_GENLIST_DATA_GET(obj, sd);
6638 sd->h_bounce = !!h_bounce;
6639 sd->v_bounce = !!v_bounce;
6640 sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
6644 elm_genlist_bounce_get(const Evas_Object *obj,
6645 Eina_Bool *h_bounce,
6646 Eina_Bool *v_bounce)
6648 ELM_GENLIST_CHECK(obj);
6649 ELM_GENLIST_DATA_GET(obj, sd);
6651 if (h_bounce) *h_bounce = sd->h_bounce;
6652 if (v_bounce) *v_bounce = sd->v_bounce;
6656 elm_genlist_homogeneous_set(Evas_Object *obj,
6657 Eina_Bool homogeneous)
6659 ELM_GENLIST_CHECK(obj);
6660 ELM_GENLIST_DATA_GET(obj, sd);
6662 sd->homogeneous = !!homogeneous;
6666 elm_genlist_homogeneous_get(const Evas_Object *obj)
6668 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6669 ELM_GENLIST_DATA_GET(obj, sd);
6671 return sd->homogeneous;
6675 elm_genlist_block_count_set(Evas_Object *obj,
6678 ELM_GENLIST_CHECK(obj);
6679 ELM_GENLIST_DATA_GET(obj, sd);
6680 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
6682 sd->max_items_per_block = count;
6683 sd->item_cache_max = sd->max_items_per_block * 2;
6684 _item_cache_all_free(sd);
6688 elm_genlist_block_count_get(const Evas_Object *obj)
6690 ELM_GENLIST_CHECK(obj) 0;
6691 ELM_GENLIST_DATA_GET(obj, sd);
6693 return sd->max_items_per_block;
6697 elm_genlist_longpress_timeout_set(Evas_Object *obj,
6700 ELM_GENLIST_CHECK(obj);
6701 ELM_GENLIST_DATA_GET(obj, sd);
6703 sd->longpress_timeout = timeout;
6707 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
6709 ELM_GENLIST_CHECK(obj) 0;
6710 ELM_GENLIST_DATA_GET(obj, sd);
6712 return sd->longpress_timeout;
6716 elm_genlist_scroller_policy_set(Evas_Object *obj,
6717 Elm_Scroller_Policy policy_h,
6718 Elm_Scroller_Policy policy_v)
6720 ELM_GENLIST_CHECK(obj);
6721 ELM_GENLIST_DATA_GET(obj, sd);
6723 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
6724 (policy_v >= ELM_SCROLLER_POLICY_LAST))
6727 sd->s_iface->policy_set(obj, policy_h, policy_v);
6731 elm_genlist_scroller_policy_get(const Evas_Object *obj,
6732 Elm_Scroller_Policy *policy_h,
6733 Elm_Scroller_Policy *policy_v)
6735 Elm_Scroller_Policy s_policy_h, s_policy_v;
6737 ELM_GENLIST_CHECK(obj);
6738 ELM_GENLIST_DATA_GET(obj, sd);
6740 sd->s_iface->policy_get(obj, &s_policy_h, &s_policy_v);
6741 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
6742 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
6746 elm_genlist_realized_items_update(Evas_Object *obj)
6748 Eina_List *list, *l;
6749 Elm_Object_Item *it;
6751 ELM_GENLIST_CHECK(obj);
6753 list = elm_genlist_realized_items_get(obj);
6754 EINA_LIST_FOREACH(list, l, it)
6755 elm_genlist_item_update(it);
6759 elm_genlist_item_decorate_mode_set(Elm_Object_Item *item,
6760 const char *decorate_it_type,
6761 Eina_Bool decorate_it_set)
6763 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6764 Elm_Genlist_Smart_Data *sd;
6766 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6767 sd = GL_IT(it)->wsd;
6769 if (elm_widget_item_disabled_get(it)) return;
6770 if (!decorate_it_type) return;
6771 if (sd->decorate_all_mode) return;
6773 if ((sd->mode_item == it) &&
6774 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
6777 if (!it->itc->decorate_item_style) return;
6778 it->decorate_it_set = decorate_it_set;
6781 if (((sd->decorate_it_type)
6782 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
6783 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
6784 _decorate_item_unset(sd);
6786 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
6787 if (decorate_it_set) _decorate_item_set(it);
6791 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *item)
6793 Elm_Gen_Item *i = (Elm_Gen_Item *)item;
6795 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6796 return GL_IT(i)->wsd->decorate_it_type;
6799 EAPI Elm_Object_Item *
6800 elm_genlist_decorated_item_get(const Evas_Object *obj)
6802 ELM_GENLIST_CHECK(obj) NULL;
6803 ELM_GENLIST_DATA_GET(obj, sd);
6805 return (Elm_Object_Item *)sd->mode_item;
6809 elm_genlist_decorate_mode_get(const Evas_Object *obj)
6811 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6812 ELM_GENLIST_DATA_GET(obj, sd);
6814 return sd->decorate_all_mode;
6818 elm_genlist_decorate_mode_set(Evas_Object *obj,
6819 Eina_Bool decorated)
6824 ELM_GENLIST_CHECK(obj);
6825 ELM_GENLIST_DATA_GET(obj, sd);
6827 decorated = !!decorated;
6828 if (sd->decorate_all_mode == decorated) return;
6829 // decorate_all_mode should be set first
6830 // because content_get func. will be called after this
6831 // and user can check whether deocrate_all_mode is enabeld.
6832 sd->decorate_all_mode = decorated;
6834 list = elm_genlist_realized_items_get(obj);
6835 EINA_LIST_FREE(list, it)
6837 if (!sd->decorate_all_mode)
6839 _decorate_all_item_unrealize(it);
6840 edje_object_signal_emit
6841 (it->deco_all_view, "elm,state,decorate,disabled", "elm");
6842 edje_object_signal_emit
6843 (VIEW(it), "elm,state,decorate,disabled", "elm");
6847 _decorate_all_item_realize(it);
6848 edje_object_signal_emit
6849 (it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
6850 edje_object_signal_emit
6851 (VIEW(it),"elm,state,decorate,enabled,effect", "elm");
6853 _item_min_calc(it, NULL, NULL);
6854 _elm_genlist_item_reorder_state_update(it);
6855 _elm_genlist_item_normal_state_update(it);
6858 #if GENLIST_FX_SUPPORT
6859 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
6861 if (sd->calc_job) ecore_job_del(sd->calc_job);
6862 sd->calc_job = ecore_job_add(_calc_job, sd);
6866 elm_genlist_reorder_mode_set(Evas_Object *obj,
6867 Eina_Bool reorder_mode)
6871 ELM_GENLIST_CHECK(obj);
6872 ELM_GENLIST_DATA_GET(obj, sd);
6874 if (sd->reorder_mode == !!reorder_mode) return;
6875 sd->reorder_mode = !!reorder_mode;
6877 list = elm_genlist_realized_items_get(obj);
6878 EINA_LIST_FREE(list, it)
6880 if (sd->reorder_mode)
6882 edje_object_signal_emit
6883 (VIEW(it), "elm,state,reorder,mode_set", "elm");
6884 if (it->deco_all_view)
6885 edje_object_signal_emit
6886 (it->deco_all_view, "elm,state,reorder,mode_set", "elm");
6890 edje_object_signal_emit
6891 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
6892 if (it->deco_all_view)
6893 edje_object_signal_emit
6894 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
6896 _elm_genlist_item_decorate_state_update(it);
6897 _elm_genlist_item_normal_state_update(it);
6902 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6904 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6905 ELM_GENLIST_DATA_GET(obj, sd);
6907 return sd->reorder_mode;
6910 EAPI Elm_Genlist_Item_Type
6911 elm_genlist_item_type_get(const Elm_Object_Item *item)
6913 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6915 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_GENLIST_ITEM_MAX);
6917 return it->item->type;
6920 EAPI Elm_Genlist_Item_Class *
6921 elm_genlist_item_class_new(void)
6923 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
6924 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6926 itc->version = CLASS_ALLOCATED;
6928 itc->delete_me = EINA_FALSE;
6934 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6936 if (itc && (itc->version == CLASS_ALLOCATED))
6938 itc->delete_me = EINA_TRUE;
6939 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6949 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6951 if (itc && (itc->version == CLASS_ALLOCATED))
6954 if (itc->refcount == 0) itc->refcount--;
6959 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6961 if (itc && (itc->version == CLASS_ALLOCATED))
6963 if (itc->refcount > 0) itc->refcount--;
6964 if (itc->delete_me && (!itc->refcount))
6965 elm_genlist_item_class_free(itc);
6970 elm_genlist_item_flip_set(Elm_Object_Item *item,
6973 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6974 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6977 if (it->flipped == flip) return;
6982 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
6983 if (GL_IT(it)->wsd->decorate_all_mode)
6984 edje_object_signal_emit
6985 (it->deco_all_view, "elm,state,flip,enabled", "elm");
6986 else if (it->item->deco_it_view)
6987 edje_object_signal_emit
6988 (it->item->deco_it_view, "elm,state,flip,enabled", "elm");
6990 it->item->flip_content_objs =
6991 _item_content_realize(it, VIEW(it), it->item->flip_content_objs,
6997 edje_object_signal_emit(VIEW(it), "elm,state,flip,disabled", "elm");
6998 if (GL_IT(it)->wsd->decorate_all_mode)
6999 edje_object_signal_emit
7000 (it->deco_all_view, "elm,state,flip,disabled", "elm");
7001 else if (it->item->deco_it_view)
7002 edje_object_signal_emit
7003 (it->item->deco_it_view, "elm,state,flip,disabled", "elm");
7005 EINA_LIST_FREE(it->item->flip_content_objs, c)
7008 // FIXME: update texts should be done by app?
7009 _item_text_realize(it, VIEW(it), NULL);
7014 elm_genlist_item_flip_get(const Elm_Object_Item *item)
7016 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
7018 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
7024 elm_genlist_select_mode_set(Evas_Object *obj,
7025 Elm_Object_Select_Mode mode)
7027 ELM_GENLIST_CHECK(obj);
7028 ELM_GENLIST_DATA_GET(obj, sd);
7030 if (mode >= ELM_OBJECT_SELECT_MODE_MAX || (sd->select_mode == mode))
7033 sd->select_mode = mode;
7034 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
7035 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
7039 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it)
7044 EAPI Elm_Object_Select_Mode
7045 elm_genlist_select_mode_get(const Evas_Object *obj)
7047 ELM_GENLIST_CHECK(obj) ELM_OBJECT_SELECT_MODE_MAX;
7048 ELM_GENLIST_DATA_GET(obj, sd);
7050 return sd->select_mode;
7054 elm_genlist_highlight_mode_set(Evas_Object *obj,
7055 Eina_Bool highlight)
7057 ELM_GENLIST_CHECK(obj);
7058 ELM_GENLIST_DATA_GET(obj, sd);
7060 sd->highlight = !!highlight;
7064 elm_genlist_highlight_mode_get(const Evas_Object *obj)
7066 ELM_GENLIST_CHECK(obj) EINA_FALSE;
7067 ELM_GENLIST_DATA_GET(obj, sd);
7069 return sd->highlight;
7073 elm_genlist_item_select_mode_set(Elm_Object_Item *item,
7074 Elm_Object_Select_Mode mode)
7076 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
7078 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
7079 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
7081 if (it->select_mode != mode)
7082 it->select_mode = mode;
7084 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
7085 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
7088 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
7090 it->item->mincalcd = EINA_FALSE;
7091 it->item->updateme = EINA_TRUE;
7092 if (it->item->block) it->item->block->updateme = EINA_TRUE;
7093 if (GL_IT(it)->wsd->update_job)
7094 ecore_job_del(GL_IT(it)->wsd->update_job);
7095 GL_IT(it)->wsd->update_job =
7096 ecore_job_add(_update_job, GL_IT(it)->wsd);
7100 EAPI Elm_Object_Select_Mode
7101 elm_genlist_item_select_mode_get(const Elm_Object_Item *item)
7103 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
7105 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_OBJECT_SELECT_MODE_MAX);
7107 return it->select_mode;
7110 // will be deprecated
7112 elm_genlist_tree_effect_enabled_set(Evas_Object *obj __UNUSED__,
7113 Eina_Bool enabled __UNUSED__)
7115 ELM_GENLIST_CHECK(obj);
7118 // will be deprecated
7120 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj __UNUSED__)
7122 ELM_GENLIST_CHECK(obj) EINA_FALSE;
7127 EAPI Elm_Object_Item *
7128 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
7130 Elm_Gen_Item *it = NULL;
7134 ELM_GENLIST_CHECK(obj) NULL;
7135 ELM_GENLIST_DATA_GET(obj, sd);
7137 if (!sd->items) return NULL;
7139 a = eina_inlist_accessor_new(sd->items);
7140 if (!a) return NULL;
7141 if (eina_accessor_data_get(a, nth, &data))
7142 it = ELM_GEN_ITEM_FROM_INLIST(data);
7143 eina_accessor_free(a);
7144 return (Elm_Object_Item *)it;
7147 #if GENLIST_FX_SUPPORT
7149 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
7151 ELM_GENLIST_CHECK(obj);
7152 ELM_GENLIST_DATA_GET(obj, sd);
7158 elm_genlist_fx_mode_get(const Evas_Object *obj)
7160 ELM_GENLIST_CHECK(obj) EINA_FALSE;
7161 ELM_GENLIST_DATA_GET(obj, sd);
7167 _elm_genlist_proxy_item_del(Proxy_Item *pi)
7169 if ((!pi) || (!pi->proxy)) return;
7171 if ((pi->it) && (GL_IT(pi->it)))
7172 GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
7175 evas_object_map_enable_set(pi->proxy, EINA_FALSE);
7176 evas_object_clip_unset(pi->proxy);
7177 evas_object_smart_member_del(pi->proxy);
7178 evas_object_del(pi->proxy);
7183 _item_all_position(Elm_Gen_Item *it,
7189 if (it->deco_all_view)
7191 _item_position(it, it->deco_all_view, it_x, it_y);
7192 evas_object_show(it->deco_all_view);
7194 else if (it->item->deco_it_view)
7196 _item_position(it, it->item->deco_it_view, it_x, it_y);
7197 evas_object_show(it->item->deco_it_view);
7201 _item_position(it, VIEW(it), it_x, it_y);
7202 evas_object_show(VIEW(it));
7207 _elm_genlist_proxy_item_new(const Elm_Object_Item *item)
7209 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
7210 if ((!it) || (!it->item)) return EINA_FALSE;
7213 Proxy_Item *pi = NULL;
7214 pi = calloc(1, sizeof(Proxy_Item));
7215 if (!pi) return NULL;
7217 pi->proxy = evas_object_image_filled_add
7218 (evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
7224 evas_object_clip_set(pi->proxy, evas_object_clip_get(GL_IT(it)->wsd->pan_obj));
7225 evas_object_smart_member_add(pi->proxy, GL_IT(it)->wsd->pan_obj);
7226 elm_widget_sub_object_add(WIDGET(it), pi->proxy);
7227 evas_object_hide(pi->proxy);
7229 if ((GL_IT(it)->wsd->decorate_all_mode) && (it->deco_all_view))
7230 evas_object_image_source_set(pi->proxy, it->deco_all_view);
7232 evas_object_image_source_set(pi->proxy, VIEW(it));
7234 GL_IT(it)->has_proxy_it = EINA_TRUE;
7236 pi->num = it->item->num;
7237 pi->x = it->item->scrl_x;
7238 pi->y = it->item->scrl_y;
7239 pi->w = it->item->w;
7240 pi->h = it->item->h;
7242 evas_object_geometry_get(VIEW(it), NULL, NULL, &w, &h);
7244 if (w <= 0 || h <= 0)
7246 evas_object_size_hint_min_get(VIEW(it), &w, &h);
7247 evas_object_size_hint_min_set(pi->proxy, w, h);
7249 else evas_object_resize(pi->proxy, w, h);
7255 _elm_genlist_fx_capture(Evas_Object *obj, int level)
7257 ELM_GENLIST_DATA_GET(obj, sd);
7261 Eina_Bool done = EINA_FALSE;
7264 Evas_Coord ox, oy, ow, oh;
7266 if ((sd->pinch_zoom_mode) || (sd->scrolling)) return EINA_FALSE;
7269 if ((!sd->rendered) || (sd->fx_playing)) return EINA_FALSE;
7270 if ((!level) && (sd->fx_first_captured)) return EINA_FALSE;
7271 if ((level) && (!sd->fx_first_captured)) return EINA_FALSE;
7273 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7277 sd->fx_first_captured = EINA_TRUE;
7278 EINA_LIST_FREE(sd->capture_before_items, pi)
7279 _elm_genlist_proxy_item_del(pi);
7284 EINA_LIST_FREE(sd->capture_after_items, pi)
7285 _elm_genlist_proxy_item_del(pi);
7287 EINA_INLIST_FOREACH(sd->blocks, itb)
7291 EINA_LIST_FOREACH(itb->items, l, it)
7293 if (it->realized && it->item->scrl_y >= oy)
7295 sd->realized_top_item = it;
7300 if (sd->realized_top_item) break;
7304 EINA_INLIST_FOREACH(sd->blocks, itb)
7309 EINA_LIST_FOREACH(itb->items, l, it)
7313 pi = _elm_genlist_proxy_item_new((Elm_Object_Item *)it);
7316 sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
7319 if (pi->it->deco_all_view)
7320 evas_object_hide(pi->it->deco_all_view);
7321 else if (pi->it->item->deco_it_view)
7322 evas_object_hide(pi->it->item->deco_it_view);
7324 evas_object_hide(VIEW(pi->it));
7325 sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
7330 else if (done) break;
7333 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7334 _item_all_position(pi->it, pi->x, pi->y);
7339 static Elm_Gen_FX_Item *
7340 _elm_genlist_fx_item_find(const Elm_Object_Item *item)
7342 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
7343 if (!it) return EINA_FALSE;
7345 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
7346 if (!sd) return NULL;
7348 Elm_Gen_FX_Item *fi = NULL;
7351 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7353 if (fi->it == it) return fi;
7358 static Elm_Gen_FX_Item *
7359 _elm_genlist_fx_item_new(const Proxy_Item *pi)
7361 if ((!pi) || (!pi->it)) return NULL;
7363 Elm_Gen_FX_Item *fi = NULL;
7364 fi = calloc(1, sizeof(Elm_Gen_FX_Item));
7365 if (!fi) return NULL;
7368 GL_IT(fi->it)->fi = fi;
7369 fi->proxy = pi->proxy;
7371 fi->from.x = fi->to.x = pi->x;
7372 fi->from.y = fi->to.y = pi->y;
7373 fi->from.w = fi->to.w = pi->w;
7374 fi->from.h = fi->to.h = pi->h;
7375 fi->update = EINA_FALSE;
7380 static Elm_Object_Item *
7381 _elm_genlist_fx_item_prev_get(const Elm_Object_Item *item)
7384 it = (Elm_Gen_Item *)item;
7385 if (!it) return NULL;
7386 if (GL_IT(it)->wsd->pinch_zoom_mode) return NULL;
7390 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7394 return (Elm_Object_Item *)it;
7398 _elm_genlist_fx_items_make(Evas_Object *obj)
7400 ELM_GENLIST_CHECK(obj) EINA_FALSE;
7401 ELM_GENLIST_DATA_GET(obj, sd);
7403 Elm_Gen_FX_Item *fi;
7406 Elm_Gen_Item *prev = NULL;
7407 Evas_Coord ox, oy, ow, oh, mv_dist, max_mv_dist = 0;
7409 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7411 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7413 fi = _elm_genlist_fx_item_new(pi);
7414 if (fi) sd->fx_items = eina_list_append(sd->fx_items, fi);
7417 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
7419 fi = _elm_genlist_fx_item_find((Elm_Object_Item *)pi->it);
7421 if (fi) // pi exists in both before and after capture items
7423 fi->type = ELM_GEN_ITEM_FX_TYPE_SAME;
7424 fi->update = EINA_TRUE;
7430 // find the max distance between before and after capture items
7431 mv_dist = abs(fi->to.y - fi->from.y);
7432 if (max_mv_dist < mv_dist) max_mv_dist = mv_dist;
7434 else // pi only exists in after capture items
7436 fi = _elm_genlist_fx_item_new(pi);
7439 fi->type = ELM_GEN_ITEM_FX_TYPE_ADD;
7440 fi->update = EINA_TRUE;
7441 sd->fx_items = eina_list_append(sd->fx_items, fi);
7446 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7448 // find deleted items
7449 if (!fi->update) // pi only exists in before capture items
7451 fi->type = ELM_GEN_ITEM_FX_TYPE_DEL;
7452 fi->update = EINA_TRUE;
7454 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7455 if ((prev) && (GL_IT(prev)->fi))
7457 fi->to.y = GL_IT(prev)->fi->to.y + GL_IT(prev)->fi->to.h;
7460 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7462 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7463 if ((prev) && (prev->realized) && (GL_IT(prev)->fi))
7465 fi->from.y = GL_IT(prev)->fi->from.y + GL_IT(prev)->fi->from.h;
7469 if (sd->realized_top_item)
7472 if (fi->num <= sd->realized_top_item->item->num)
7473 fi->from.y -= max_mv_dist;
7475 fi->from.y += max_mv_dist;
7481 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7483 if ((GL_IT(fi->it)->items) && (GL_IT(fi->it)->expanded_depth == 0))
7485 if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7487 if (sd->realized_top_item)
7489 if (fi->num <= sd->realized_top_item->item->num)
7490 fi->to.y = oy - fi->from.h;
7501 static Elm_Gen_FX_Item *
7502 _fx_cover_item_get(const Elm_Gen_FX_Item *fi)
7504 Elm_Gen_FX_Item *cover_fi;
7506 if (!fi) return NULL;
7508 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7509 Evas_Coord ox, oy, ow, oh;
7510 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7512 EINA_LIST_FOREACH(sd->fx_items, l, cover_fi)
7514 if (fi == cover_fi) continue;
7515 if (sd->fx_items_deleted)
7517 if ((cover_fi->from.y >= oy+oh || cover_fi->from.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y > 0))
7522 if ((cover_fi->to.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y < 0))
7530 _item_fx_zoom_process(Evas_Object *proxy, float from_rate, float to_rate, double progress)
7534 Evas_Coord x, y, w, h;
7537 map = evas_map_new(4);
7540 from = (FX_TRANSIT_FOCAL - (from_rate * FX_TRANSIT_FOCAL)) * (1 / from_rate);
7541 to = ((FX_TRANSIT_FOCAL - (to_rate * FX_TRANSIT_FOCAL)) * (1 / to_rate)) - from;
7543 evas_object_geometry_get(proxy, &x, &y, &w, &h);
7544 evas_map_util_points_populate_from_object_full(map, proxy, from +(progress * to));
7545 evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, FX_TRANSIT_FOCAL);
7546 evas_object_map_enable_set(proxy, EINA_TRUE);
7547 evas_object_map_set(proxy, map);
7553 _item_fx_op(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__, double progress)
7555 Elm_Gen_FX_Item *fi = data, *cover_it;
7556 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7557 Evas_Coord fi_ox, fi_oy, cover_it_ox, cover_it_oy;
7558 Evas_Coord ox, oy, ow, oh;
7560 evas_object_show(VIEW(fi->it));
7561 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7562 evas_object_geometry_get(fi->proxy, &fi_ox, &fi_oy, NULL, NULL);
7563 evas_object_move(fi->proxy, ox, fi_oy);
7564 evas_object_show(fi->proxy);
7566 if ((!sd->pinch_zoom_mode) && (!sd->expanded_item) && (!sd->sorting))
7568 if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7569 _item_fx_zoom_process(fi->proxy, 0.8, 1.0, progress);
7570 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7571 _item_fx_zoom_process(fi->proxy, 1.0, 0.8, progress);
7574 #if GENLIST_PINCH_ZOOM_SUPPORT
7575 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(fi->it))) evas_object_raise(fi->proxy);
7578 if ((!sd->expanded_next_item) || (sd->expanded_next_item == fi->it)) goto raise_event_block;
7579 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME)
7581 evas_object_raise(fi->proxy);
7582 goto raise_event_block;
7585 cover_it = _fx_cover_item_get(fi);
7586 if (!cover_it) goto raise_event_block;
7588 if (((cover_it->from.h)>= (fi->from.h / 2))
7589 || (elm_genlist_item_next_get((Elm_Object_Item *)(cover_it->it))))
7591 evas_object_geometry_get(cover_it->proxy, &cover_it_ox, &cover_it_oy, NULL, NULL);
7593 if (sd->fx_items_deleted)
7596 && (fi_oy + fi->to.h >= cover_it_oy + cover_it->to.h ) && (fi->from.y < cover_it->from.y))
7597 evas_object_hide(fi->proxy);
7599 else if (cover_it_oy && (fi_oy >= cover_it_oy))
7600 evas_object_hide(fi->proxy);
7602 evas_object_show(fi->proxy);
7605 evas_object_raise(sd->alpha_bg);
7611 _item_fx_del_cb(void *data, Elm_Transit *transit __UNUSED__)
7613 Elm_Gen_FX_Item *fx_done_it = data;
7614 Elm_Gen_Item *it = NULL;
7615 Proxy_Item *pi = NULL;
7616 Elm_Genlist_Smart_Data *sd;
7618 if (!fx_done_it || !fx_done_it->it) return;
7620 sd = GL_IT(fx_done_it->it)->wsd;
7623 if ((sd->decorate_all_mode) && (fx_done_it->it->deco_all_view))
7624 _item_position(fx_done_it->it, fx_done_it->it->deco_all_view,
7625 fx_done_it->to.x, fx_done_it->to.y);
7627 _item_position(fx_done_it->it, VIEW(fx_done_it->it),
7628 fx_done_it->to.x, fx_done_it->to.y);
7630 evas_object_image_source_visible_set(fx_done_it->proxy, EINA_TRUE);
7631 evas_object_lower(fx_done_it->proxy);
7632 GL_IT(fx_done_it->it)->has_proxy_it = EINA_FALSE;
7634 sd->fx_items = eina_list_remove(sd->fx_items, fx_done_it);
7635 GL_IT(fx_done_it->it)->fi = NULL;
7638 if (!eina_list_count(sd->fx_items))
7640 EINA_LIST_FREE (sd->pending_unrealized_items, it)
7642 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7643 _item_unrealize(it, EINA_FALSE);
7645 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
7647 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7648 _decorate_all_item_unrealize(it);
7651 EINA_LIST_FREE (sd->pending_del_items, it)
7652 _item_del_post_process(it);
7654 EINA_LIST_FREE(sd->capture_before_items, pi)
7655 if (pi->it) _elm_genlist_proxy_item_del(pi);
7657 EINA_LIST_FREE(sd->capture_after_items, pi)
7658 if (pi->it) _elm_genlist_proxy_item_del(pi);
7660 sd->fx_playing = EINA_FALSE;
7661 sd->sorting = EINA_FALSE;
7662 sd->fx_first_captured = EINA_FALSE;
7663 evas_object_hide(sd->alpha_bg);
7665 sd->realized_top_item = NULL;
7666 sd->pan_changed = EINA_TRUE;
7667 evas_object_smart_changed(sd->pan_obj);
7672 _sorting_effect_animator_cb(void *data)
7674 Elm_Genlist_Smart_Data *sd = data;
7675 Elm_Gen_FX_Item *fi;
7678 Evas_Coord ox, oy, ow, oh;
7679 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7681 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7685 fi->changed = EINA_TRUE;
7686 evas_object_resize(fi->proxy, ow, fi->to.h);
7688 fi->trans = elm_transit_add();
7689 elm_transit_object_add(fi->trans, fi->proxy);
7690 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7691 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7693 elm_transit_effect_translation_add(fi->trans, fi->to.x, fi->to.y - 30 * elm_config_scale_get(), fi->to.x, fi->to.y);
7694 elm_transit_effect_color_add(fi->trans,0, 0, 0, 0, 255,255,255,255);
7696 elm_transit_effect_add(fi->trans, _item_fx_op, fi, NULL);
7697 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7698 elm_transit_duration_set(fi->trans,0.3);
7699 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7700 elm_transit_go(fi->trans);
7702 return ECORE_CALLBACK_RENEW;
7705 sd->fx_timer = NULL;
7706 return ECORE_CALLBACK_CANCEL;
7710 _fx_items_intersect(Evas_Object *obj, Elm_Gen_FX_Item *fi)
7712 ELM_GENLIST_CHECK(obj) EINA_FALSE;
7713 ELM_GENLIST_DATA_GET(obj, sd);
7715 Elm_Gen_FX_Item *fx_it;
7717 EINA_LIST_FOREACH(sd->fx_items, l, fx_it)
7719 if ((fx_it == fi) || (fx_it->type != ELM_GEN_ITEM_FX_TYPE_ADD)) continue;
7720 if ((fi->from.y >= fx_it->from.y && fi->from.y <= fx_it->from.y + fx_it->from.h) ||
7721 (fi->from.y + fi->from.h >= fx_it->from.y && fi->from.y + fi->from.h <= fx_it->from.y + fx_it->from.h))
7728 _elm_genlist_fx_play(Evas_Object *obj)
7730 ELM_GENLIST_CHECK(obj);
7731 ELM_GENLIST_DATA_GET(obj, sd);
7733 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
7734 Elm_Gen_FX_Item *fi;
7737 if (!sd->fx_mode) return;
7739 EINA_LIST_FREE(sd->fx_items, fi)
7741 if (fi->trans) elm_transit_del(fi->trans);
7744 _item_cache_all_free(sd);
7746 _elm_genlist_fx_items_make(obj);
7747 if (!eina_list_count(sd->fx_items) || (sd->queue))
7749 _elm_genlist_fx_clear(obj, EINA_TRUE);
7753 sd->fx_playing = EINA_TRUE;
7755 if (!sd->alpha_bg) sd->alpha_bg = _tray_alpha_bg_create(obj);
7756 evas_object_show(sd->alpha_bg);
7758 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7759 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
7763 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7764 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7765 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
7766 sd->fx_timer = ecore_timer_add(0.05, _sorting_effect_animator_cb, sd);
7770 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7772 if (!fi->proxy) continue;
7774 if ((fi->from.y <= oy) || (fi->from.y + fi->from.h >= oy + oh))
7775 _item_all_position(fi->it, cvx, fi->to.y);
7776 else if ((fi->to.y <= oy) || (fi->to.y + fi->to.h >= oy + oh))
7777 _item_all_position(fi->it, cvx, fi->from.y);
7779 evas_object_resize(fi->proxy, ow, fi->to.h);
7780 evas_object_show(fi->proxy);
7782 fi->trans = elm_transit_add();
7783 elm_transit_object_add(fi->trans, fi->proxy);
7785 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7786 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7788 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME)
7790 evas_object_raise(fi->proxy);
7791 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7794 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7796 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7797 elm_transit_effect_color_add(fi->trans, 0, 0, 0, 0, 255, 255, 255, 255);
7799 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7801 _item_unhighlight(fi->it);
7802 evas_object_raise(fi->proxy);
7803 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7805 if (_fx_items_intersect(obj, fi))
7806 elm_transit_effect_color_add(fi->trans, 1, 1, 1, 1, 0, 0, 0, 0);
7808 elm_transit_effect_color_add(fi->trans, 255, 255, 255, 255, 0, 0, 0, 0);
7810 elm_transit_effect_add(fi->trans, _item_fx_op, fi, NULL);
7811 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7813 elm_transit_duration_set(fi->trans, FX_MOVE_TIME);
7814 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7815 elm_transit_go(fi->trans);
7820 #if GENLIST_PINCH_ZOOM_SUPPORT
7822 elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Elm_Gen_Pinch_Zoom_Mode mode)
7824 ELM_GENLIST_DATA_GET(obj, sd);
7829 Eina_Bool done = EINA_FALSE;
7831 if ((sd->queue) || (!sd->rendered)
7832 || (sd->queue_idle_enterer) || (!sd->fx_mode)) return EINA_FALSE;
7834 if (mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7835 sd->multi_touched = EINA_FALSE;
7836 elm_object_signal_emit(obj, "do-hide-vbar", "");
7838 EINA_INLIST_FOREACH(sd->blocks, itb)
7840 EINA_LIST_FOREACH(itb->items, l, it)
7843 if (IS_ROOT_PARENT_IT(it))
7851 if (!done) return EINA_FALSE;
7853 sd->pinch_zoom_mode = mode;
7855 _item_cache_all_free(sd);
7856 sd->pinch_pan_y = sd->pan_y;
7858 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7859 sd->s_iface->content_region_show(obj, 0,0,0,0);
7861 sd->pan_changed = EINA_TRUE;
7862 evas_object_smart_changed(sd->pan_obj);
7869 eina_list_sort_merge(Eina_List *a, Eina_List *b, Eina_Compare_Cb func)
7871 Eina_List *first, *last;
7873 if (func(a->data, b->data) < 0)
7874 a = (last = first = a)->next;
7876 b = (last = first = b)->next;
7879 if (func(a->data, b->data) < 0)
7880 a = (last = last->next = a)->next;
7882 b = (last = last->next = b)->next;
7884 last->next = a ? a : b;
7890 elm_genlist_sort(Evas_Object *obj, Eina_Compare_Cb func)
7892 ELM_GENLIST_CHECK(obj) NULL;
7893 ELM_GENLIST_DATA_GET(obj, sd);
7894 Eina_List *list = NULL, *l;
7895 Elm_Gen_Item *it, *next, *last_it;;
7896 unsigned int limit = 0, i = 0, n = 0;
7897 Eina_List *tail = NULL, *unsort = NULL, *stack[32], *prev = NULL;
7899 sd->sorting = EINA_TRUE;
7901 it = (Elm_Gen_Item*)elm_genlist_first_item_get(obj);
7904 list = eina_list_append(list, it);
7905 next = (Elm_Gen_Item*)elm_genlist_item_next_get((Elm_Object_Item *)it);
7913 limit = eina_list_count(list);
7917 (limit > list->accounting->count))
7918 limit = list->accounting->count;
7920 if (limit != list->accounting->count)
7922 unsort = eina_list_nth_list(list, limit);
7924 unsort->prev->next = NULL;
7929 unsigned int idx, tmp;
7931 Eina_List *a = tail;
7932 Eina_List *b = tail->next;
7942 if (func(a->data, b->data) < 0)
7943 ((stack[i++] = a)->next = b)->next = 0;
7945 ((stack[i++] = b)->next = a)->next = 0;
7948 for (idx = n ^ tmp; idx &= idx - 1; i--)
7949 stack[i - 2] = eina_list_sort_merge(stack[i - 2], stack[i - 1], func);
7953 stack[i - 1] = eina_list_sort_merge(stack[i - 1], stack[i], func);
7957 for (; stack[0]; stack[0] = stack[0]->next)
7959 stack[0]->prev = prev;
7966 tail->next = unsort;
7967 unsort->prev = tail;
7970 list->accounting->last = tail;
7972 EINA_LIST_FOREACH(list, l, it)
7974 last_it = (Elm_Gen_Item*)elm_genlist_last_item_get(obj);
7975 _item_move_after(it, last_it);
7978 if (!sd->fx_mode) sd->sorting = EINA_FALSE;
7979 if (sd->decorate_all_mode) sd->sorting = EINA_FALSE;
7980 sd->s_iface->content_region_show(obj, 0,0,0,0);
7981 sd->pan_changed = EINA_TRUE;
7982 evas_object_smart_changed(sd->pan_obj);