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
15 EAPI const char ELM_GENLIST_SMART_NAME[] = "elm_genlist";
16 EAPI const char ELM_GENLIST_PAN_SMART_NAME[] = "elm_genlist_pan";
18 #define ERR_ABORT(_msg) \
20 if (getenv("ELM_ERROR_ABORT")) abort();
22 #define GL_IT(_it) (_it->item)
24 #define IS_ROOT_PARENT_IT(_it) \
25 ((_it->group) || (GL_IT(_it)->items && GL_IT(_it)->expanded_depth == 0)) \
27 static const Evas_Smart_Interface *_smart_interfaces[] =
29 (Evas_Smart_Interface *)&ELM_SCROLLABLE_IFACE, NULL
32 static const char SIG_ACTIVATED[] = "activated";
33 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
34 static const char SIG_SELECTED[] = "selected";
35 static const char SIG_UNSELECTED[] = "unselected";
36 static const char SIG_EXPANDED[] = "expanded";
37 static const char SIG_CONTRACTED[] = "contracted";
38 static const char SIG_EXPAND_REQUEST[] = "expand,request";
39 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
40 static const char SIG_REALIZED[] = "realized";
41 static const char SIG_UNREALIZED[] = "unrealized";
42 static const char SIG_DRAG_START_UP[] = "drag,start,up";
43 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
44 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
45 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
46 static const char SIG_DRAG_STOP[] = "drag,stop";
47 static const char SIG_DRAG[] = "drag";
48 static const char SIG_LONGPRESSED[] = "longpressed";
49 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
50 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
51 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
52 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
53 static const char SIG_EDGE_TOP[] = "edge,top";
54 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
55 static const char SIG_EDGE_LEFT[] = "edge,left";
56 static const char SIG_EDGE_RIGHT[] = "edge,right";
57 static const char SIG_VBAR_DRAG[] = "vbar,drag";
58 static const char SIG_VBAR_PRESS[] = "vbar,press";
59 static const char SIG_VBAR_UNPRESS[] = "vbar,unpress";
60 static const char SIG_HBAR_DRAG[] = "hbar,drag";
61 static const char SIG_HBAR_PRESS[] = "hbar,press";
62 static const char SIG_HBAR_UNPRESS[] = "hbar,unpress";
63 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
64 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
65 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
66 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
67 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
68 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
69 static const char SIG_SWIPE[] = "swipe";
70 static const char SIG_MOVED[] = "moved";
71 static const char SIG_MOVED_AFTER[] = "moved,after";
72 static const char SIG_MOVED_BEFORE[] = "moved,before";
73 static const char SIG_INDEX_UPDATE[] = "index,update";
74 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
75 static const char SIG_HIGHLIGHTED[] = "highlighted";
76 static const char SIG_UNHIGHLIGHTED[] = "unhighlighted";
78 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
79 {SIG_CLICKED_DOUBLE, ""},
85 {SIG_EXPAND_REQUEST, ""},
86 {SIG_CONTRACT_REQUEST, ""},
89 {SIG_DRAG_START_UP, ""},
90 {SIG_DRAG_START_DOWN, ""},
91 {SIG_DRAG_START_LEFT, ""},
92 {SIG_DRAG_START_RIGHT, ""},
95 {SIG_LONGPRESSED, ""},
96 {SIG_SCROLL_ANIM_START, ""},
97 {SIG_SCROLL_ANIM_STOP, ""},
98 {SIG_SCROLL_DRAG_START, ""},
99 {SIG_SCROLL_DRAG_STOP, ""},
101 {SIG_EDGE_BOTTOM, ""},
103 {SIG_EDGE_RIGHT, ""},
105 {SIG_VBAR_PRESS, ""},
106 {SIG_VBAR_UNPRESS, ""},
108 {SIG_HBAR_PRESS, ""},
109 {SIG_HBAR_UNPRESS, ""},
110 {SIG_MULTI_SWIPE_LEFT, ""},
111 {SIG_MULTI_SWIPE_RIGHT, ""},
112 {SIG_MULTI_SWIPE_UP, ""},
113 {SIG_MULTI_SWIPE_DOWN, ""},
114 {SIG_MULTI_PINCH_OUT, ""},
115 {SIG_MULTI_PINCH_IN, ""},
118 {SIG_MOVED_AFTER, ""},
119 {SIG_MOVED_BEFORE, ""},
120 {SIG_TREE_EFFECT_FINISHED, ""},
121 {SIG_HIGHLIGHTED, ""},
122 {SIG_UNHIGHLIGHTED, ""},
126 EVAS_SMART_SUBCLASS_IFACE_NEW
127 (ELM_GENLIST_SMART_NAME, _elm_genlist, Elm_Genlist_Smart_Class,
128 Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks,
131 ELM_INTERNAL_SMART_SUBCLASS_NEW
132 (ELM_GENLIST_PAN_SMART_NAME, _elm_genlist_pan, Elm_Genlist_Pan_Smart_Class,
133 Elm_Pan_Smart_Class, elm_pan_smart_class_get, NULL);
135 static void _calc_job(void *);
136 static Eina_Bool _item_block_recalc(Item_Block *, int, Eina_Bool);
137 static void _item_mouse_callbacks_add(Elm_Gen_Item *, Evas_Object *);
138 static void _item_mouse_callbacks_del(Elm_Gen_Item *, Evas_Object *);
139 static void _access_activate_cb(void *data __UNUSED__,
140 Evas_Object *part_obj __UNUSED__,
141 Elm_Object_Item *item);
142 static void _item_select(Elm_Gen_Item *it);
144 static void _expand_toggle_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
145 static void _expand_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
146 static void _contract_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
147 static void _elm_genlist_item_state_update(Elm_Gen_Item *it);
148 static void _decorate_item_unrealize(Elm_Gen_Item *it);
149 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
150 static void _decorate_item_set(Elm_Gen_Item *it);
151 static void _changed_job(Elm_Genlist_Smart_Data *sd);
153 #if GENLIST_FX_SUPPORT
154 static Eina_Bool _elm_genlist_fx_capture(Evas_Object *obj, int level);
155 static void _elm_genlist_fx_play(Evas_Object *obj);
156 static void _elm_genlist_fx_clear(Evas_Object *obj);
157 static void _elm_genlist_proxy_item_del(const Elm_Object_Item *item);
160 #if GENLIST_PINCH_ZOOM_SUPPORT
161 EAPI Eina_Bool elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Elm_Gen_Pinch_Zoom_Mode mode);
165 _item_cache_all_free(Elm_Genlist_Smart_Data *sd)
167 // It would be better not to use
168 // EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
169 while (sd->item_cache)
171 Item_Cache *ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
172 if (ic->spacer) evas_object_del(ic->spacer);
173 if (ic->base_view) evas_object_del(ic->base_view);
174 if (ic->item_style) eina_stringshare_del(ic->item_style);
175 sd->item_cache = eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
176 // Free should be performed after inlist is poped
179 sd->item_cache = NULL;
180 sd->item_cache_count = 0;
184 _item_cache_push(Elm_Gen_Item *it)
186 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
187 Item_Cache *ic = NULL;
189 if (sd->item_cache_count >= sd->item_cache_max)
191 ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
192 if (ic->spacer) evas_object_del(ic->spacer);
193 if (ic->base_view) evas_object_del(ic->base_view);
194 eina_stringshare_del(ic->item_style);
195 sd->item_cache = eina_inlist_remove(sd->item_cache,
196 sd->item_cache->last);
197 sd->item_cache_count--;
198 // Free should be performed after inlist is poped
201 //evas_event_freeze(evas_object_evas_get(obj));
203 edje_object_mirrored_set(VIEW(it),
204 elm_widget_mirrored_get(WIDGET(it)));
205 edje_object_scale_set(VIEW(it),
206 elm_widget_scale_get(WIDGET(it))
207 * elm_config_scale_get());
209 // FIXME: other callbacks?
210 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand,toggle",
211 "elm", _expand_toggle_signal_cb, it);
212 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand", "elm",
213 _expand_signal_cb, it);
214 edje_object_signal_callback_del_full(VIEW(it), "elm,action,contract", "elm",
215 _contract_signal_cb, it);
216 _item_mouse_callbacks_del(it, VIEW(it));
218 #if GENLIST_FX_SUPPORT
219 if ((it->item->nocache_once) || (it->item->nocache) || (sd->pending_del_items))
221 if ((it->item->nocache_once) || (it->item->nocache))
224 if (VIEW(it)) evas_object_del(VIEW(it));
225 if (it->spacer) evas_object_del(it->spacer);
228 ic = ELM_NEW(Item_Cache);
231 if (VIEW(it)) evas_object_del(VIEW(it));
232 if (it->spacer) evas_object_del(it->spacer);
237 ecore_timer_del(it->long_timer);
238 it->long_timer = NULL;
240 if (it->item->swipe_timer)
242 ecore_timer_del(it->item->swipe_timer);
243 it->item->swipe_timer = NULL;
246 ic->base_view = VIEW(it);
247 ic->spacer = it->spacer;
248 ic->item_style = eina_stringshare_add(it->itc->item_style);
249 if (it->item->type & ELM_GENLIST_ITEM_TREE) ic->tree = 1;
251 ic->selected = it->selected;
252 ic->disabled = elm_widget_item_disabled_get(it);
253 ic->expanded = it->item->expanded;
254 if (it->item->type & ELM_GENLIST_ITEM_TREE) ic->tree = 1;
256 edje_object_signal_emit(ic->base_view, "elm,state,unselected", "elm");
257 evas_object_hide(ic->base_view);
259 sd->item_cache = eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(ic));
260 sd->item_cache_count++;
266 it->realized = EINA_FALSE;
267 it->want_unrealize = EINA_FALSE;
269 //evas_event_thaw(evas_object_evas_get(obj));
270 //evas_event_thaw_eval(evas_object_evas_get(obj));
274 _item_cache_pop(Elm_Gen_Item *it)
276 Item_Cache *ic = NULL;
279 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
281 if (it->item->nocache_once) {
282 it->item->nocache_once = EINA_FALSE;
285 if (it->item->nocache) return EINA_FALSE;
287 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
288 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, ic)
290 if ((ic->selected) || (ic->disabled) || (ic->expanded))
293 if ((ic->tree == tree) &&
294 (((!it->itc->item_style) && (!ic->item_style)) ||
295 (it->itc->item_style && ic->item_style &&
296 (!strcmp(it->itc->item_style, ic->item_style)))))
299 eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
300 sd->item_cache_count--;
302 VIEW(it) = ic->base_view;
303 it->spacer = ic->spacer;
305 #if 1 // FIXME: different from upstream
306 // Because of item cache, set state as default after cache item
308 edje_object_signal_emit(VIEW(it),"elm,state,default", "elm");
310 edje_object_signal_callback_add
311 (VIEW(it), "elm,action,expand,toggle", "elm",
312 _expand_toggle_signal_cb, it);
313 edje_object_signal_callback_add
314 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
315 edje_object_signal_callback_add
316 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
317 _item_mouse_callbacks_add(it, VIEW(it));
319 eina_stringshare_del(ic->item_style);
329 _elm_genlist_pan_smart_pos_set(Evas_Object *obj,
335 ELM_GENLIST_PAN_DATA_GET(obj, psd);
337 if ((x == psd->wsd->pan_x) && (y == psd->wsd->pan_y)) return;
341 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
343 if ((itb->y + itb->h) > y)
348 EINA_LIST_FOREACH(itb->items, l2, it)
350 if ((itb->y + it->y) >= y)
352 psd->wsd->anchor_item = it;
353 psd->wsd->anchor_y = -(itb->y + it->y - y);
360 if (!psd->wsd->reorder_move_animator) evas_object_smart_changed(obj);
364 _elm_genlist_pan_smart_pos_get(const Evas_Object *obj,
368 ELM_GENLIST_PAN_DATA_GET(obj, psd);
370 if (x) *x = psd->wsd->pan_x;
371 if (y) *y = psd->wsd->pan_y;
375 _elm_genlist_pan_smart_pos_max_get(const Evas_Object *obj,
381 ELM_GENLIST_PAN_DATA_GET(obj, psd);
383 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
384 ow = psd->wsd->minw - ow;
386 oh = psd->wsd->minh - oh;
391 #if GENLIST_PINCH_ZOOM_SUPPORT
392 if (psd->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
394 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
395 if (psd->wsd->pinch_zoom_h > oh)
396 *y = psd->wsd->pinch_zoom_h - oh;
403 _elm_genlist_pan_smart_pos_min_get(const Evas_Object *obj __UNUSED__,
412 _elm_genlist_pan_smart_content_size_get(const Evas_Object *obj,
416 ELM_GENLIST_PAN_DATA_GET(obj, psd);
418 if (w) *w = psd->wsd->minw;
419 if (h) *h = psd->wsd->minh;
423 _elm_genlist_pan_smart_add(Evas_Object *obj)
425 /* here just to allocate our extended data */
426 EVAS_SMART_DATA_ALLOC(obj, Elm_Genlist_Pan_Smart_Data);
428 ELM_PAN_CLASS(_elm_genlist_pan_parent_sc)->base.add(obj);
432 _elm_genlist_pan_smart_del(Evas_Object *obj)
434 ELM_GENLIST_PAN_DATA_GET(obj, psd);
438 ecore_job_del(psd->resize_job);
439 psd->resize_job = NULL;
442 _elm_genlist_pan_parent_sc->base.del(obj);
446 _elm_genlist_pan_smart_move(Evas_Object *obj,
447 Evas_Coord x __UNUSED__,
448 Evas_Coord y __UNUSED__)
450 ELM_GENLIST_PAN_DATA_GET(obj, psd);
452 psd->wsd->pan_changed = EINA_TRUE;
453 evas_object_smart_changed(obj);
454 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
455 psd->wsd->calc_job = NULL;
459 _elm_genlist_pan_smart_resize(Evas_Object *obj,
463 Evas_Coord ow = 0, oh = 0, vw = 0, vh = 0;
465 ELM_GENLIST_PAN_DATA_GET(obj, psd);
467 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
468 if ((ow == w) && (oh == h)) return;
470 if (vw != 0) psd->wsd->prev_viewport_w = vw;
472 if (psd->wsd->mode == ELM_LIST_COMPRESS)
473 psd->wsd->size_changed = EINA_TRUE;
475 psd->wsd->pan_changed = EINA_TRUE;
476 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
477 psd->wsd->calc_job = ecore_job_add(_calc_job, psd->wsd);
481 _item_scroll(Elm_Genlist_Smart_Data *sd)
484 Elm_Gen_Item *it = NULL;
485 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
487 if (!sd->show_item) return;
489 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &oh);
491 dx = it->x + it->item->block->x;
492 dy = it->y + it->item->block->y;
493 dw = it->item->block->w;
496 switch (sd->scroll_to_type)
498 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
499 if (it->item->group_item) gith = it->item->group_item->item->h;
503 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
504 dy += ((it->item->h / 2) - (oh / 2));
507 case ELM_GENLIST_ITEM_SCROLLTO_IN:
509 if ((sd->expanded_item) &&
510 ((sd->show_item->y + sd->show_item->item->block->y
511 + sd->show_item->item->h) -
512 (sd->expanded_item->y + sd->expanded_item->item->block->y) > oh))
514 it = sd->expanded_item;
515 if (it->item->group_item) gith = it->item->group_item->item->h;
516 dx = it->x + it->item->block->x;
517 dy = it->y + it->item->block->y - gith;
518 dw = it->item->block->w;
522 if ((it->item->group_item) &&
523 (sd->pan_y > (it->y + it->item->block->y)))
524 gith = it->item->group_item->item->h;
531 sd->s_iface->region_bring_in(ELM_WIDGET_DATA(sd)->obj, dx, dy, dw, dh);
533 sd->s_iface->content_region_show
534 (ELM_WIDGET_DATA(sd)->obj, dx, dy, dw, dh);
536 it->item->show_me = EINA_FALSE;
537 sd->show_item = NULL;
538 sd->auto_scroll_enabled = EINA_FALSE;
539 sd->check_scroll = EINA_FALSE;
543 _item_unrealize(Elm_Gen_Item *it,
546 Evas_Object *content;
550 if (!it->realized) return;
551 if (GL_IT(it)->wsd->reorder_it == it) return;
553 #if GENLIST_FX_SUPPORT
554 if ((GL_IT(it)->has_proxy_it) && (!GL_IT(it)->wsd->genlist_clearing))
556 if (!eina_list_data_find(GL_IT(it)->wsd->pending_unrealized_items, it))
557 GL_IT(it)->wsd->pending_unrealized_items =
558 eina_list_append(GL_IT(it)->wsd->pending_unrealized_items, it);
562 #if GENLIST_ENTRY_SUPPORT
563 if (it->item->unrealize_disabled)
565 evas_object_hide(VIEW(it));
570 //evas_event_freeze(evas_object_evas_get(WIDGET(it)));
572 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
575 ecore_timer_del(it->long_timer);
576 it->long_timer = NULL;
578 if (it->item->swipe_timer)
580 ecore_timer_del(it->item->swipe_timer);
581 it->item->swipe_timer = NULL;
585 EINA_LIST_FOREACH(it->texts, l, part)
586 edje_object_part_text_set(VIEW(it), part, NULL);
588 elm_widget_stringlist_free(it->texts);
590 elm_widget_stringlist_free(it->contents);
592 elm_widget_stringlist_free(it->states);
594 EINA_LIST_FREE(it->content_objs, content)
596 // FIXME: If parent-child relationship was broken before 'ic'
597 // is deleted, freeze_pop will not be called. ex) elm_slider
598 // If layout is used instead of edje, this problme can be
600 if (0 != elm_widget_scroll_freeze_get(content))
601 elm_widget_scroll_freeze_pop(content);
602 evas_object_del(content);
606 elm_widget_stringlist_free(it->item->flip_contents);
607 it->item->flip_contents = NULL;
608 EINA_LIST_FREE(it->item->flip_content_objs, content)
609 evas_object_del(content);
612 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
613 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
615 // unswallow VIEW(it) first then manipulate VIEW(it)
616 _decorate_item_unrealize(it);
617 _decorate_all_item_unrealize(it);
619 edje_object_signal_emit
620 (VIEW(it), "elm,state,decorate,disabled", "elm");
621 edje_object_signal_emit
622 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
623 edje_object_message_signal_process(VIEW(it));
625 it->realized = EINA_FALSE;
626 _item_cache_push(it);
628 #if GENLIST_ENTRY_SUPPORT
629 it->item->unrealize_disabled = EINA_FALSE;
631 it->want_unrealize = EINA_FALSE;
633 //evas_event_thaw(evas_object_evas_get(WIDGET(it)));
634 //evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
638 _item_block_unrealize(Item_Block *itb)
642 Eina_Bool dragging = EINA_FALSE;
644 if (!itb->realized) return;
645 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
647 EINA_LIST_FOREACH(itb->items, l, it)
649 if (itb->must_recalc || !it->group)
653 dragging = EINA_TRUE;
654 it->want_unrealize = EINA_TRUE;
657 _item_unrealize(it, EINA_FALSE);
662 itb->realized = EINA_FALSE;
663 itb->want_unrealize = EINA_TRUE;
666 itb->want_unrealize = EINA_FALSE;
667 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
668 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
672 _must_recalc_idler(void *data)
674 Elm_Genlist_Smart_Data *sd = data;
676 if (sd->calc_job) ecore_job_del(sd->calc_job);
677 sd->calc_job = ecore_job_add(_calc_job, sd);
678 sd->must_recalc_idler = NULL;
679 return ECORE_CALLBACK_CANCEL;
683 _calc_job(void *data)
686 Item_Block *itb, *chb = NULL;
687 Evas_Coord pan_w = 0, pan_h = 0;
688 Elm_Genlist_Smart_Data *sd = data;
689 Eina_Bool minw_change = EINA_FALSE;
690 Eina_Bool did_must_recalc = EINA_FALSE;
691 Evas_Coord minw = -1, minh = 0, y = 0, dy = 0, vw = 0;
693 sd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(sd)->obj, &sd->w, &sd->h);
695 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
696 EINA_INLIST_FOREACH(sd->blocks, itb)
698 Eina_Bool show_me = EINA_FALSE;
701 show_me = itb->show_me;
702 itb->show_me = EINA_FALSE;
705 if (itb->realized) _item_block_unrealize(itb);
707 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
709 if (itb->must_recalc)
714 EINA_LIST_FOREACH(itb->items, l, it)
715 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
716 itb->changed = EINA_TRUE;
717 did_must_recalc = EINA_TRUE;
718 if (itb->realized) _item_block_unrealize(itb);
719 itb->must_recalc = EINA_FALSE;
721 show_me = _item_block_recalc(itb, in, EINA_FALSE);
727 if (minw == -1) minw = itb->minw;
728 else if ((!itb->must_recalc) && (minw < itb->minw))
731 minw_change = EINA_TRUE;
733 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
736 minw_change = EINA_TRUE;
742 if ((show_me) && (sd->show_item) && (!sd->show_item->item->queued))
743 sd->check_scroll = EINA_TRUE;
747 EINA_INLIST_FOREACH(sd->blocks, itb)
753 if ((chb) && (EINA_INLIST_GET(chb)->next))
755 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
757 if (itb->realized) _item_block_unrealize(itb);
761 if (minw < sd->w) minw = sd->w;
762 if ((minw != sd->minw) || (minh != sd->minh))
766 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
767 elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
774 if ((sd->anchor_item) && (sd->anchor_item->item->block)
775 && (!sd->auto_scroll_enabled))
780 it = sd->anchor_item;
782 sd->s_iface->content_pos_set
783 (ELM_WIDGET_DATA(sd)->obj, sd->pan_x, it->item->block->y
784 + it->y + it_y, EINA_TRUE);
785 sd->anchor_item = it;
791 if (!sd->must_recalc_idler)
792 sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, sd);
794 if (sd->check_scroll)
796 _elm_genlist_pan_smart_content_size_get(sd->pan_obj, &pan_w, &pan_h);
797 if (EINA_INLIST_GET(sd->show_item) == sd->items->last)
798 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
800 switch (sd->scroll_to_type)
802 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
806 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
810 case ELM_GENLIST_ITEM_SCROLLTO_IN:
815 if ((sd->show_item) && (sd->show_item->item->block))
817 if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
818 && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
827 evas_object_smart_changed(sd->pan_obj);
828 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
829 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
833 _elm_genlist_smart_sizing_eval(Evas_Object *obj)
835 Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1, vw = 0;
837 ELM_GENLIST_DATA_GET(obj, sd);
839 /* parent class' early call */
840 if (!sd->s_iface) return;
841 if (sd->on_sub_del) return;;
843 evas_object_size_hint_min_get(obj, &minw, NULL);
844 evas_object_size_hint_max_get(obj, &maxw, &maxh);
845 edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
847 sd->s_iface->content_viewport_size_get(obj, &vw, NULL);
848 if (vw != 0) sd->prev_viewport_w = vw;
850 if (sd->mode == ELM_LIST_LIMIT)
853 minw = minw + sd->realminw;
856 evas_object_size_hint_min_set(obj, minw, minh);
857 evas_object_size_hint_max_set(obj, maxw, maxh);
861 _item_position(Elm_Gen_Item *it,
869 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
870 evas_object_resize(view, it->item->w, it->item->h);
871 evas_object_move(view, it_x, it_y);
872 evas_object_show(view);
873 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
874 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
878 _item_sub_items_clear(Elm_Gen_Item *it)
881 Elm_Object_Item *it2;
883 EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, it2)
884 elm_widget_item_del(it2);
888 _item_auto_scroll(Elm_Genlist_Smart_Data *sd)
890 Elm_Gen_Item *tmp_item = NULL;
892 #if GENLIST_FX_SUPPORT
893 if (sd->fx_first_captured) return;
895 if ((sd->expanded_item) && (sd->auto_scroll_enabled))
897 tmp_item = eina_list_data_get
898 (eina_list_last(sd->expanded_item->item->items));
899 if (!tmp_item) return;
900 sd->show_item = tmp_item;
901 sd->bring_in = EINA_TRUE;
902 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
903 if ((sd->show_item->item->queued) || (!sd->show_item->item->mincalcd))
905 sd->show_item->item->show_me = EINA_TRUE;
906 sd->auto_scroll_enabled = EINA_FALSE;
914 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
916 if (!it->item->nostacking)
918 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
920 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
921 else evas_object_lower(VIEW(it));
925 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
926 else evas_object_raise(VIEW(it));
930 if (it->item->order_num_in & 0x1)
932 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
933 if (it->deco_all_view)
934 edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
938 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
939 if (it->deco_all_view)
940 edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
945 _item_order_update(const Eina_Inlist *l,
948 Elm_Gen_Item *it, *it2;
950 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next,
951 it = ELM_GEN_ITEM_FROM_INLIST(l))
953 it->item->order_num_in = start++;
954 _elm_genlist_item_odd_even_update(it);
955 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
956 if (it2 && (it->item->order_num_in != it2->item->order_num_in))
962 _elm_genlist_item_state_update(Elm_Gen_Item *it)
966 if (it->deco_all_view)
967 edje_object_signal_emit
968 (it->deco_all_view, "elm,state,selected", "elm");
969 edje_object_signal_emit
970 (VIEW(it), "elm,state,selected", "elm");
971 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
973 if (elm_widget_item_disabled_get(it))
975 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
976 if (it->deco_all_view)
977 edje_object_signal_emit
978 (it->deco_all_view, "elm,state,disabled", "elm");
980 if (it->item->expanded)
982 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
983 if (it->deco_all_view)
984 edje_object_signal_emit
985 (it->deco_all_view, "elm,state,expanded", "elm");
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_text_realize(Elm_Gen_Item *it,
1001 Evas_Object *target,
1005 if (it->itc->func.text_get)
1011 *source = elm_widget_stringlist_get
1012 (edje_object_data_get(target, "texts"));
1013 EINA_LIST_FOREACH(*source, l, key)
1015 if (parts && fnmatch(parts, key, FNM_PERIOD))
1018 char *s = it->itc->func.text_get
1019 ((void *)it->base.data, WIDGET(it), key);
1023 edje_object_part_text_escaped_set(target, key, s);
1028 edje_object_part_text_set(target, key, "");
1035 // FIXME: difference from upstream
1037 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1039 Elm_Gen_Item *it = data;
1040 if (it) it->defer_unrealize = EINA_TRUE;
1044 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1046 Elm_Gen_Item *it = data;
1047 if (it) it->defer_unrealize = EINA_FALSE;
1052 _item_mode_content_realize(Elm_Gen_Item *it,
1053 Evas_Object *target,
1056 Eina_List **contents_list)
1058 Eina_List *res = *contents_list;
1060 if (it->itc->func.content_get)
1066 EINA_LIST_FOREACH(*source, l, key)
1068 if (parts && fnmatch(parts, key, FNM_PERIOD))
1071 ic = it->itc->func.content_get
1072 ((void *)it->base.data, WIDGET(it), key);
1076 res = eina_list_append(res, ic);
1077 edje_object_part_swallow(target, key, ic);
1078 evas_object_show(ic);
1079 #if GENLIST_ENTRY_SUPPORT
1082 // For entry or editfield
1083 // 1. Add resize callback for multiline entry.
1084 // 2. Do not unrealize it for focus issue
1085 // ps. Only for entry because of performnace
1086 if (!strcmp("elm_layout", evas_object_type_get(ic)))
1088 // If editfield style, it can have entry.
1090 edje_object_file_get(elm_layout_edje_get(ic), NULL, &group);
1091 if (group && !strncmp("elm/layout/editfield/", group, 20))
1092 it->item->unrealize_disabled = EINA_TRUE;
1094 else if (!strcmp("elm_entry", evas_object_type_get(ic)))
1095 it->item->unrealize_disabled = EINA_TRUE;
1099 // FIXME: difference from upstream
1102 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1103 // genlist does not need to handle this focus thing.
1104 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1105 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1108 if (elm_widget_item_disabled_get(it))
1109 elm_widget_disabled_set(ic, EINA_TRUE);
1118 _item_state_realize(Elm_Gen_Item *it,
1119 Evas_Object *target,
1123 if (it->itc->func.state_get)
1130 *source = elm_widget_stringlist_get
1131 (edje_object_data_get(target, "states"));
1132 EINA_LIST_FOREACH(*source, l, key)
1134 if (parts && fnmatch(parts, key, FNM_PERIOD))
1137 Eina_Bool on = it->itc->func.state_get
1138 ((void *)it->base.data, WIDGET(it), key);
1142 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1143 edje_object_signal_emit(target, buf, "elm");
1147 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1148 edje_object_signal_emit(target, buf, "elm");
1155 _decorate_item_unrealize(Elm_Gen_Item *it)
1157 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
1158 Evas_Object *content;
1160 if (!it->item->deco_it_view) return;
1162 //evas_event_freeze(evas_object_evas_get(obj));
1163 elm_widget_stringlist_free(it->item->deco_it_texts);
1164 it->item->deco_it_texts = NULL;
1165 elm_widget_stringlist_free(it->item->deco_it_contents);
1166 it->item->deco_it_contents = NULL;
1167 elm_widget_stringlist_free(it->item->deco_it_states);
1169 EINA_LIST_FREE (it->item->deco_it_content_objs, content)
1170 evas_object_del(content);
1172 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
1173 evas_object_smart_member_add(VIEW(it), sd->pan_obj);
1174 evas_object_del(it->item->deco_it_view);
1175 it->item->deco_it_view = NULL;
1177 if (sd->mode_item == it) sd->mode_item = NULL;
1178 //evas_event_thaw(evas_object_evas_get(obj));
1179 //evas_event_thaw_eval(evas_object_evas_get(obj));
1184 _decorate_all_item_position(Elm_Gen_Item *it,
1188 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
1189 evas_object_move(it->deco_all_view, itx, ity);
1193 _decorate_all_item_realize(Elm_Gen_Item *it,
1194 Eina_Bool effect_on)
1197 const char *stacking;
1198 const char *stacking_even;
1200 if ((!it) || (it->item->decorate_all_item_realized)) return;
1202 if (it->item->deco_it_view) _decorate_item_unrealize(it);
1204 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1205 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
1206 elm_config_scale_get());
1207 evas_object_smart_member_add(it->deco_all_view, GL_IT(it)->wsd->pan_obj);
1208 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
1210 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1211 strncpy(buf, "tree", sizeof(buf));
1212 else strncpy(buf, "item", sizeof(buf));
1213 if (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)
1214 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1216 strncat(buf, "/", sizeof(buf) - strlen(buf));
1217 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
1219 elm_widget_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
1220 elm_widget_style_get(WIDGET(it)));
1222 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1223 if (!stacking_even) stacking_even = "above";
1224 it->item->stacking_even = !!strcmp("above", stacking_even);
1226 stacking = edje_object_data_get(VIEW(it), "stacking");
1227 if (!stacking) stacking = "yes";
1228 it->item->nostacking = !!strcmp("yes", stacking);
1230 edje_object_mirrored_set
1231 (it->deco_all_view, elm_widget_mirrored_get(WIDGET(it)));
1233 _elm_genlist_item_odd_even_update(it);
1234 _elm_genlist_item_state_update(it);
1236 #if 1 // FIXME: difference from upstream
1237 if (GL_IT(it)->wsd->reorder_mode)
1238 edje_object_signal_emit
1239 (it->deco_all_view, "elm,state,reorder,mode_set", "elm");
1241 edje_object_signal_emit
1242 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
1246 edje_object_signal_emit
1247 (it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
1248 edje_object_signal_emit
1249 (VIEW(it), "elm,state,decorate,enabled,effect", "elm");
1253 edje_object_signal_emit
1254 (it->deco_all_view, "elm,state,decorate,enabled", "elm");
1255 edje_object_signal_emit
1256 (VIEW(it), "elm,state,decorate,enabled", "elm");
1258 _item_mouse_callbacks_del(it, VIEW(it));
1259 _item_mouse_callbacks_add(it, it->deco_all_view);
1261 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
1263 edje_object_signal_emit
1264 (it->deco_all_view, "elm,state,flip,enabled", "elm");
1265 if (!it->item->deco_all_contents)
1266 it->item->deco_all_contents = elm_widget_stringlist_get
1267 (edje_object_data_get(it->deco_all_view, "contents"));
1268 it->item->deco_all_content_objs =
1269 _item_mode_content_realize(it, it->deco_all_view,
1270 &it->item->deco_all_contents, NULL,
1271 &it->item->deco_all_content_objs);
1273 (it, it->deco_all_view, &it->item->deco_all_states, NULL);
1274 edje_object_part_swallow
1275 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1277 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
1278 evas_object_show(it->deco_all_view);
1282 edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
1283 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
1286 it->item->decorate_all_item_realized = EINA_TRUE;
1287 it->want_unrealize = EINA_FALSE;
1291 _expand_toggle_signal_cb(void *data,
1292 Evas_Object *obj __UNUSED__,
1293 const char *emission __UNUSED__,
1294 const char *source __UNUSED__)
1296 Elm_Gen_Item *it = data;
1298 if (it->item->expanded)
1299 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1301 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1305 _expand_signal_cb(void *data,
1306 Evas_Object *obj __UNUSED__,
1307 const char *emission __UNUSED__,
1308 const char *source __UNUSED__)
1310 Elm_Gen_Item *it = data;
1312 if (!it->item->expanded)
1313 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1317 _contract_signal_cb(void *data,
1318 Evas_Object *obj __UNUSED__,
1319 const char *emission __UNUSED__,
1320 const char *source __UNUSED__)
1322 Elm_Gen_Item *it = data;
1324 if (it->item->expanded)
1325 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1328 #if GENLIST_ENTRY_SUPPORT
1330 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1332 Elm_Gen_Item *it = data;
1334 if (it->want_unrealize) return;
1335 GL_IT(it)->wsd->size_changed = EINA_TRUE;
1336 evas_object_smart_changed(GL_IT(it)->wsd->pan_obj);
1341 _item_content_realize(Elm_Gen_Item *it,
1342 Evas_Object *target,
1346 Eina_List *res = it->content_objs;
1348 if (it->itc->func.content_get)
1352 Evas_Object *ic = NULL;
1355 *source = elm_widget_stringlist_get
1356 (edje_object_data_get(target, "contents"));
1358 EINA_LIST_FOREACH(*source, l, key)
1360 if (parts && fnmatch(parts, key, FNM_PERIOD))
1363 if (it->itc->func.content_get)
1364 ic = it->itc->func.content_get
1365 ((void *)it->base.data, WIDGET(it), key);
1368 res = eina_list_append(res, ic);
1369 edje_object_part_swallow(target, key, ic);
1370 evas_object_show(ic);
1372 #if GENLIST_ENTRY_SUPPORT
1373 // For entry or editfield
1374 // 1. Add resize callback for multiline entry.
1375 // 2. Do not unrealize it for focus issue
1376 // ps. Only for entry because of performnace
1377 if (!strcmp("elm_layout", evas_object_type_get(ic)))
1379 // If editfield style, it can have entry.
1381 edje_object_file_get(elm_layout_edje_get(ic), NULL, &group);
1382 if (group && !strncmp("elm/layout/editfield/", group, 20))
1384 evas_object_event_callback_add
1385 (ic, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1386 _changed_size_hints, it);
1387 it->item->unrealize_disabled = EINA_TRUE;
1391 else if (!strcmp("elm_entry", evas_object_type_get(ic)))
1393 evas_object_event_callback_add
1394 (ic, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1395 _changed_size_hints, it);
1396 it->item->unrealize_disabled = EINA_TRUE;
1399 #if 0 // FIXME: difference from upstream
1402 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1403 // genlist does not need to handle this focus thing.
1404 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1405 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1408 if (elm_widget_item_disabled_get(it))
1409 elm_widget_disabled_set(ic, EINA_TRUE);
1418 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
1423 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1424 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1426 buf = eina_strbuf_new();
1428 if (it->itc->func.text_get)
1433 if (!(it->texts)) it->texts =
1434 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1436 EINA_LIST_FOREACH(it->texts, l, key)
1438 char *s = it->itc->func.text_get
1439 ((void *)it->base.data, WIDGET(it), key);
1441 s = _elm_util_mkup_to_text(s);
1445 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1446 eina_strbuf_append(buf, s);
1452 ret = eina_strbuf_string_steal(buf);
1453 eina_strbuf_free(buf);
1458 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
1460 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1461 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1463 if (it->base.disabled)
1464 return strdup(E_("State: Disabled"));
1470 _access_on_highlight_cb(void *data)
1472 Evas_Coord x, y, w, h;
1473 Evas_Coord sx, sy, sw, sh;
1474 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1475 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1477 ELM_GENLIST_DATA_GET(it->base.widget, sd);
1479 evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
1480 // XXX There would be a reason.
1481 if ((w == 0) && (h == 0)) return;
1483 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
1484 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
1485 elm_genlist_item_bring_in((Elm_Object_Item *)it,
1486 ELM_GENLIST_ITEM_SCROLLTO_IN);
1490 _access_widget_item_register(Elm_Gen_Item *it)
1492 Elm_Access_Info *ai;
1494 _elm_access_widget_item_register((Elm_Widget_Item *)it);
1496 ai = _elm_access_object_get(it->base.access_obj);
1498 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1499 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1500 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
1501 _elm_access_activate_callback_set(ai, _access_activate_cb, it);
1505 _item_realize(Elm_Gen_Item *it,
1509 const char *treesize;
1515 if (it->item->order_num_in != in)
1517 _item_order_update(EINA_INLIST_GET(it), in);
1518 _elm_genlist_item_state_update(it);
1519 _elm_genlist_item_index_update(it);
1523 it->item->order_num_in = in;
1525 if (it->item->nocache_once | it->item->nocache ||
1526 it->item->type == ELM_GENLIST_ITEM_TREE || it->parent ||
1527 !_item_cache_pop(it))
1529 const char *stacking_even;
1530 const char *stacking;
1532 it->item->nocache_once = EINA_FALSE;
1534 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1535 edje_object_scale_set(VIEW(it),
1536 elm_widget_scale_get(WIDGET(it)) *
1537 elm_config_scale_get());
1538 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
1539 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1541 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1542 snprintf(buf, sizeof(buf), "tree%s/%s",
1543 GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS ? "_compress" :
1544 "", it->itc->item_style ? : "default");
1546 snprintf(buf, sizeof(buf), "item%s/%s",
1547 GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS ? "_compress" :
1548 "", it->itc->item_style ? : "default");
1550 elm_widget_theme_object_set
1551 (WIDGET(it), VIEW(it), "genlist", buf,
1552 elm_widget_style_get(WIDGET(it)));
1554 #if 1 // FIXME: difference from upstream
1555 if (it->item->expanded_depth > 0)
1556 edje_object_signal_emit(VIEW(it), "bg_color_change", "elm");
1559 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1560 if (!stacking_even) stacking_even = "above";
1561 it->item->stacking_even = !!strcmp("above", stacking_even);
1563 stacking = edje_object_data_get(VIEW(it), "stacking");
1564 if (!stacking) stacking = "yes";
1565 it->item->nostacking = !!strcmp("yes", stacking);
1567 edje_object_mirrored_set
1568 (VIEW(it), elm_widget_mirrored_get(WIDGET(it)));
1570 edje_object_signal_callback_add
1571 (VIEW(it), "elm,action,expand,toggle", "elm",
1572 _expand_toggle_signal_cb, it);
1573 edje_object_signal_callback_add
1574 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1575 edje_object_signal_callback_add
1576 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1577 _item_mouse_callbacks_add(it, VIEW(it));
1581 if (_elm_config->access_mode) _access_widget_item_register(it);
1583 _item_order_update(EINA_INLIST_GET(it), in);
1584 #if 1 // FIXME: difference from upstream
1585 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
1587 if (GL_IT(it)->wsd->reorder_mode)
1588 edje_object_signal_emit
1589 (VIEW(it), "elm,state,reorder,mode_set", "elm");
1591 edje_object_signal_emit
1592 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
1595 treesize = edje_object_data_get(VIEW(it), "treesize");
1596 if (treesize) tsize = atoi(treesize);
1597 if (it->parent && GL_IT(it->parent)->type == ELM_GENLIST_ITEM_TREE &&
1598 !it->spacer && treesize)
1601 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1602 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1606 evas_object_size_hint_min_set
1607 (it->spacer, (it->item->expanded_depth * tsize) *
1608 elm_config_scale_get(), 1);
1609 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1613 if ((GL_IT(it)->wsd->decorate_all_mode) && (!it->deco_all_view) &&
1614 (it->item->type != ELM_GENLIST_ITEM_GROUP) &&
1615 (it->itc->decorate_all_item_style))
1616 _decorate_all_item_realize(it, EINA_FALSE);
1618 _elm_genlist_item_state_update(it);
1619 _elm_genlist_item_index_update(it);
1622 /* homogenous genlist shortcut */
1623 if ((calc) && (GL_IT(it)->wsd->homogeneous) && (!it->item->mincalcd) &&
1624 ((it->group && GL_IT(it)->wsd->group_item_width) ||
1625 (!it->group && GL_IT(it)->wsd->item_width)))
1629 it->item->w = it->item->minw = GL_IT(it)->wsd->group_item_width;
1630 it->item->h = it->item->minh = GL_IT(it)->wsd->group_item_height;
1634 it->item->w = it->item->minw = GL_IT(it)->wsd->item_width;
1635 it->item->h = it->item->minh = GL_IT(it)->wsd->item_height;
1637 it->item->mincalcd = EINA_TRUE;
1641 if (eina_list_count(it->content_objs) != 0)
1642 ERR_ABORT("If you see this error, please notify us and we"
1645 _item_text_realize(it, VIEW(it), &it->texts, NULL);
1647 _item_content_realize(it, VIEW(it), &it->contents, NULL);
1648 _item_state_realize(it, VIEW(it), &it->states, NULL);
1651 edje_object_signal_emit
1652 (VIEW(it), "elm,state,flip,enabled", "elm");
1653 // This is needed before contents are swallowed
1654 edje_object_message_signal_process(VIEW(it));
1656 if (!(it->item->flip_contents))
1657 it->item->flip_contents = elm_widget_stringlist_get
1658 (edje_object_data_get(VIEW(it), "flips"));
1659 it->item->flip_content_objs = _item_mode_content_realize
1660 (it, VIEW(it), &it->item->flip_contents, NULL,
1661 &it->item->flip_content_objs);
1664 /* access: unregister item which have no text and content */
1665 if (_elm_config->access_mode && !it->texts && !it->contents)
1666 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1669 // FIXME: difference from upstream
1670 if (!it->item->mincalcd || ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
1672 if (!it->item->mincalcd)
1675 Evas_Coord mw = 0, mh = 0;
1677 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1678 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1679 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
1680 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
1681 (mw < GL_IT(it)->wsd->prev_viewport_w))
1682 mw = GL_IT(it)->wsd->prev_viewport_w;
1683 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
1684 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
1685 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
1686 (mw > GL_IT(it)->wsd->prev_viewport_w))
1687 mw = GL_IT(it)->wsd->prev_viewport_w;
1690 it->item->w = it->item->minw = mw;
1691 it->item->h = it->item->minh = mh;
1692 it->item->mincalcd = EINA_TRUE;
1694 if ((!GL_IT(it)->wsd->group_item_width) && (it->group))
1696 GL_IT(it)->wsd->group_item_width = mw;
1697 GL_IT(it)->wsd->group_item_height = mh;
1699 else if ((!GL_IT(it)->wsd->item_width) &&
1700 (it->item->type == ELM_GENLIST_ITEM_NONE))
1702 GL_IT(it)->wsd->item_width = mw;
1703 GL_IT(it)->wsd->item_height = mh;
1706 if (!calc) evas_object_show(VIEW(it));
1709 if (it->tooltip.content_cb)
1711 elm_widget_item_tooltip_content_cb_set
1712 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
1713 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1714 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1717 if (it->mouse_cursor)
1718 elm_widget_item_cursor_set(it, it->mouse_cursor);
1720 it->realized = EINA_TRUE;
1721 it->want_unrealize = EINA_FALSE;
1723 if (!calc || it->item->unrealize_disabled)
1724 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1726 if ((!calc) && (GL_IT(it)->wsd->decorate_all_mode) &&
1727 (it->item->type != ELM_GENLIST_ITEM_GROUP))
1729 if (it->itc->decorate_all_item_style)
1731 if (!it->deco_all_view)
1732 _decorate_all_item_realize(it, EINA_FALSE);
1733 edje_object_message_signal_process(it->deco_all_view);
1736 if ((!calc) && (it->decorate_it_set) &&
1737 (it->item->type != ELM_GENLIST_ITEM_GROUP))
1739 if (it->itc->decorate_item_style)
1741 if (!it->item->deco_it_view)
1742 _decorate_item_set(it);
1743 edje_object_message_signal_process(it->item->deco_it_view);
1746 edje_object_message_signal_process(VIEW(it));
1749 #if GENLIST_PINCH_ZOOM_SUPPORT
1751 _pinch_items_recalc(void *data)
1753 Elm_Genlist_Smart_Data *sd = data;
1758 Evas_Coord tot_y = 0, ox, oy;
1759 evas_object_geometry_get(sd->pan_obj, &ox, &oy, NULL, NULL);
1761 EINA_INLIST_FOREACH(sd->blocks, itb)
1763 EINA_LIST_FOREACH(itb->items, l, it)
1766 if (IS_ROOT_PARENT_IT(it))
1768 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
1770 if (!it->realized) _item_realize(it, 0, EINA_FALSE);
1771 it->item->scrl_y = oy + tot_y - sd->pan_y;
1772 evas_object_resize(VIEW(it), sd->minw, it->item->h);
1773 evas_object_move(VIEW(it), it->item->scrl_x, it->item->scrl_y);
1774 evas_object_show(VIEW(it));
1775 evas_object_raise(VIEW(it));
1776 tot_y += it->item->h;
1777 sd->pinch_zoom_h = tot_y;
1780 else if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND)
1782 evas_object_resize(VIEW(it), sd->minw, it->item->h);
1783 it->item->scrl_y = oy + it->item->pan_scrl_y - sd->pan_y;
1784 evas_object_move(VIEW(it), it->item->scrl_x, it->item->scrl_y);
1793 #if GROUP_ITEMS_FEATURE
1795 _group_items_recalc(void *data)
1799 Elm_Genlist_Smart_Data *sd = data;
1801 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1802 EINA_LIST_FOREACH(sd->group_items, l, git)
1804 if (git->item->want_realize)
1806 if (!git->realized) _item_realize(git, 0, EINA_FALSE);
1807 evas_object_resize(VIEW(git), sd->minw, git->item->h);
1808 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
1809 evas_object_show(VIEW(git));
1810 evas_object_raise(VIEW(git));
1812 else if (!git->item->want_realize)
1815 _item_unrealize(git, EINA_FALSE);
1818 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1819 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1824 _reorder_move_animator_cb(void *data)
1827 Elm_Gen_Item *it = data;
1828 Eina_Bool down = EINA_FALSE;
1831 dy = 6 * elm_config_scale_get();
1832 t = ((0.0 > (t = ecore_loop_time_get()
1833 - GL_IT(it)->wsd->start_time)) ? 0.0 : t);
1835 if (t <= REORDER_EFFECT_TIME)
1836 y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
1839 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
1840 if (diff < dy) y = diff;
1842 if (it->item->old_scrl_y < it->item->scrl_y)
1844 it->item->old_scrl_y += y;
1847 else if (it->item->old_scrl_y > it->item->scrl_y)
1849 it->item->old_scrl_y -= y;
1853 if (it->deco_all_view)
1855 (it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
1856 else if (it->item->deco_it_view)
1858 (it, it->item->deco_it_view, it->item->scrl_x, it->item->old_scrl_y);
1860 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
1862 if ((GL_IT(it)->wsd->reorder_pan_move) ||
1863 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
1864 (!down && it->item->old_scrl_y <= it->item->scrl_y))
1866 it->item->old_scrl_y = it->item->scrl_y;
1867 it->item->move_effect_enabled = EINA_FALSE;
1868 GL_IT(it)->wsd->reorder_move_animator = NULL;
1869 return ECORE_CALLBACK_CANCEL;
1872 return ECORE_CALLBACK_RENEW;
1876 _reorder_item_space_get(Elm_Gen_Item *it)
1878 Elm_Gen_Item *reorder_it = GL_IT(it)->wsd->reorder_it;
1879 Evas_Coord rox, roy, row, roh, oy, oh;
1880 Eina_Bool top = EINA_FALSE;
1882 if (!reorder_it) return 0;
1883 if(it->deco_all_view) evas_object_lower(it->deco_all_view);
1885 evas_object_geometry_get(GL_IT(it)->wsd->pan_obj, NULL, &oy, NULL, &oh);
1886 evas_object_geometry_get
1887 (GL_IT(it)->wsd->VIEW(reorder_it), &rox, &roy, &row, &roh);
1889 if ((GL_IT(it)->wsd->reorder_start_y < it->item->block->y) &&
1890 (roy - oy + (roh / 2) >= it->item->block->y - GL_IT(it)->wsd->pan_y))
1892 it->item->block->reorder_offset =
1893 GL_IT(it)->wsd->reorder_it->item->h * -1;
1894 if (it->item->block->count == 1)
1895 GL_IT(it)->wsd->reorder_rel = it;
1897 else if ((GL_IT(it)->wsd->reorder_start_y >= it->item->block->y) &&
1898 (roy - oy + (roh / 2) <= it->item->block->y -
1899 GL_IT(it)->wsd->pan_y))
1901 it->item->block->reorder_offset = GL_IT(it)->wsd->reorder_it->item->h;
1904 it->item->block->reorder_offset = 0;
1906 it->item->scrl_y += it->item->block->reorder_offset;
1908 top = (ELM_RECTS_INTERSECT
1909 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
1910 rox, roy + (roh / 2), row, 1));
1913 GL_IT(it)->wsd->reorder_rel = it;
1914 it->item->scrl_y += GL_IT(it)->wsd->reorder_it->item->h;
1915 return GL_IT(it)->wsd->reorder_it->item->h;
1922 _item_block_position(Item_Block *itb,
1928 Eina_Bool vis = EINA_FALSE;
1929 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
1931 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
1932 evas_object_geometry_get(itb->sd->pan_obj, &ox, &oy, &ow, &oh);
1933 evas_output_viewport_get
1934 (evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj),
1935 &cvx, &cvy, &cvw, &cvh);
1937 EINA_LIST_FOREACH(itb->items, l, it)
1939 if ((GL_IT(it)->wsd->reorder_it == it) && it->highlighted) continue;
1943 it->item->w = itb->w;
1944 it->item->scrl_x = itb->x + it->x - GL_IT(it)->wsd->pan_x + ox;
1945 it->item->scrl_y = itb->y + it->y - GL_IT(it)->wsd->pan_y + oy;
1947 vis = (ELM_RECTS_INTERSECT
1948 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
1949 cvx, cvy, cvw, cvh));
1952 if ((itb->realized) && (!it->realized))
1954 if (vis) _item_realize(it, in, EINA_FALSE);
1958 if (vis || it->dragging)
1960 #if GENLIST_ENTRY_SUPPORT
1961 evas_object_show(VIEW(it));
1963 if (GL_IT(it)->wsd->reorder_mode &&
1964 GL_IT(it)->wsd->reorder_it &&
1965 GL_IT(it)->wsd->reorder_it->highlighted)
1966 y += _reorder_item_space_get(it);
1967 git = it->item->group_item;
1970 if (git->item->scrl_y < oy)
1971 git->item->scrl_y = oy;
1972 if ((git->item->scrl_y + git->item->h) >
1973 (it->item->scrl_y + it->item->h))
1974 git->item->scrl_y = (it->item->scrl_y +
1975 it->item->h) - git->item->h;
1976 git->item->scrl_x = it->item->scrl_x;
1977 git->item->want_realize = EINA_TRUE;
1979 if ((GL_IT(it)->wsd->reorder_it) &&
1980 GL_IT(it)->wsd->reorder_it->highlighted &&
1981 (it->item->old_scrl_y != it->item->scrl_y))
1983 if (!it->item->move_effect_enabled)
1985 it->item->move_effect_enabled = EINA_TRUE;
1986 GL_IT(it)->wsd->reorder_move_animator =
1988 _reorder_move_animator_cb, it);
1991 if (!it->item->move_effect_enabled)
1993 if ((GL_IT(it)->wsd->decorate_all_mode) &&
1994 (it->itc->decorate_all_item_style))
1995 _decorate_all_item_position
1996 (it, it->item->scrl_x, it->item->scrl_y);
1999 if (it->item->deco_it_view)
2001 (it, it->item->deco_it_view,
2006 (it, VIEW(it), it->item->scrl_x,
2009 it->item->old_scrl_y = it->item->scrl_y;
2010 #if GENLIST_PINCH_ZOOM_SUPPORT
2011 if (((GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
2012 && (!IS_ROOT_PARENT_IT(it))) || (GL_IT(it)->wsd->sorting))
2014 if (it->deco_all_view) evas_object_hide(it->deco_all_view);
2015 else evas_object_hide(VIEW(it));
2023 if ((GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
2024 && (!IS_ROOT_PARENT_IT(it)))
2026 if (it->deco_all_view) evas_object_hide(it->deco_all_view);
2027 else evas_object_hide(VIEW(it));
2030 _item_unrealize(it, EINA_FALSE);
2037 if (vis) it->item->want_realize = EINA_TRUE;
2041 // FIXME: diffrence from upstream
2042 minh += it->item->minh;
2046 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
2047 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
2051 _item_block_realize(Item_Block *itb)
2053 if (itb->realized) return;
2055 itb->realized = EINA_TRUE;
2056 itb->want_unrealize = EINA_FALSE;
2060 _changed_job(Elm_Genlist_Smart_Data *sd)
2066 Eina_Bool anything_changed = EINA_FALSE;
2067 Eina_Bool width_changed = EINA_FALSE;
2068 Eina_Bool height_changed = EINA_FALSE;
2070 EINA_INLIST_FOREACH(sd->blocks, itb)
2075 width_changed = height_changed = EINA_FALSE;
2076 EINA_LIST_FOREACH(itb->items, l2, it)
2080 Evas_Coord mw = 0, mh = 0;
2082 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2083 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2084 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
2085 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
2086 (mw < GL_IT(it)->wsd->prev_viewport_w))
2087 mw = GL_IT(it)->wsd->prev_viewport_w;
2088 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
2089 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
2090 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
2091 (mw > GL_IT(it)->wsd->prev_viewport_w))
2092 mw = GL_IT(it)->wsd->prev_viewport_w;
2094 if (it->item->minw != mw)
2096 it->item->w = it->item->minw = mw;
2097 width_changed = EINA_TRUE;
2099 if (it->item->minh != mh)
2101 it->item->h = it->item->minh = mh;
2102 height_changed = EINA_TRUE;
2109 if ((!sd->group_item_width) && (it->group))
2111 sd->group_item_width = mw;
2112 sd->group_item_height = mh;
2114 else if ((!sd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2116 sd->item_width = mw;
2117 sd->item_height = mh;
2124 anything_changed = EINA_TRUE;
2125 itb->changed = EINA_TRUE;
2126 _item_block_recalc(itb, num0, 0);
2127 _item_block_position(itb, num0);
2129 else if (width_changed)
2131 _item_block_position(itb, num0);
2134 if (anything_changed)
2136 if (sd->calc_job) ecore_job_del(sd->calc_job);
2137 sd->calc_job = ecore_job_add(_calc_job, sd);
2142 _elm_genlist_pan_smart_calculate(Evas_Object *obj)
2144 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2145 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
2151 ELM_GENLIST_PAN_DATA_GET(obj, psd);
2153 //evas_event_freeze(evas_object_evas_get(obj));
2155 #if GENLIST_FX_SUPPORT
2156 if (psd->wsd->fx_playing) return;
2158 if (psd->wsd->pan_changed)
2160 _calc_job(psd->wsd);
2161 psd->wsd->pan_changed = EINA_FALSE;
2164 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2165 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2166 EINA_LIST_FOREACH(psd->wsd->group_items, l, git)
2168 #if GROUP_ITEMS_FEATURE
2169 git->item->want_realize = EINA_FALSE;
2171 _item_unrealize(git, EINA_TRUE);
2175 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
2177 itb->w = psd->wsd->minw;
2178 if (ELM_RECTS_INTERSECT(itb->x - psd->wsd->pan_x + ox,
2179 itb->y - psd->wsd->pan_y + oy,
2181 cvx, cvy, cvw, cvh))
2183 if ((!itb->realized) || (itb->changed))
2185 _item_block_realize(itb);
2187 // FIXME: difference from opensource
2188 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2189 sd->wd->calc_job = NULL;
2193 _item_block_position(itb, in);
2197 if (itb->realized) _item_block_unrealize(itb);
2201 #if GENLIST_PINCH_ZOOM_SUPPORT
2202 if (psd->wsd->pinch_zoom_mode) _pinch_items_recalc(psd->wsd);
2205 #if GROUP_ITEMS_FEATURE
2206 if ((!psd->wsd->reorder_it) || (psd->wsd->reorder_pan_move))
2207 _group_items_recalc(psd->wsd);
2209 if ((psd->wsd->reorder_mode) && (psd->wsd->reorder_it))
2211 if (psd->wsd->pan_y != psd->wsd->reorder_old_pan_y)
2212 psd->wsd->reorder_pan_move = EINA_TRUE;
2213 else psd->wsd->reorder_pan_move = EINA_FALSE;
2215 evas_object_raise(psd->wsd->VIEW(reorder_it));
2216 psd->wsd->reorder_old_pan_y = psd->wsd->pan_y;
2217 psd->wsd->start_time = ecore_loop_time_get();
2219 _item_auto_scroll(psd->wsd);
2221 psd->wsd->s_iface->content_pos_get(ELM_WIDGET_DATA(psd->wsd)->obj, &vx, &vy);
2222 psd->wsd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(psd->wsd)->obj,
2225 if (psd->wsd->reorder_fast == 1)
2226 psd->wsd->s_iface->content_region_show(ELM_WIDGET_DATA(psd->wsd)->obj,
2227 vx,vy - 10, vw, vh);
2228 else if (psd->wsd->reorder_fast == -1)
2229 psd->wsd->s_iface->content_region_show(ELM_WIDGET_DATA(psd->wsd)->obj,
2230 vx, vy + 10, vw, vh);
2232 if (psd->wsd->size_changed)
2234 _changed_job(psd->wsd);
2235 psd->wsd->size_changed = EINA_FALSE;
2238 #if GENLIST_FX_SUPPORT
2239 psd->wsd->rendered = EINA_TRUE;
2240 if ((psd->wsd->fx_mode) && (!psd->wsd->queue))
2242 if (_elm_genlist_fx_capture(ELM_WIDGET_DATA(psd->wsd)->obj, 1))
2243 _elm_genlist_fx_play(ELM_WIDGET_DATA(psd->wsd)->obj);
2246 #if GENLIST_PINCH_ZOOM_SUPPORT
2247 if (psd->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND)
2248 psd->wsd->pinch_zoom_mode = ELM_GEN_PINCH_ZOOM_NONE;
2250 //evas_event_thaw(evas_object_evas_get(obj));
2251 //evas_event_thaw_eval(evas_object_evas_get(obj));
2255 _elm_genlist_pan_smart_set_user(Elm_Genlist_Pan_Smart_Class *sc)
2257 ELM_PAN_CLASS(sc)->base.add = _elm_genlist_pan_smart_add;
2258 ELM_PAN_CLASS(sc)->base.del = _elm_genlist_pan_smart_del;
2259 ELM_PAN_CLASS(sc)->base.move = _elm_genlist_pan_smart_move;
2260 ELM_PAN_CLASS(sc)->base.resize = _elm_genlist_pan_smart_resize;
2261 ELM_PAN_CLASS(sc)->base.calculate = _elm_genlist_pan_smart_calculate;
2263 ELM_PAN_CLASS(sc)->pos_set = _elm_genlist_pan_smart_pos_set;
2264 ELM_PAN_CLASS(sc)->pos_get = _elm_genlist_pan_smart_pos_get;
2265 ELM_PAN_CLASS(sc)->pos_max_get = _elm_genlist_pan_smart_pos_max_get;
2266 ELM_PAN_CLASS(sc)->pos_min_get = _elm_genlist_pan_smart_pos_min_get;
2267 ELM_PAN_CLASS(sc)->content_size_get =
2268 _elm_genlist_pan_smart_content_size_get;
2272 _item_multi_select_up(Elm_Genlist_Smart_Data *sd)
2274 Elm_Object_Item *prev;
2276 if (!sd->selected) return EINA_FALSE;
2277 if (!sd->multi) return EINA_FALSE;
2279 prev = elm_genlist_item_prev_get(sd->last_selected_item);
2280 if (!prev) return EINA_TRUE;
2282 if (elm_genlist_item_selected_get(prev))
2284 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2285 sd->last_selected_item = prev;
2286 elm_genlist_item_show
2287 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2291 elm_genlist_item_selected_set(prev, EINA_TRUE);
2292 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2298 _item_multi_select_down(Elm_Genlist_Smart_Data *sd)
2300 Elm_Object_Item *next;
2302 if (!sd->selected) return EINA_FALSE;
2303 if (!sd->multi) return EINA_FALSE;
2305 next = elm_genlist_item_next_get(sd->last_selected_item);
2306 if (!next) return EINA_TRUE;
2308 if (elm_genlist_item_selected_get(next))
2310 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2311 sd->last_selected_item = next;
2312 elm_genlist_item_show
2313 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2317 elm_genlist_item_selected_set(next, EINA_TRUE);
2318 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2325 _all_items_deselect(Elm_Genlist_Smart_Data *sd)
2327 if (!sd->selected) return EINA_FALSE;
2329 while (sd->selected)
2330 elm_genlist_item_selected_set(sd->selected->data, EINA_FALSE);
2336 _item_single_select_up(Elm_Genlist_Smart_Data *sd)
2342 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2344 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2347 prev = (Elm_Gen_Item *)elm_genlist_item_prev_get
2348 (sd->last_selected_item);
2350 if (!prev) return EINA_FALSE;
2352 _all_items_deselect(sd);
2354 elm_genlist_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
2355 elm_genlist_item_show((Elm_Object_Item *)prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2360 _item_single_select_down(Elm_Genlist_Smart_Data *sd)
2366 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2368 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2371 next = (Elm_Gen_Item *)elm_genlist_item_next_get
2372 (sd->last_selected_item);
2374 if (!next) return EINA_FALSE;
2376 _all_items_deselect(sd);
2378 elm_genlist_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
2379 elm_genlist_item_show
2380 ((Elm_Object_Item *)next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2386 _elm_genlist_smart_event(Evas_Object *obj,
2387 Evas_Object *src __UNUSED__,
2388 Evas_Callback_Type type,
2395 Evas_Coord step_x = 0;
2396 Evas_Coord step_y = 0;
2397 Evas_Coord page_x = 0;
2398 Evas_Coord page_y = 0;
2399 Elm_Object_Item *it;
2400 Evas_Event_Key_Down *ev = event_info;
2401 Evas_Coord pan_max_x = 0, pan_max_y = 0;
2403 ELM_GENLIST_DATA_GET(obj, sd);
2405 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2406 if (!sd->items) return EINA_FALSE;
2407 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
2408 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
2410 sd->s_iface->content_pos_get(obj, &x, &y);
2411 sd->s_iface->step_size_get(obj, &step_x, &step_y);
2412 sd->s_iface->page_size_get(obj, &page_x, &page_y);
2413 sd->s_iface->content_viewport_size_get(obj, &v_w, &v_h);
2415 if ((!strcmp(ev->keyname, "Left")) ||
2416 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
2420 else if ((!strcmp(ev->keyname, "Right")) ||
2421 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
2425 else if ((!strcmp(ev->keyname, "Up")) ||
2426 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
2428 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
2429 (_item_multi_select_up(sd)))
2430 || (_item_single_select_up(sd)))
2432 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2438 else if ((!strcmp(ev->keyname, "Down")) ||
2439 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
2441 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
2442 (_item_multi_select_down(sd)))
2443 || (_item_single_select_down(sd)))
2445 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2451 else if ((!strcmp(ev->keyname, "Home")) ||
2452 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
2454 it = elm_genlist_first_item_get(obj);
2455 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
2456 elm_genlist_item_selected_set(it, EINA_TRUE);
2457 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2460 else if ((!strcmp(ev->keyname, "End")) ||
2461 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
2463 it = elm_genlist_last_item_get(obj);
2464 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
2465 elm_genlist_item_selected_set(it, EINA_TRUE);
2466 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2469 else if ((!strcmp(ev->keyname, "Prior")) ||
2470 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
2473 y -= -(page_y * v_h) / 100;
2477 else if ((!strcmp(ev->keyname, "Next")) ||
2478 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
2481 y += -(page_y * v_h) / 100;
2485 else if (!strcmp(ev->keyname, "Escape"))
2487 if (!_all_items_deselect(sd)) return EINA_FALSE;
2488 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2491 else if (((!strcmp(ev->keyname, "Return")) ||
2492 (!strcmp(ev->keyname, "KP_Enter")) ||
2493 (!strcmp(ev->keyname, "space")))
2494 && (!sd->multi) && (sd->selected))
2496 it = elm_genlist_selected_item_get(obj);
2497 elm_genlist_item_expanded_set(it, !elm_genlist_item_expanded_get(it));
2498 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
2500 else return EINA_FALSE;
2502 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2503 _elm_genlist_pan_smart_pos_max_get(sd->pan_obj, &pan_max_x, &pan_max_y);
2505 if (x > pan_max_x) x = pan_max_x;
2507 if (y > pan_max_y) y = pan_max_y;
2509 sd->s_iface->content_pos_set(obj, x, y, EINA_TRUE);
2515 _elm_genlist_smart_sub_object_add(Evas_Object *obj,
2518 Elm_Widget_Smart_Class *parent_parent;
2520 parent_parent = (Elm_Widget_Smart_Class *)((Evas_Smart_Class *)
2521 _elm_genlist_parent_sc)->parent;
2523 /* skipping layout's code, which registers size hint changing
2524 * callback on sub objects. this is here because items'
2525 * content_get() routines may change hints on the objects after
2526 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
2527 * not needed at here anyway, so let's skip listening to those
2529 if (!parent_parent->sub_object_add(obj, sobj))
2536 _elm_genlist_smart_sub_object_del(Evas_Object *obj,
2539 ELM_GENLIST_DATA_GET(obj, sd);
2541 /* XXX: hack -- also skipping sizing recalculation on
2542 * sub-object-del. genlist's crazy code paths (like groups and
2543 * such) seem to issue a whole lot of deletions and Evas bitches
2544 * about too many recalculations */
2545 sd->on_sub_del = EINA_TRUE;
2547 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->sub_object_del(obj, sobj))
2550 sd->on_sub_del = EINA_FALSE;
2556 _elm_genlist_smart_on_focus(Evas_Object *obj)
2558 ELM_GENLIST_DATA_GET(obj, sd);
2560 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->on_focus(obj))
2563 if (elm_widget_focus_get(obj) && (sd->items) && (sd->selected) &&
2564 (!sd->last_selected_item))
2565 sd->last_selected_item = eina_list_data_get(sd->selected);
2571 _elm_genlist_smart_focus_next(const Evas_Object *obj,
2572 Elm_Focus_Direction dir,
2575 Evas_Coord x, y, w, h;
2576 Evas_Coord sx, sy, sw, sh;
2578 Eina_List *items = NULL;
2579 Eina_Bool done = EINA_FALSE;
2581 ELM_GENLIST_CHECK(obj) EINA_FALSE;
2582 ELM_GENLIST_DATA_GET(obj, sd);
2584 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
2586 EINA_INLIST_FOREACH(sd->blocks, itb)
2594 EINA_LIST_FOREACH(itb->items, l, it)
2598 evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
2600 /* check item which displays more than half of its size */
2601 if (ELM_RECTS_INTERSECT
2602 (x + (w / 2), y + (h / 2), 0, 0, sx, sy, sw, sh))
2603 items = eina_list_append(items, it->base.access_obj);
2605 if (!it->base.access_order) continue;
2609 EINA_LIST_FOREACH(it->base.access_order, subl, subo)
2610 items = eina_list_append(items, subo);
2614 else if (done) break;
2617 return elm_widget_focus_list_next_get
2618 (obj, items, eina_list_data_get, dir, next);
2622 _mirrored_set(Evas_Object *obj,
2625 ELM_GENLIST_DATA_GET(obj, sd);
2627 sd->s_iface->mirrored_set(obj, rtl);
2631 _elm_genlist_smart_theme(Evas_Object *obj)
2635 ELM_GENLIST_DATA_GET(obj, sd);
2637 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->theme(obj))
2640 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2641 _item_cache_all_free(sd);
2642 _mirrored_set(obj, elm_widget_mirrored_get(obj));
2645 // FIXME: difference from opensource
2646 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
2649 sd->item_width = sd->item_height = 0;
2650 sd->group_item_width = sd->group_item_height = 0;
2651 sd->minw = sd->minh = sd->realminw = 0;
2652 EINA_INLIST_FOREACH(sd->blocks, itb)
2657 if (itb->realized) _item_block_unrealize(itb);
2658 EINA_LIST_FOREACH(itb->items, l, it)
2659 it->item->mincalcd = EINA_FALSE;
2661 itb->changed = EINA_TRUE;
2663 if (sd->calc_job) ecore_job_del(sd->calc_job);
2664 sd->calc_job = NULL;
2665 elm_layout_sizing_eval(obj);
2666 sd->pan_changed = EINA_TRUE;
2667 evas_object_smart_changed(sd->pan_obj);
2668 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2669 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2674 /* FIXME: take off later. maybe this show region coords belong in the
2675 * interface (new api functions, set/get)? */
2677 _show_region_hook(void *data,
2680 Evas_Coord x, y, w, h;
2682 ELM_GENLIST_DATA_GET(data, sd);
2684 elm_widget_show_region_get(obj, &x, &y, &w, &h);
2685 //x & y are screen coordinates, Add with pan coordinates
2688 sd->s_iface->content_region_show(obj, x, y, w, h);
2692 _elm_genlist_smart_translate(Evas_Object *obj)
2694 evas_object_smart_callback_call(obj, "language,changed", NULL);
2700 _item_highlight(Elm_Gen_Item *it)
2702 const char *selectraise;
2703 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2705 if (elm_widget_item_disabled_get(it)) return;
2706 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2707 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2708 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2709 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2712 if (!sd->highlight || it->highlighted) return;
2713 #if GENLIST_PINCH_ZOOM_SUPPORT
2714 if (sd->pinch_zoom_mode) return;
2717 selectraise = edje_object_data_get(VIEW(it), "selectraise");
2718 if ((selectraise) && (!strcmp(selectraise, "on")))
2720 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2721 else evas_object_raise(VIEW(it));
2722 if ((it->item->group_item) && (it->item->group_item->realized))
2723 evas_object_raise(it->item->VIEW(group_item));
2725 it->highlighted = EINA_TRUE;
2727 if (it->deco_all_view)
2728 edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
2729 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
2730 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
2734 _item_unhighlight(Elm_Gen_Item *it)
2736 if (!it->highlighted) return;
2738 if (!it->item->nostacking)
2740 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
2742 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
2743 else evas_object_lower(VIEW(it));
2747 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2748 else evas_object_raise(VIEW(it));
2751 it->highlighted = EINA_FALSE;
2753 if (it->deco_all_view)
2754 edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
2755 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
2756 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it);
2760 _item_unselect(Elm_Gen_Item *it)
2762 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2763 _item_unhighlight(it);
2764 if (!it->selected) return;
2766 it->selected = EINA_FALSE;
2767 sd->selected = eina_list_remove(sd->selected, it);
2768 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
2772 _item_select(Elm_Gen_Item *it)
2774 Evas_Object *obj = WIDGET(it);
2775 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2776 if (elm_widget_item_disabled_get(it)) return;
2777 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2778 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
2779 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2780 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
2783 #if GENLIST_PINCH_ZOOM_SUPPORT
2784 if (IS_ROOT_PARENT_IT(it) && (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
2786 elm_genlist_pinch_zoom_mode_set(obj, ELM_GEN_PINCH_ZOOM_EXPAND);
2787 elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
2793 // FIXME: difference from upstream
2794 if ((GL_IT(it)->wsd->last_selected_item) &&
2795 (it != (Elm_Gen_Item *) GL_IT(it)->wsd->last_selected_item))
2796 _item_unfocusable_set
2797 ((Elm_Gen_Item *)GL_IT(it)->wsd->last_selected_item, EINA_TRUE);
2800 // Do not check selected because always select mode can be used
2801 _item_highlight(it);
2802 it->selected = EINA_TRUE;
2803 sd->selected = eina_list_append(sd->selected, it);
2804 sd->last_selected_item = (Elm_Object_Item *)it;
2806 if (it->func.func) it->func.func((void *)it->func.data, obj, it);
2807 if (!EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC))
2809 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
2813 _item_select_unselect(Elm_Gen_Item *it, Eina_Bool selected)
2815 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2816 Evas_Object *obj = ELM_WIDGET_DATA(sd)->obj;
2817 if (elm_widget_item_disabled_get(it)) return;
2819 evas_object_ref(obj);
2822 const Eina_List *l, *ll;
2824 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
2825 if (it2 != it) _item_unselect(it2);
2827 if (selected) _item_select(it);
2828 else _item_unselect(it);
2829 evas_object_unref(obj);
2833 _item_block_position_update(Eina_Inlist *list,
2838 EINA_INLIST_FOREACH(list, tmp)
2840 tmp->position = idx++;
2841 tmp->position_update = EINA_TRUE;
2846 _item_position_update(Eina_List *list,
2852 EINA_LIST_FOREACH(list, l, it)
2854 it->position = idx++;
2855 it->position_update = EINA_TRUE;
2860 _item_block_merge(Item_Block *left,
2866 EINA_LIST_FOREACH(right->items, l, it2)
2868 it2->item->block = left;
2870 left->changed = EINA_TRUE;
2872 left->items = eina_list_merge(left->items, right->items);
2876 _item_block_del(Elm_Gen_Item *it)
2879 Item_Block *itb = it->item->block;
2880 Eina_Bool block_changed = EINA_FALSE;
2882 itb->items = eina_list_remove(itb->items, it);
2884 itb->changed = EINA_TRUE;
2885 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
2886 GL_IT(it)->wsd->calc_job = ecore_job_add(_calc_job, GL_IT(it)->wsd);
2891 il = EINA_INLIST_GET(itb);
2892 itbn = (Item_Block *)(il->next);
2894 it->parent->item->items =
2895 eina_list_remove(it->parent->item->items, it);
2898 _item_block_position_update(il->next, itb->position);
2900 GL_IT(it)->wsd->blocks =
2901 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
2904 if (itbn) itbn->changed = EINA_TRUE;
2908 if (itb->count < (itb->sd->max_items_per_block / 2))
2913 il = EINA_INLIST_GET(itb);
2914 itbp = (Item_Block *)(il->prev);
2915 itbn = (Item_Block *)(il->next);
2917 /* merge block with previous */
2919 ((itbp->count + itb->count) <
2920 (itb->sd->max_items_per_block +
2921 (itb->sd->max_items_per_block / 2))))
2923 _item_block_merge(itbp, itb);
2924 _item_block_position_update
2925 (EINA_INLIST_GET(itb)->next, itb->position);
2926 GL_IT(it)->wsd->blocks = eina_inlist_remove
2927 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
2929 block_changed = EINA_TRUE;
2931 /* merge block with next */
2933 ((itbn->count + itb->count) <
2934 (itb->sd->max_items_per_block +
2935 (itb->sd->max_items_per_block / 2))))
2937 _item_block_merge(itb, itbn);
2938 _item_block_position_update
2939 (EINA_INLIST_GET(itbn)->next, itbn->position);
2940 GL_IT(it)->wsd->blocks =
2941 eina_inlist_remove(GL_IT(it)->wsd->blocks,
2942 EINA_INLIST_GET(itbn));
2944 block_changed = EINA_TRUE;
2951 GL_IT(it)->wsd->pan_changed = EINA_TRUE;
2952 evas_object_smart_changed(GL_IT(it)->wsd->pan_obj);
2953 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
2954 GL_IT(it)->wsd->calc_job = NULL;
2956 #if GENLIST_FX_SUPPORT
2957 it->item->block = NULL;
2962 _decorate_all_item_unrealize(Elm_Gen_Item *it)
2966 if ((!it) || (!it->item->decorate_all_item_realized)) return;
2968 #if GENLIST_FX_SUPPORT
2969 if ((GL_IT(it)->has_proxy_it) && (!GL_IT(it)->wsd->genlist_clearing))
2971 if (!eina_list_data_find(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it))
2972 GL_IT(it)->wsd->pending_unrealized_decorate_all_items =
2973 eina_list_append(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it);
2978 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
2979 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
2980 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2981 _elm_genlist_item_odd_even_update(it);
2982 _elm_genlist_item_state_update(it);
2984 edje_object_signal_emit
2985 (it->deco_all_view, "elm,state,decorate,disabled", "elm");
2986 edje_object_signal_emit
2987 (VIEW(it), "elm,state,decorate,disabled", "elm");
2988 edje_object_signal_emit
2989 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
2990 edje_object_message_signal_process(VIEW(it));
2991 edje_object_message_signal_process(it->deco_all_view);
2993 evas_object_del(it->deco_all_view);
2994 it->deco_all_view = NULL;
2995 elm_widget_stringlist_free(it->item->deco_all_texts);
2996 it->item->deco_all_texts = NULL;
2997 elm_widget_stringlist_free(it->item->deco_all_contents);
2998 it->item->deco_all_contents = NULL;
2999 elm_widget_stringlist_free(it->item->deco_all_states);
3000 it->item->deco_all_states = NULL;
3001 EINA_LIST_FREE (it->item->deco_all_content_objs, icon)
3002 evas_object_del(icon);
3004 _item_mouse_callbacks_del(it, it->deco_all_view);
3005 _item_mouse_callbacks_add(it, VIEW(it));
3007 it->item->decorate_all_item_realized = EINA_FALSE;
3011 _item_free_common(Elm_Gen_Item *it)
3013 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
3014 elm_widget_item_pre_notify_del(it);
3015 if (it->itc->func.del)
3016 it->itc->func.del((void *)it->base.data, WIDGET(it));
3017 if (it->tooltip.del_cb)
3018 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
3019 if (it->item->block) _item_block_del(it);
3021 it->parent->item->items =
3022 eina_list_remove(it->parent->item->items, it);
3023 if (it->item->queued) sd->queue = eina_list_remove(sd->queue, it);
3024 if (it->group) sd->group_items = eina_list_remove(sd->group_items, it);
3026 // FIXME: relative will be better to be fixed. it is too harsh.
3028 it->item->rel->item->rel_revs =
3029 eina_list_remove(it->item->rel->item->rel_revs, it);
3030 if (it->item->rel_revs)
3033 EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
3035 _item_sub_items_clear(it);
3037 #if GENLIST_ENTRY_SUPPORT
3038 it->item->unrealize_disabled = EINA_FALSE;
3041 if (it->selected) sd->selected = eina_list_remove(sd->selected, it);
3042 if (sd->show_item == it) sd->show_item = NULL;
3043 if (sd->anchor_item == it)
3046 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3047 if (!sd->anchor_item) sd->anchor_item =
3048 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3050 if (sd->expanded_item == it) sd->expanded_item = NULL;
3051 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3052 if (sd->state) eina_inlist_sorted_state_free(sd->state);
3054 if (sd->last_selected_item == (Elm_Object_Item *)it)
3055 sd->last_selected_item = NULL;
3059 ecore_timer_del(it->long_timer);
3060 it->long_timer = NULL;
3062 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
3064 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3069 _item_mouse_move_cb(void *data,
3070 Evas *evas __UNUSED__,
3074 EINA_SAFETY_ON_NULL_RETURN(data);
3075 Elm_Gen_Item *it = data;
3076 Elm_Genlist_Smart_Data *sd;
3077 Evas_Event_Mouse_Move *ev = event_info;
3078 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
3079 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
3081 sd = GL_IT(it)->wsd;
3083 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3085 if (!sd->on_hold) _item_unselect(it);
3086 sd->on_hold = EINA_TRUE;
3088 if (sd->multi_touched)
3090 sd->cur_x = ev->cur.canvas.x;
3091 sd->cur_y = ev->cur.canvas.y;
3094 if ((it->dragging) && (it->down))
3096 if (sd->movements == SWIPE_MOVES)
3097 sd->swipe = EINA_TRUE;
3100 sd->history[sd->movements].x = ev->cur.canvas.x;
3101 sd->history[sd->movements].y = ev->cur.canvas.y;
3102 if (abs((sd->history[sd->movements].x -
3103 sd->history[0].x)) > 40)
3104 sd->swipe = EINA_TRUE;
3110 ecore_timer_del(it->long_timer);
3111 it->long_timer = NULL;
3113 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
3116 if ((!it->down) || (sd->longpressed))
3120 ecore_timer_del(it->long_timer);
3121 it->long_timer = NULL;
3123 if ((sd->reorder_mode) && (sd->reorder_it))
3125 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3127 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
3128 sd->reorder_fast = 1;
3129 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
3130 sd->reorder_fast = -1;
3131 else sd->reorder_fast = 0;
3133 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
3135 if (!sd->reorder_start_y)
3136 sd->reorder_start_y = it->item->block->y + it->y;
3140 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
3141 y_pos = oy + oh - sd->reorder_it->item->h;
3145 if (it->deco_all_view)
3146 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
3147 else if (it->item->deco_it_view)
3149 (it, it->item->deco_it_view, it->item->scrl_x, y_pos);
3151 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
3153 if (sd->calc_job) ecore_job_del(sd->calc_job);
3154 sd->calc_job = ecore_job_add(_calc_job, sd);
3158 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3159 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3161 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3162 x = ev->cur.canvas.x - x;
3163 y = ev->cur.canvas.y - y;
3166 if (adx < 0) adx = -dx;
3170 if (ady < 0) ady = -dy;
3174 if ((adx > minw) || (ady > minh))
3176 it->dragging = EINA_TRUE;
3179 ecore_timer_del(it->long_timer);
3180 it->long_timer = NULL;
3185 evas_object_smart_callback_call
3186 (WIDGET(it), SIG_DRAG_START_UP, it);
3190 evas_object_smart_callback_call
3191 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3193 evas_object_smart_callback_call
3194 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3200 evas_object_smart_callback_call
3201 (WIDGET(it), SIG_DRAG_START_DOWN, it);
3205 evas_object_smart_callback_call
3206 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3208 evas_object_smart_callback_call
3209 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3216 _long_press_cb(void *data)
3218 Elm_Gen_Item *it = data, *it2;
3219 Elm_Genlist_Smart_Data *sd;
3222 sd = GL_IT(it)->wsd;
3224 it->long_timer = NULL;
3225 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
3226 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3227 return ECORE_CALLBACK_CANCEL;
3229 GL_IT(it)->wsd->longpressed = EINA_TRUE;
3230 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
3231 if ((GL_IT(it)->wsd->reorder_mode) && (!it->group))
3233 GL_IT(it)->wsd->reorder_it = it;
3234 GL_IT(it)->wsd->reorder_start_y = 0;
3235 if (it->deco_all_view)
3236 evas_object_raise(it->deco_all_view);
3238 evas_object_raise(VIEW(it));
3240 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
3241 sd->s_iface->bounce_allow_set
3242 (ELM_WIDGET_DATA(sd)->obj, EINA_FALSE, EINA_FALSE);
3244 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
3246 if (it != it2) _item_unselect(it2);
3249 // FIXME: difference from opensource
3250 if (it->item->items)
3252 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
3254 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
3256 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
3258 return ECORE_CALLBACK_RENEW;
3263 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
3265 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
3266 return ECORE_CALLBACK_RENEW;
3269 if (!GL_IT(it)->wsd->decorate_all_mode)
3270 edje_object_signal_emit
3271 (VIEW(it), "elm,state,reorder,enabled", "elm");
3274 return ECORE_CALLBACK_CANCEL;
3278 _swipe_do(Elm_Gen_Item *it)
3283 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3284 elm_widget_item_disabled_get(it)) return;
3286 GL_IT(it)->wsd->swipe = EINA_FALSE;
3287 for (i = 0; i < GL_IT(it)->wsd->movements; i++)
3289 sum += GL_IT(it)->wsd->history[i].x;
3290 if (abs(GL_IT(it)->wsd->history[0].y -
3291 GL_IT(it)->wsd->history[i].y) > 10) return;
3294 sum /= GL_IT(it)->wsd->movements;
3295 if (abs(sum - GL_IT(it)->wsd->history[0].x) <= 10) return;
3296 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
3300 _swipe_cancel(void *data)
3302 Elm_Gen_Item *it = data;
3304 if (!it) return ECORE_CALLBACK_CANCEL;
3305 GL_IT(it)->wsd->swipe = EINA_FALSE;
3306 GL_IT(it)->wsd->movements = 0;
3308 return ECORE_CALLBACK_RENEW;
3312 _multi_cancel(void *data)
3314 Elm_Genlist_Smart_Data *sd = data;
3316 if (!sd) return ECORE_CALLBACK_CANCEL;
3317 sd->multi_timeout = EINA_TRUE;
3319 return ECORE_CALLBACK_RENEW;
3323 _multi_touch_gesture_eval(void *data)
3325 Elm_Gen_Item *it = data;
3326 Evas_Coord minw = 0, minh = 0;
3327 Evas_Coord off_x, off_y, off_mx, off_my;
3329 GL_IT(it)->wsd->multi_touched = EINA_FALSE;
3330 if (GL_IT(it)->wsd->multi_timer)
3332 ecore_timer_del(GL_IT(it)->wsd->multi_timer);
3333 GL_IT(it)->wsd->multi_timer = NULL;
3335 if (GL_IT(it)->wsd->multi_timeout)
3337 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3341 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3342 off_x = abs(GL_IT(it)->wsd->cur_x - GL_IT(it)->wsd->prev_x);
3343 off_y = abs(GL_IT(it)->wsd->cur_y - GL_IT(it)->wsd->prev_y);
3344 off_mx = abs(GL_IT(it)->wsd->cur_mx - GL_IT(it)->wsd->prev_mx);
3345 off_my = abs(GL_IT(it)->wsd->cur_my - GL_IT(it)->wsd->prev_my);
3347 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
3348 || (off_my > minh)))
3350 if ((off_x + off_mx) > (off_y + off_my))
3352 if ((GL_IT(it)->wsd->cur_x > GL_IT(it)->wsd->prev_x)
3353 && (GL_IT(it)->wsd->cur_mx > GL_IT(it)->wsd->prev_mx))
3354 evas_object_smart_callback_call
3355 (WIDGET(it), SIG_MULTI_SWIPE_RIGHT, it);
3356 else if ((GL_IT(it)->wsd->cur_x < GL_IT(it)->wsd->prev_x)
3357 && (GL_IT(it)->wsd->cur_mx < GL_IT(it)->wsd->prev_mx))
3358 evas_object_smart_callback_call
3359 (WIDGET(it), SIG_MULTI_SWIPE_LEFT, it);
3360 else if (abs(GL_IT(it)->wsd->cur_x - GL_IT(it)->wsd->cur_mx) >
3361 abs(GL_IT(it)->wsd->prev_x - GL_IT(it)->wsd->prev_mx))
3362 evas_object_smart_callback_call
3363 (WIDGET(it), SIG_MULTI_PINCH_OUT, it);
3365 evas_object_smart_callback_call
3366 (WIDGET(it), SIG_MULTI_PINCH_IN, it);
3370 if ((GL_IT(it)->wsd->cur_y > GL_IT(it)->wsd->prev_y)
3371 && (GL_IT(it)->wsd->cur_my > GL_IT(it)->wsd->prev_my))
3372 evas_object_smart_callback_call
3373 (WIDGET(it), SIG_MULTI_SWIPE_DOWN, it);
3374 else if ((GL_IT(it)->wsd->cur_y < GL_IT(it)->wsd->prev_y)
3375 && (GL_IT(it)->wsd->cur_my < GL_IT(it)->wsd->prev_my))
3376 evas_object_smart_callback_call
3377 (WIDGET(it), SIG_MULTI_SWIPE_UP, it);
3378 else if (abs(GL_IT(it)->wsd->cur_y - GL_IT(it)->wsd->cur_my) >
3379 abs(GL_IT(it)->wsd->prev_y - GL_IT(it)->wsd->prev_my))
3381 evas_object_smart_callback_call
3382 (WIDGET(it), SIG_MULTI_PINCH_OUT, it);
3383 #if GENLIST_PINCH_ZOOM_SUPPORT
3384 if (IS_ROOT_PARENT_IT(it) && (GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
3386 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj, ELM_GEN_PINCH_ZOOM_EXPAND);
3387 elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
3393 evas_object_smart_callback_call
3394 (WIDGET(it), SIG_MULTI_PINCH_IN, it);
3395 #if GENLIST_PINCH_ZOOM_SUPPORT
3396 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj,
3397 ELM_GEN_PINCH_ZOOM_CONTRACT);
3403 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3407 _item_multi_down_cb(void *data,
3408 Evas *evas __UNUSED__,
3409 Evas_Object *obj __UNUSED__,
3412 Elm_Gen_Item *it = data;
3413 Evas_Event_Multi_Down *ev = event_info;
3415 if ((GL_IT(it)->wsd->multi_device != 0) || (GL_IT(it)->wsd->multi_touched)
3416 || (GL_IT(it)->wsd->multi_timeout))
3419 GL_IT(it)->wsd->multi_device = ev->device;
3420 GL_IT(it)->wsd->multi_down = EINA_TRUE;
3421 GL_IT(it)->wsd->multi_touched = EINA_TRUE;
3422 GL_IT(it)->wsd->prev_mx = ev->canvas.x;
3423 GL_IT(it)->wsd->prev_my = ev->canvas.y;
3425 if (!GL_IT(it)->wsd->wasselected)
3427 GL_IT(it)->wsd->wasselected = EINA_FALSE;
3431 ecore_timer_del(it->long_timer);
3432 it->long_timer = NULL;
3436 it->dragging = EINA_FALSE;
3437 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
3439 if (it->item->swipe_timer)
3441 ecore_timer_del(it->item->swipe_timer);
3442 it->item->swipe_timer = NULL;
3444 GL_IT(it)->wsd->longpressed = EINA_FALSE;
3445 if (GL_IT(it)->wsd->on_hold)
3447 GL_IT(it)->wsd->swipe = EINA_FALSE;
3448 GL_IT(it)->wsd->movements = 0;
3449 GL_IT(it)->wsd->on_hold = EINA_FALSE;
3454 _item_multi_up_cb(void *data,
3455 Evas *evas __UNUSED__,
3456 Evas_Object *obj __UNUSED__,
3459 Elm_Gen_Item *it = data;
3460 Evas_Event_Multi_Up *ev = event_info;
3462 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3463 GL_IT(it)->wsd->multi_device = 0;
3464 GL_IT(it)->wsd->multi_down = EINA_FALSE;
3465 if (GL_IT(it)->wsd->mouse_down) return;
3466 _multi_touch_gesture_eval(data);
3470 _item_multi_move_cb(void *data,
3471 Evas *evas __UNUSED__,
3472 Evas_Object *obj __UNUSED__,
3475 Elm_Gen_Item *it = data;
3476 Evas_Event_Multi_Move *ev = event_info;
3478 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3479 GL_IT(it)->wsd->cur_mx = ev->cur.canvas.x;
3480 GL_IT(it)->wsd->cur_my = ev->cur.canvas.y;
3484 // FIXME: difference from upstream
3486 _item_unfocusable_set(Elm_Gen_Item *it, Eina_Bool unfocus)
3489 Evas_Object *item_obj;
3490 Evas_Object *obj = WIDGET(it);
3494 EINA_LIST_FOREACH(it->content_objs, l, item_obj)
3496 if (unfocus) elm_widget_focused_object_clear(item_obj);
3497 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3499 EINA_LIST_FOREACH(it->item->flip_content_objs, l, item_obj)
3501 if (unfocus) elm_widget_focused_object_clear(item_obj);
3502 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3504 EINA_LIST_FOREACH(it->item->deco_all_content_objs, l, item_obj)
3506 if (unfocus) elm_widget_focused_object_clear(item_obj);
3507 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3509 it->can_focus = !unfocus;
3515 _item_mouse_down_cb(void *data,
3516 Evas *evas __UNUSED__,
3520 Evas_Event_Mouse_Down *ev = event_info;
3521 Elm_Gen_Item *it = data;
3522 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
3525 if (ev->button != 1) return;
3527 _item_unfocusable_set(it, EINA_FALSE);
3529 it->down = EINA_TRUE;
3530 it->dragging = EINA_FALSE;
3531 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3532 it->dx = ev->canvas.x - x;
3533 it->dy = ev->canvas.y - y;
3534 sd->mouse_down = EINA_TRUE;
3535 if (!sd->multi_touched)
3537 sd->prev_x = ev->canvas.x;
3538 sd->prev_y = ev->canvas.y;
3539 sd->multi_timeout = EINA_FALSE;
3540 if (sd->multi_timer) ecore_timer_del(sd->multi_timer);
3541 sd->multi_timer = ecore_timer_add(1, _multi_cancel, sd);
3543 sd->longpressed = EINA_FALSE;
3544 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3546 sd->on_hold = EINA_TRUE;
3549 else sd->on_hold = EINA_FALSE;
3550 _item_highlight(it);
3551 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
3552 if ((!elm_widget_item_disabled_get(it)) &&
3553 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3555 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
3556 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
3558 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
3559 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
3560 if (it->long_timer) ecore_timer_del(it->long_timer);
3562 it->long_timer = ecore_timer_add
3563 (sd->longpress_timeout, _long_press_cb, it);
3565 it->long_timer = NULL;
3566 sd->swipe = EINA_FALSE;
3571 _item_block_new(Elm_Genlist_Smart_Data *sd,
3576 itb = calloc(1, sizeof(Item_Block));
3577 if (!itb) return NULL;
3581 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
3582 _item_block_position_update(sd->blocks, 0);
3586 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3587 itb->position_update = EINA_TRUE;
3588 if (sd->blocks != EINA_INLIST_GET(itb))
3591 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
3603 _item_block_add(Elm_Genlist_Smart_Data *sd,
3606 Item_Block *itb = NULL;
3613 itb = calloc(1, sizeof(Item_Block));
3614 if (!itb) return EINA_FALSE;
3616 if (!it->item->rel->item->block)
3619 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3620 itb->items = eina_list_append(itb->items, it);
3621 itb->position_update = EINA_TRUE;
3622 it->position = eina_list_count(itb->items);
3623 it->position_update = EINA_TRUE;
3625 if (sd->blocks != EINA_INLIST_GET(itb))
3629 (EINA_INLIST_GET(itb)->prev))->position + 1;
3640 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3641 if (it->item->before)
3643 sd->blocks = eina_inlist_prepend_relative
3644 (sd->blocks, EINA_INLIST_GET(itb),
3645 EINA_INLIST_GET(it->item->rel->item->block));
3647 eina_list_prepend_relative_list(itb->items, it, tmp);
3649 /* Update index from where we prepended */
3650 _item_position_update
3651 (eina_list_prev(tmp), it->item->rel->position);
3652 _item_block_position_update
3653 (EINA_INLIST_GET(itb),
3654 it->item->rel->item->block->position);
3658 sd->blocks = eina_inlist_append_relative
3659 (sd->blocks, EINA_INLIST_GET(itb),
3660 EINA_INLIST_GET(it->item->rel->item->block));
3662 eina_list_append_relative_list(itb->items, it, tmp);
3664 /* Update block index from where we appended */
3665 _item_position_update
3666 (eina_list_next(tmp), it->item->rel->position + 1);
3667 _item_block_position_update
3668 (EINA_INLIST_GET(itb),
3669 it->item->rel->item->block->position + 1);
3675 if (it->item->before)
3679 itb = (Item_Block *)(sd->blocks);
3680 if (itb->count >= sd->max_items_per_block)
3682 itb = _item_block_new(sd, EINA_TRUE);
3683 if (!itb) return EINA_FALSE;
3688 itb = _item_block_new(sd, EINA_TRUE);
3689 if (!itb) return EINA_FALSE;
3691 itb->items = eina_list_prepend(itb->items, it);
3693 _item_position_update(itb->items, 0);
3699 itb = (Item_Block *)(sd->blocks->last);
3700 if (itb->count >= sd->max_items_per_block)
3702 itb = _item_block_new(sd, EINA_FALSE);
3703 if (!itb) return EINA_FALSE;
3708 itb = _item_block_new(sd, EINA_FALSE);
3709 if (!itb) return EINA_FALSE;
3711 itb->items = eina_list_append(itb->items, it);
3712 it->position = eina_list_count(itb->items);
3720 if (it->item->rel->item->queued)
3722 /* NOTE: for a strange reason eina_list and eina_inlist
3723 don't have the same property on sorted insertion
3724 order, so the queue is not always ordered like the
3725 item list. This lead to issue where we depend on an
3726 item that is not yet created. As a quick work around,
3727 we reschedule the calc of the item and stop reordering
3728 the list to prevent any nasty issue to show up here.
3730 sd->queue = eina_list_append(sd->queue, it);
3731 sd->requeued = EINA_TRUE;
3732 it->item->queued = EINA_TRUE;
3736 itb = it->item->rel->item->block;
3737 if (!itb) goto newblock;
3738 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3739 if (it->item->before)
3741 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3742 _item_position_update
3743 (eina_list_prev(tmp), it->item->rel->position);
3747 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3748 _item_position_update
3749 (eina_list_next(tmp), it->item->rel->position + 1);
3754 itb->changed = EINA_TRUE;
3755 it->item->block = itb;
3756 if (itb->sd->calc_job) ecore_job_del(itb->sd->calc_job);
3757 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd);
3759 if (itb->count > itb->sd->max_items_per_block)
3764 Eina_Bool done = EINA_FALSE;
3766 newc = itb->count / 2;
3768 if (EINA_INLIST_GET(itb)->prev)
3770 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3772 if (itbp->count + newc < sd->max_items_per_block / 2)
3774 /* moving items to previous block */
3775 while ((itb->count > newc) && (itb->items))
3777 it2 = eina_list_data_get(itb->items);
3778 itb->items = eina_list_remove_list
3779 (itb->items, itb->items);
3782 itbp->items = eina_list_append(itbp->items, it2);
3783 it2->item->block = itbp;
3791 if (!done && EINA_INLIST_GET(itb)->next)
3793 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3795 if (itbn->count + newc < sd->max_items_per_block / 2)
3797 /* moving items to next block */
3798 while ((itb->count > newc) && (itb->items))
3802 l = eina_list_last(itb->items);
3803 it2 = eina_list_data_get(l);
3804 itb->items = eina_list_remove_list(itb->items, l);
3807 itbn->items = eina_list_prepend(itbn->items, it2);
3808 it2->item->block = itbn;
3818 /* moving items to new block */
3819 itb2 = calloc(1, sizeof(Item_Block));
3820 if (!itb2) return EINA_FALSE;
3823 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
3824 EINA_INLIST_GET(itb));
3825 itb2->changed = EINA_TRUE;
3826 while ((itb->count > newc) && (itb->items))
3830 l = eina_list_last(itb->items);
3832 itb->items = eina_list_remove_list(itb->items, l);
3835 itb2->items = eina_list_prepend(itb2->items, it2);
3836 it2->item->block = itb2;
3846 _item_process(Elm_Genlist_Smart_Data *sd,
3849 if (!_item_block_add(sd, it)) return 1;
3851 _item_block_realize(it->item->block);
3857 _item_process_post(Elm_Genlist_Smart_Data *sd,
3861 Eina_Bool show_me = EINA_FALSE;
3863 if (it->item->block->changed)
3865 show_me = _item_block_recalc
3866 (it->item->block, it->item->block->num, qadd);
3867 it->item->block->changed = 0;
3868 if (sd->pan_changed)
3870 if (sd->calc_job) ecore_job_del(sd->calc_job);
3871 sd->calc_job = NULL;
3873 sd->pan_changed = EINA_FALSE;
3876 if (show_me) it->item->block->show_me = EINA_TRUE;
3878 /* when prepending, move the scroller along with the first selected
3879 * item to create the illusion that we're watching the selected
3880 * item this prevents the selected item being scrolled off the
3883 if (sd->selected && it->item->before)
3888 it2 = sd->selected->data;
3889 if (!it2->item->block) return;
3890 sd->s_iface->content_pos_get(ELM_WIDGET_DATA(sd)->obj, NULL, &y);
3891 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
3892 if ((it->y + it->item->block->y > y + h) ||
3893 (it->y + it->item->block->y + it->item->h < y))
3894 /* offscreen, just update */
3895 sd->s_iface->content_region_show
3896 (ELM_WIDGET_DATA(sd)->obj, it2->x + it2->item->block->x, y,
3897 it2->item->block->w, h);
3899 sd->s_iface->content_region_show
3900 (ELM_WIDGET_DATA(sd)->obj, it->x + it->item->block->x,
3901 y + it->item->h, it->item->block->w, h);
3906 _queue_process(Elm_Genlist_Smart_Data *sd)
3911 t0 = ecore_loop_time_get();
3912 for (n = 0; (sd->queue) && (n < 128); n++)
3916 it = eina_list_data_get(sd->queue);
3917 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
3918 it->item->queued = EINA_FALSE;
3919 if (_item_process(sd, it)) continue;
3920 t = ecore_time_get();
3921 _item_process_post(sd, it, EINA_TRUE);
3922 /* same as eina_inlist_count > 1 */
3923 if (sd->blocks && sd->blocks->next)
3925 if ((t - t0) > (ecore_animator_frametime_get())) break;
3932 _item_idle_enterer(void *data)
3934 Elm_Genlist_Smart_Data *sd = data;
3936 if (sd->prev_viewport_w == 0) return ECORE_CALLBACK_RENEW;
3937 if (_queue_process(sd) > 0)
3940 // Job always be alive because idle_enterer should be alive
3941 if (sd->calc_job) ecore_job_del(sd->calc_job);
3942 sd->calc_job = ecore_job_add(_calc_job, sd);
3946 sd->queue_idle_enterer = NULL;
3947 return ECORE_CALLBACK_CANCEL;
3950 #if GENLIST_FX_SUPPORT
3951 if (sd->fx_first_captured)
3952 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj);
3954 return ECORE_CALLBACK_RENEW;
3958 _item_queue(Elm_Genlist_Smart_Data *sd,
3962 if (it->item->queued) return;
3964 it->item->queued = EINA_TRUE;
3965 if (cb && !sd->requeued)
3966 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
3968 sd->queue = eina_list_append(sd->queue, it);
3970 if (sd->queue_idle_enterer)
3971 ecore_idle_enterer_del(sd->queue_idle_enterer);
3972 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd);
3974 if (sd->prev_viewport_w != 0)
3976 while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
3979 while ((sd->queue) && (sd->blocks) &&
3980 (sd->homogeneous) && (sd->mode == ELM_LIST_COMPRESS))
3985 /* If the application wants to know the relative item, use
3986 * elm_genlist_item_prev_get(it)*/
3988 _item_move_after(Elm_Gen_Item *it,
3989 Elm_Gen_Item *after)
3993 if (it == after) return;
3995 GL_IT(it)->wsd->items =
3996 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
3997 if (it->item->block) _item_block_del(it);
3999 GL_IT(it)->wsd->items = eina_inlist_append_relative
4000 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4001 it->item->rel = after;
4002 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
4003 it->item->before = EINA_FALSE;
4004 if (after->item->group_item) it->item->group_item = after->item->group_item;
4005 _item_queue(GL_IT(it)->wsd, it, NULL);
4007 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4011 _access_activate_cb(void *data __UNUSED__,
4012 Evas_Object *part_obj __UNUSED__,
4013 Elm_Object_Item *item)
4015 _item_select_unselect((Elm_Gen_Item *)item, EINA_TRUE);
4018 /* If the application wants to know the relative item, use
4019 * elm_genlist_item_next_get(it)*/
4021 _item_move_before(Elm_Gen_Item *it,
4022 Elm_Gen_Item *before)
4025 if (!before) return;
4026 if (it == before) return;
4028 GL_IT(it)->wsd->items =
4029 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
4030 if (it->item->block) _item_block_del(it);
4031 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
4032 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4033 it->item->rel = before;
4034 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
4035 it->item->before = EINA_TRUE;
4036 if (before->item->group_item)
4037 it->item->group_item = before->item->group_item;
4038 _item_queue(GL_IT(it)->wsd, it, NULL);
4040 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4044 _item_mouse_up_cb(void *data,
4045 Evas *evas __UNUSED__,
4046 Evas_Object *obj __UNUSED__,
4049 Evas_Event_Mouse_Up *ev = event_info;
4050 Eina_Bool dragged = EINA_FALSE;
4051 Elm_Genlist_Smart_Data *sd;
4052 Elm_Gen_Item *it = data;
4054 if (ev->button != 1) return;
4055 it->down = EINA_FALSE;
4056 sd = GL_IT(it)->wsd;
4058 sd->mouse_down = EINA_FALSE;
4059 if (sd->multi_touched)
4061 if ((!sd->multi) && (!it->selected) && (it->highlighted))
4062 _item_unhighlight(it);
4063 if (sd->multi_down) return;
4064 _multi_touch_gesture_eval(data);
4069 ecore_timer_del(it->long_timer);
4070 it->long_timer = NULL;
4074 it->dragging = EINA_FALSE;
4075 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
4078 if (it->item->swipe_timer)
4080 ecore_timer_del(it->item->swipe_timer);
4081 it->item->swipe_timer = NULL;
4083 if (sd->multi_timer)
4085 ecore_timer_del(sd->multi_timer);
4086 sd->multi_timer = NULL;
4087 sd->multi_timeout = EINA_FALSE;
4089 sd->on_hold = EINA_FALSE;
4090 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4092 if (sd->swipe) _swipe_do(data);
4093 sd->longpressed = EINA_FALSE;
4096 if ((sd->reorder_mode) && (sd->reorder_it))
4098 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
4099 sd->reorder_fast = 0;
4101 if (sd->reorder_rel &&
4102 (sd->reorder_it->parent == sd->reorder_rel->parent))
4104 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
4105 _item_move_before(sd->reorder_it, sd->reorder_rel);
4107 _item_move_after(sd->reorder_it, sd->reorder_rel);
4108 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4112 if (sd->calc_job) ecore_job_del(sd->calc_job);
4113 sd->calc_job = ecore_job_add(_calc_job, sd);
4115 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
4116 sd->reorder_it = sd->reorder_rel = NULL;
4117 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4118 sd->s_iface->bounce_allow_set
4119 (ELM_WIDGET_DATA(sd)->obj, sd->h_bounce, sd->v_bounce);
4123 if (it->want_unrealize && !(it->item->unrealize_disabled))
4125 _item_unrealize(it, EINA_FALSE);
4126 if (it->item->block->want_unrealize)
4127 _item_block_unrealize(it->item->block);
4132 if (!sd->longpressed)
4133 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
4134 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
4135 _item_select_unselect(it, EINA_TRUE);
4136 else _item_select_unselect(it, !it->selected);
4138 _item_unhighlight(it);
4142 _item_mouse_callbacks_add(Elm_Gen_Item *it,
4145 evas_object_event_callback_add
4146 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4147 evas_object_event_callback_add
4148 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4149 evas_object_event_callback_add
4150 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4151 evas_object_event_callback_add
4152 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4153 evas_object_event_callback_add
4154 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4155 evas_object_event_callback_add
4156 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4160 _item_mouse_callbacks_del(Elm_Gen_Item *it,
4163 evas_object_event_callback_del_full
4164 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4165 evas_object_event_callback_del_full
4166 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4167 evas_object_event_callback_del_full
4168 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4169 evas_object_event_callback_del_full
4170 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4171 evas_object_event_callback_del_full
4172 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4173 evas_object_event_callback_del_full
4174 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4178 _scroll_hold_timer_cb(void *data)
4180 Elm_Genlist_Smart_Data *sd = data;
4182 if (!data) return ECORE_CALLBACK_CANCEL;
4184 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4185 sd->scr_hold_timer = NULL;
4187 return ECORE_CALLBACK_CANCEL;
4191 _decorate_item_finished_signal_cb(void *data,
4193 const char *emission __UNUSED__,
4194 const char *source __UNUSED__)
4196 Elm_Gen_Item *it = data;
4199 if (!data || !obj) return;
4200 if ((!it->realized) || (!it->item->deco_it_view)) return;
4202 it->item->nocache_once = EINA_FALSE;
4203 _decorate_item_unrealize(it);
4204 if (it->item->group_item)
4205 evas_object_raise(it->item->VIEW(group_item));
4207 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
4208 GL_IT(it)->wsd->decorate_it_type);
4209 edje_object_signal_callback_del_full
4210 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
4214 _item_mode_content_unrealize(Elm_Gen_Item *it,
4215 Evas_Object *target,
4218 Eina_List **contents_list)
4220 Eina_List *res = *contents_list;
4222 if (it->itc->func.content_get)
4226 Evas_Object *ic = NULL;
4228 EINA_LIST_FOREACH(*source, l, key)
4230 if (parts && fnmatch(parts, key, FNM_PERIOD))
4233 ic = edje_object_part_swallow_get(target, key);
4236 res = eina_list_remove(res, ic);
4237 edje_object_part_unswallow(target, ic);
4238 evas_object_del(ic);
4247 _item_content_unrealize(Elm_Gen_Item *it,
4248 Evas_Object *target,
4252 Eina_List *res = it->content_objs;
4254 if (it->itc->func.content_get)
4258 Evas_Object *ic = NULL;
4260 EINA_LIST_FOREACH(*source, l, key)
4262 if (parts && fnmatch(parts, key, FNM_PERIOD))
4265 ic = edje_object_part_swallow_get(target, key);
4268 res = eina_list_remove(res, ic);
4269 edje_object_part_unswallow(target, ic);
4270 // FIXME: If parent-child relationship was broken before 'ic'
4271 // is deleted, freeze_pop will not be called. ex) elm_slider
4272 // If layout is used instead of edje, this problme can be
4274 if (0 != elm_widget_scroll_freeze_get(ic))
4275 elm_widget_scroll_freeze_pop(ic);
4276 evas_object_del(ic);
4285 _item_block_recalc(Item_Block *itb,
4289 const Eina_List *l, *ll;
4291 Evas_Coord minw = 0, minh = 0;
4292 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
4296 EINA_LIST_FOREACH_SAFE(itb->items, l, ll, it)
4298 show_me |= it->item->show_me;
4303 if (!it->item->mincalcd) changed = EINA_TRUE;
4306 _item_realize(it, in, EINA_TRUE);
4307 _item_unrealize(it, EINA_TRUE);
4312 if ((itb->sd->homogeneous) &&
4313 (itb->sd->mode == ELM_LIST_COMPRESS))
4317 it->item->w = it->item->minw =
4318 GL_IT(it)->wsd->group_item_width;
4319 it->item->h = it->item->minh =
4320 GL_IT(it)->wsd->group_item_height;
4324 it->item->w = it->item->minw =
4325 GL_IT(it)->wsd->item_width;
4326 it->item->h = it->item->minh =
4327 GL_IT(it)->wsd->item_height;
4332 _item_realize(it, in, EINA_TRUE);
4333 _item_unrealize(it, EINA_TRUE);
4339 if (!it->item->mincalcd) changed = EINA_TRUE;
4340 _item_realize(it, in, EINA_FALSE);
4342 minh += it->item->minh;
4343 if (minw < it->item->minw) minw = it->item->minw;
4347 #if GENLIST_PINCH_ZOOM_SUPPORT
4348 if (IS_ROOT_PARENT_IT(it))
4349 it->item->pan_scrl_y = itb->y + it->y;
4353 if (changed) itb->sd->pan_changed = changed;
4356 itb->changed = EINA_FALSE;
4357 itb->position_update = EINA_FALSE;
4363 _update_job(void *data)
4365 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
4366 Elm_Genlist_Smart_Data *sd = data;
4371 sd->update_job = NULL;
4374 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4375 EINA_INLIST_FOREACH(sd->blocks, itb)
4377 Evas_Coord itminw, itminh;
4384 _item_block_position(itb, num);
4388 recalc = EINA_FALSE;
4389 EINA_LIST_FOREACH(itb->items, l2, it)
4391 if (it->item->updateme)
4393 itminw = it->item->minw;
4394 itminh = it->item->minh;
4396 it->item->updateme = EINA_FALSE;
4399 _item_unrealize(it, EINA_FALSE);
4400 _item_realize(it, num, EINA_FALSE);
4401 position = EINA_TRUE;
4405 _item_realize(it, num, EINA_TRUE);
4406 _item_unrealize(it, EINA_TRUE);
4408 if ((it->item->minw != itminw) || (it->item->minh != itminh))
4413 itb->updateme = EINA_FALSE;
4416 position = EINA_TRUE;
4417 itb->changed = EINA_TRUE;
4418 _item_block_recalc(itb, num0, EINA_FALSE);
4419 _item_block_position(itb, num0);
4424 if (sd->calc_job) ecore_job_del(sd->calc_job);
4425 sd->calc_job = ecore_job_add(_calc_job, sd);
4427 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4428 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4432 _scroll_animate_start_cb(Evas_Object *obj,
4433 void *data __UNUSED__)
4435 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
4439 _scroll_animate_stop_cb(Evas_Object *obj,
4440 void *data __UNUSED__)
4442 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
4446 _scroll_drag_start_cb(Evas_Object *obj,
4447 void *data __UNUSED__)
4449 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
4453 _scroll_drag_stop_cb(Evas_Object *obj,
4454 void *data __UNUSED__)
4456 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
4460 _edge_left_cb(Evas_Object *obj,
4461 void *data __UNUSED__)
4463 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
4467 _edge_right_cb(Evas_Object *obj,
4468 void *data __UNUSED__)
4470 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
4474 _edge_top_cb(Evas_Object *obj,
4475 void *data __UNUSED__)
4477 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
4481 _edge_bottom_cb(Evas_Object *obj,
4482 void *data __UNUSED__)
4484 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
4488 _vbar_drag_cb(Evas_Object *obj,
4489 void *data __UNUSED__)
4491 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
4495 _vbar_press_cb(Evas_Object *obj,
4496 void *data __UNUSED__)
4498 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
4502 _vbar_unpress_cb(Evas_Object *obj,
4503 void *data __UNUSED__)
4505 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
4509 _hbar_drag_cb(Evas_Object *obj,
4510 void *data __UNUSED__)
4512 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
4516 _hbar_press_cb(Evas_Object *obj,
4517 void *data __UNUSED__)
4519 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
4523 _hbar_unpress_cb(Evas_Object *obj,
4524 void *data __UNUSED__)
4526 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
4530 _decorate_item_realize(Elm_Gen_Item *it)
4533 if (it->item->deco_it_view) return;
4535 //evas_event_freeze(evas_object_evas_get(obj));
4536 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
4537 edje_object_scale_set
4538 (it->item->deco_it_view, elm_widget_scale_get(WIDGET(it)) *
4539 elm_config_scale_get());
4540 evas_object_smart_member_add
4541 (it->item->deco_it_view, GL_IT(it)->wsd->pan_obj);
4542 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
4544 strncpy(buf, "item", sizeof(buf));
4545 if (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)
4546 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
4548 if (it->item->order_num_in & 0x1)
4549 strncat(buf, "_odd", sizeof(buf) - strlen(buf));
4550 strncat(buf, "/", sizeof(buf) - strlen(buf));
4551 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
4553 elm_widget_theme_object_set
4554 (WIDGET(it), it->item->deco_it_view, "genlist", buf,
4555 elm_widget_style_get(WIDGET(it)));
4556 edje_object_mirrored_set
4557 (it->item->deco_it_view, elm_widget_mirrored_get(WIDGET(it)));
4559 /* signal callback add */
4560 evas_object_event_callback_add
4561 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb,
4563 evas_object_event_callback_add
4564 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4565 evas_object_event_callback_add
4566 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb,
4569 if (eina_list_count(it->item->deco_it_content_objs) != 0)
4570 ERR_ABORT("If you see this error, please notify us and we"
4573 /* text_get, content_get, state_get */
4575 (it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
4576 if (!it->item->deco_it_contents)
4577 it->item->deco_it_contents =
4578 elm_widget_stringlist_get
4579 (edje_object_data_get(it->item->deco_it_view, "contents"));
4580 it->item->deco_it_content_objs =
4581 _item_mode_content_realize
4582 (it, it->item->deco_it_view, &it->item->deco_it_contents, NULL,
4583 &it->item->deco_it_content_objs);
4585 (it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
4586 edje_object_part_swallow
4587 (it->item->deco_it_view,
4588 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
4590 it->want_unrealize = EINA_FALSE;
4591 //evas_event_thaw(evas_object_evas_get(obj));
4592 //evas_event_thaw_eval(evas_object_evas_get(obj));
4596 _decorate_item_set(Elm_Gen_Item *it)
4598 Elm_Genlist_Smart_Data *sd;
4603 sd = GL_IT(it)->wsd;
4606 it->item->nocache_once = EINA_TRUE;
4608 if (sd->scr_hold_timer)
4610 ecore_timer_del(sd->scr_hold_timer);
4611 sd->scr_hold_timer = NULL;
4613 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
4614 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
4616 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4617 _decorate_item_realize(it);
4618 if (it->item->group_item)
4619 evas_object_raise(it->item->VIEW(group_item));
4621 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
4622 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4623 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4625 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
4626 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4630 _decorate_item_unset(Elm_Genlist_Smart_Data *sd)
4632 char buf[1024], buf2[1024];
4635 if (!sd->mode_item) return;
4638 it->item->nocache_once = EINA_TRUE;
4640 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
4641 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
4642 sd->decorate_it_type);
4643 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4644 edje_object_signal_callback_add
4645 (it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb,
4647 sd->mode_item = NULL;
4651 // FIXME: difference from upstream
4653 _mouse_down_scroller(void *data,
4654 Evas *evas __UNUSED__,
4655 Evas_Object *obj __UNUSED__,
4656 void *event_info __UNUSED__)
4658 Widget_Data *wd = elm_widget_data_get(data);
4661 wd->drag_started = EINA_FALSE;
4665 _mouse_up_scroller(void *data,
4666 Evas *evas __UNUSED__,
4667 Evas_Object *obj __UNUSED__,
4668 void *event_info __UNUSED__)
4670 Widget_Data *wd = elm_widget_data_get(data);
4673 wd->drag_started = EINA_FALSE;
4677 _mouse_move_scroller(void *data,
4678 Evas *evas __UNUSED__,
4679 Evas_Object *obj __UNUSED__,
4682 Widget_Data *wd = elm_widget_data_get(data);
4683 Evas_Event_Mouse_Move *ev = event_info;
4684 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
4687 if (wd->drag_started) return;
4689 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4690 dx = ev->cur.canvas.x - ev->prev.canvas.x;
4691 dy = ev->cur.canvas.y - ev->prev.canvas.y;
4694 if (adx < 0) adx = -dx;
4695 if (ady < 0) ady = -dy;
4696 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
4700 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
4701 wd->drag_started = EINA_TRUE;
4705 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
4706 wd->drag_started = EINA_TRUE;
4713 _elm_genlist_smart_add(Evas_Object *obj)
4715 Evas_Coord minw, minh;
4716 Elm_Genlist_Pan_Smart_Data *pan_data;
4718 EVAS_SMART_DATA_ALLOC(obj, Elm_Genlist_Smart_Data);
4720 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.add(obj);
4722 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
4723 evas_object_smart_member_add(priv->hit_rect, obj);
4724 elm_widget_sub_object_add(obj, priv->hit_rect);
4726 /* common scroller hit rectangle setup */
4727 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
4728 evas_object_show(priv->hit_rect);
4729 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
4731 elm_widget_can_focus_set(obj, EINA_TRUE);
4732 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
4734 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
4736 /* interface's add() routine issued AFTER the object's smart_add() */
4737 priv->s_iface = evas_object_smart_interface_get
4738 (obj, ELM_SCROLLABLE_IFACE_NAME);
4740 priv->s_iface->objects_set
4741 (obj, ELM_WIDGET_DATA(priv)->resize_obj, priv->hit_rect);
4743 priv->s_iface->bounce_allow_set
4744 (obj, EINA_FALSE, _elm_config->thumbscroll_bounce_enable);
4745 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
4747 priv->s_iface->animate_start_cb_set(obj, _scroll_animate_start_cb);
4748 priv->s_iface->animate_stop_cb_set(obj, _scroll_animate_stop_cb);
4749 priv->s_iface->drag_start_cb_set(obj, _scroll_drag_start_cb);
4750 priv->s_iface->drag_stop_cb_set(obj, _scroll_drag_stop_cb);
4751 priv->s_iface->edge_left_cb_set(obj, _edge_left_cb);
4752 priv->s_iface->edge_right_cb_set(obj, _edge_right_cb);
4753 priv->s_iface->edge_top_cb_set(obj, _edge_top_cb);
4754 priv->s_iface->edge_bottom_cb_set(obj, _edge_bottom_cb);
4755 priv->s_iface->vbar_drag_cb_set(obj, _vbar_drag_cb);
4756 priv->s_iface->vbar_press_cb_set(obj, _vbar_press_cb);
4757 priv->s_iface->vbar_unpress_cb_set(obj, _vbar_unpress_cb);
4758 priv->s_iface->hbar_drag_cb_set(obj, _hbar_drag_cb);
4759 priv->s_iface->hbar_press_cb_set(obj, _hbar_press_cb);
4760 priv->s_iface->hbar_unpress_cb_set(obj, _hbar_unpress_cb);
4762 priv->mode = ELM_LIST_SCROLL;
4763 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
4764 priv->item_cache_max = priv->max_items_per_block * 2;
4765 priv->longpress_timeout = _elm_config->longpress_timeout;
4766 priv->highlight = EINA_TRUE;
4768 #if GENLIST_FX_SUPPORT
4769 priv->fx_mode = EINA_FALSE;
4770 priv->rendered = EINA_FALSE;
4771 priv->fx_first_captured = EINA_FALSE;
4772 priv->fx_playing = EINA_FALSE;
4773 priv->fx_items_deleted = EINA_FALSE;
4774 priv->genlist_clearing = EINA_FALSE;
4777 priv->pan_obj = evas_object_smart_add
4778 (evas_object_evas_get(obj), _elm_genlist_pan_smart_class_new());
4779 pan_data = evas_object_smart_data_get(priv->pan_obj);
4780 pan_data->wsd = priv;
4783 // FIXME: difference from upstream
4784 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
4785 _mouse_down_scroller, obj);
4786 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
4787 _mouse_up_scroller, obj);
4788 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
4789 _mouse_move_scroller, obj);
4792 priv->s_iface->extern_pan_set(obj, priv->pan_obj);
4794 edje_object_size_min_calc(ELM_WIDGET_DATA(priv)->resize_obj, &minw, &minh);
4795 evas_object_size_hint_min_set(obj, minw, minh);
4797 _item_cache_all_free(priv);
4798 _mirrored_set(obj, elm_widget_mirrored_get(obj));
4800 elm_layout_sizing_eval(obj);
4804 _elm_genlist_smart_del(Evas_Object *obj)
4806 ELM_GENLIST_DATA_GET(obj, sd);
4808 elm_genlist_clear(obj);
4809 if (sd->calc_job) ecore_job_del(sd->calc_job);
4810 if (sd->update_job) ecore_job_del(sd->update_job);
4811 if (sd->queue_idle_enterer) ecore_idle_enterer_del(sd->queue_idle_enterer);
4812 if (sd->must_recalc_idler) ecore_idler_del(sd->must_recalc_idler);
4813 if (sd->multi_timer) ecore_timer_del(sd->multi_timer);
4814 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
4815 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
4817 evas_object_del(sd->pan_obj);
4818 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.del(obj);
4822 _elm_genlist_smart_move(Evas_Object *obj,
4826 ELM_GENLIST_DATA_GET(obj, sd);
4828 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.move(obj, x, y);
4830 evas_object_move(sd->hit_rect, x, y);
4834 _elm_genlist_smart_resize(Evas_Object *obj,
4838 ELM_GENLIST_DATA_GET(obj, sd);
4840 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.resize(obj, w, h);
4842 evas_object_resize(sd->hit_rect, w, h);
4846 _elm_genlist_smart_member_add(Evas_Object *obj,
4847 Evas_Object *member)
4849 ELM_GENLIST_DATA_GET(obj, sd);
4851 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.member_add(obj, member);
4854 evas_object_raise(sd->hit_rect);
4858 _access_obj_process(Elm_Genlist_Smart_Data *sd, Eina_Bool is_access)
4861 Eina_Bool done = EINA_FALSE;
4863 EINA_INLIST_FOREACH(sd->blocks, itb)
4871 EINA_LIST_FOREACH(itb->items, l, it)
4873 if (!it->realized) continue;
4874 if (is_access) _access_widget_item_register(it);
4876 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
4879 else if (done) break;
4884 _elm_genlist_smart_access(Evas_Object *obj, Eina_Bool is_access)
4886 ELM_GENLIST_CHECK(obj);
4887 ELM_GENLIST_DATA_GET(obj, sd);
4890 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
4891 _elm_genlist_smart_focus_next;
4893 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
4894 _access_obj_process(sd, is_access);
4898 _elm_genlist_smart_set_user(Elm_Genlist_Smart_Class *sc)
4900 ELM_WIDGET_CLASS(sc)->base.add = _elm_genlist_smart_add;
4901 ELM_WIDGET_CLASS(sc)->base.del = _elm_genlist_smart_del;
4902 ELM_WIDGET_CLASS(sc)->base.move = _elm_genlist_smart_move;
4903 ELM_WIDGET_CLASS(sc)->base.resize = _elm_genlist_smart_resize;
4904 ELM_WIDGET_CLASS(sc)->base.member_add = _elm_genlist_smart_member_add;
4906 ELM_WIDGET_CLASS(sc)->sub_object_add = _elm_genlist_smart_sub_object_add;
4907 ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_genlist_smart_sub_object_del;
4908 ELM_WIDGET_CLASS(sc)->on_focus = _elm_genlist_smart_on_focus;
4909 ELM_WIDGET_CLASS(sc)->theme = _elm_genlist_smart_theme;
4910 ELM_WIDGET_CLASS(sc)->event = _elm_genlist_smart_event;
4911 ELM_WIDGET_CLASS(sc)->translate = _elm_genlist_smart_translate;
4913 /* not a 'focus chain manager' */
4914 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
4915 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
4917 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_genlist_smart_sizing_eval;
4920 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
4921 ELM_WIDGET_CLASS(sc)->focus_next = _elm_genlist_smart_focus_next;
4923 ELM_WIDGET_CLASS(sc)->access = _elm_genlist_smart_access;
4926 EAPI const Elm_Genlist_Smart_Class *
4927 elm_genlist_smart_class_get(void)
4929 static Elm_Genlist_Smart_Class _sc =
4930 ELM_GENLIST_SMART_CLASS_INIT_NAME_VERSION(ELM_GENLIST_SMART_NAME);
4931 static const Elm_Genlist_Smart_Class *class = NULL;
4932 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
4937 _elm_genlist_smart_set(&_sc);
4938 esc->callbacks = _smart_callbacks;
4945 elm_genlist_add(Evas_Object *parent)
4949 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
4951 obj = elm_widget_add(_elm_genlist_smart_class_new(), parent);
4952 if (!obj) return NULL;
4954 if (!elm_widget_sub_object_add(parent, obj))
4955 ERR("could not add %p as sub object of %p", obj, parent);
4961 static Evas_Object *
4962 _item_content_get_hook(Elm_Gen_Item *it,
4965 Evas_Object *ret = NULL;
4966 if (it->deco_all_view)
4967 ret = edje_object_part_swallow_get(it->deco_all_view, part);
4968 else if (it->decorate_it_set)
4969 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
4971 ret = edje_object_part_swallow_get(VIEW(it), part);
4976 _item_text_get_hook(Elm_Gen_Item *it,
4979 if (!it->itc->func.text_get) return NULL;
4980 const char *ret = NULL;
4981 if (it->deco_all_view)
4982 ret = edje_object_part_text_get(it->deco_all_view, part);
4983 else if (it->decorate_it_set)
4984 ret = edje_object_part_text_get(it->item->deco_it_view, part);
4986 ret = edje_object_part_text_get(VIEW(it), part);
4991 _item_disable_hook(Elm_Object_Item *item)
4995 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4998 elm_genlist_item_selected_set(item, EINA_FALSE);
5002 if (elm_widget_item_disabled_get(it))
5004 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
5005 if (it->deco_all_view)
5006 edje_object_signal_emit
5007 (it->deco_all_view, "elm,state,disabled", "elm");
5011 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
5012 if (it->deco_all_view)
5013 edje_object_signal_emit
5014 (it->deco_all_view, "elm,state,enabled", "elm");
5016 EINA_LIST_FOREACH(it->content_objs, l, obj)
5017 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(it));
5022 _item_free(Elm_Gen_Item *it)
5024 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5026 #if GENLIST_FX_SUPPORT
5027 if (sd->fx_mode) GL_IT(it)->has_proxy_it = EINA_FALSE;
5028 _elm_genlist_proxy_item_del((Elm_Object_Item *)it);
5029 if ((!sd->fx_mode) || (sd->genlist_clearing))
5032 _item_free_common(it);
5034 _item_unrealize(it, EINA_FALSE);
5035 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
5038 if (sd->calc_job) ecore_job_del(sd->calc_job);
5039 sd->calc_job = ecore_job_add(_calc_job, sd);
5042 #if GENLIST_FX_SUPPORT
5044 _item_del_pre_fx_process(Elm_Gen_Item *it)
5046 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5048 sd->fx_items_deleted = EINA_TRUE;
5049 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5050 if (!eina_list_data_find(sd->pending_del_items, it))
5051 sd->pending_del_items = eina_list_append(sd->pending_del_items, it);
5053 _item_free_common(it);
5059 _item_del_pre_hook(Elm_Object_Item *item)
5061 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5063 #if GENLIST_FX_SUPPORT
5064 if ((GL_IT(it)->wsd->fx_mode) && (!GL_IT(it)->wsd->genlist_clearing))
5066 _item_del_pre_fx_process(it);
5075 _item_signal_emit_hook(Elm_Object_Item *it,
5076 const char *emission,
5079 edje_object_signal_emit(VIEW(it), emission, source);
5082 static Elm_Gen_Item *
5083 _elm_genlist_item_new(Elm_Genlist_Smart_Data *sd,
5084 const Elm_Genlist_Item_Class *itc,
5086 Elm_Gen_Item *parent,
5087 Elm_Genlist_Item_Type type,
5089 const void *func_data)
5091 Elm_Gen_Item *it, *it2;
5094 if (!itc) return NULL;
5096 it = elm_widget_item_new(ELM_WIDGET_DATA(sd)->obj, Elm_Gen_Item);
5097 if (!it) return NULL;
5100 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
5102 it->base.data = data;
5103 it->parent = parent;
5104 it->func.func = func;
5105 it->func.data = func_data;
5107 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
5108 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
5109 elm_widget_item_disable_hook_set(it, _item_disable_hook);
5110 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
5111 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
5113 #if 0 // FIXME: difference from upstream
5114 it->can_focus = EINA_TRUE;
5116 //it->del_cb = (Ecore_Cb)_item_free;
5117 //it->highlight_cb = (Ecore_Cb)_item_highlight;
5118 //it->unhighlight_cb = (Ecore_Cb)_item_unhighlight;
5119 //it->sel_cb = (Ecore_Cb)_item_select;
5120 //it->unsel_cb = (Ecore_Cb)_item_unselect;
5121 //it->unrealize_cb = (Ecore_Cb)_item_unrealize_cb;
5123 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
5124 GL_IT(it)->wsd = sd;
5125 GL_IT(it)->type = type;
5126 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
5130 if (it->parent->group)
5131 GL_IT(it)->group_item = parent;
5132 else if (GL_IT(it->parent)->group_item)
5133 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
5135 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
5137 if (!it2->parent->group) depth += 1;
5139 GL_IT(it)->expanded_depth = depth;
5142 #if GENLIST_FX_SUPPORT
5143 it->item->num = sd->item_count;
5146 sd->fx_items_deleted = EINA_FALSE;
5147 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5154 _elm_genlist_item_compare(const void *data,
5157 const Elm_Gen_Item *it, *item1;
5159 it = ELM_GEN_ITEM_FROM_INLIST(data);
5160 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
5161 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5165 _elm_genlist_item_list_compare(const void *data,
5168 const Elm_Gen_Item *it = data;
5169 const Elm_Gen_Item *item1 = data1;
5171 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5175 elm_genlist_items_count(const Evas_Object *obj)
5177 ELM_GENLIST_CHECK(obj) 0;
5178 ELM_GENLIST_DATA_GET(obj, sd);
5180 return sd->item_count;
5183 EAPI Elm_Object_Item *
5184 elm_genlist_item_append(Evas_Object *obj,
5185 const Elm_Genlist_Item_Class *itc,
5187 Elm_Object_Item *parent,
5188 Elm_Genlist_Item_Type type,
5190 const void *func_data)
5194 ELM_GENLIST_CHECK(obj) NULL;
5195 ELM_GENLIST_DATA_GET(obj, sd);
5197 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(((Elm_Widget_Item *)parent),NULL);
5199 it = _elm_genlist_item_new
5200 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5201 if (!it) return NULL;
5206 sd->group_items = eina_list_append(sd->group_items, it);
5207 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
5208 it->item->rel = NULL;
5212 Elm_Gen_Item *it2 = NULL;
5213 Eina_List *ll = eina_list_last(it->parent->item->items);
5215 if (ll) it2 = ll->data;
5216 it->parent->item->items =
5217 eina_list_append(it->parent->item->items, it);
5218 if (!it2) it2 = it->parent;
5219 sd->items = eina_inlist_append_relative
5220 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5221 it->item->rel = it2;
5222 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5224 it->item->before = EINA_FALSE;
5225 _item_queue(sd, it, NULL);
5227 return (Elm_Object_Item *)it;
5230 EAPI Elm_Object_Item *
5231 elm_genlist_item_prepend(Evas_Object *obj,
5232 const Elm_Genlist_Item_Class *itc,
5234 Elm_Object_Item *parent,
5235 Elm_Genlist_Item_Type type,
5237 const void *func_data)
5241 ELM_GENLIST_CHECK(obj) NULL;
5242 ELM_GENLIST_DATA_GET(obj, sd);
5243 it = _elm_genlist_item_new
5244 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5245 if (!it) return NULL;
5250 sd->group_items = eina_list_prepend(sd->group_items, it);
5251 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
5252 it->item->rel = NULL;
5256 Elm_Gen_Item *it2 = NULL;
5257 Eina_List *ll = it->parent->item->items;
5259 if (ll) it2 = ll->data;
5260 it->parent->item->items =
5261 eina_list_prepend(it->parent->item->items, it);
5262 if (!it2) it2 = it->parent;
5263 sd->items = eina_inlist_prepend_relative
5264 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5265 it->item->rel = it2;
5266 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5268 it->item->before = EINA_TRUE;
5269 _item_queue(sd, it, NULL);
5271 return (Elm_Object_Item *)it;
5274 EAPI Elm_Object_Item *
5275 elm_genlist_item_insert_after(Evas_Object *obj,
5276 const Elm_Genlist_Item_Class *itc,
5278 Elm_Object_Item *parent,
5279 Elm_Object_Item *after_it,
5280 Elm_Genlist_Item_Type type,
5282 const void *func_data)
5284 Elm_Gen_Item *after = (Elm_Gen_Item *)after_it;
5287 ELM_GENLIST_CHECK(obj) NULL;
5288 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
5289 ELM_GENLIST_DATA_GET(obj, sd);
5291 /* It makes no sense to insert after in an empty list with after !=
5292 * NULL, something really bad is happening in your app. */
5293 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5295 it = _elm_genlist_item_new
5296 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5297 if (!it) return NULL;
5301 if ((it->group) && (after->group))
5302 sd->group_items = eina_list_append_relative
5303 (sd->group_items, it, after);
5307 it->parent->item->items =
5308 eina_list_append_relative(it->parent->item->items, it, after);
5310 sd->items = eina_inlist_append_relative
5311 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5313 it->item->rel = after;
5314 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5315 it->item->before = EINA_FALSE;
5316 _item_queue(sd, it, NULL);
5318 return (Elm_Object_Item *)it;
5321 EAPI Elm_Object_Item *
5322 elm_genlist_item_insert_before(Evas_Object *obj,
5323 const Elm_Genlist_Item_Class *itc,
5325 Elm_Object_Item *parent,
5326 Elm_Object_Item *before_it,
5327 Elm_Genlist_Item_Type type,
5329 const void *func_data)
5331 Elm_Gen_Item *before = (Elm_Gen_Item *)before_it;
5334 ELM_GENLIST_CHECK(obj) NULL;
5335 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
5336 ELM_GENLIST_DATA_GET(obj, sd);
5338 /* It makes no sense to insert before in an empty list with before
5339 * != NULL, something really bad is happening in your app. */
5340 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5342 it = _elm_genlist_item_new
5343 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5344 if (!it) return NULL;
5348 if (it->group && before->group)
5350 eina_list_prepend_relative(sd->group_items, it, before);
5354 it->parent->item->items =
5355 eina_list_prepend_relative(it->parent->item->items, it, before);
5357 sd->items = eina_inlist_prepend_relative
5358 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5360 it->item->rel = before;
5361 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5362 it->item->before = EINA_TRUE;
5363 _item_queue(sd, it, NULL);
5365 return (Elm_Object_Item *)it;
5368 EAPI Elm_Object_Item *
5369 elm_genlist_item_sorted_insert(Evas_Object *obj,
5370 const Elm_Genlist_Item_Class *itc,
5372 Elm_Object_Item *parent,
5373 Elm_Genlist_Item_Type type,
5374 Eina_Compare_Cb comp,
5376 const void *func_data)
5378 Elm_Gen_Item *rel = NULL;
5381 ELM_GENLIST_CHECK(obj) NULL;
5382 ELM_GENLIST_DATA_GET(obj, sd);
5384 it = _elm_genlist_item_new
5385 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5386 if (!it) return NULL;
5388 sd->item_compare_cb = comp;
5395 l = eina_list_search_sorted_near_list
5396 (it->parent->item->items, _elm_genlist_item_list_compare, it,
5400 rel = eina_list_data_get(l);
5404 if (cmp_result >= 0)
5406 it->parent->item->items = eina_list_prepend_relative_list
5407 (it->parent->item->items, it, l);
5408 sd->items = eina_inlist_prepend_relative
5409 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5410 it->item->before = EINA_FALSE;
5412 else if (cmp_result < 0)
5414 it->parent->item->items = eina_list_append_relative_list
5415 (it->parent->item->items, it, l);
5416 sd->items = eina_inlist_append_relative
5417 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5418 it->item->before = EINA_TRUE;
5425 sd->state = eina_inlist_sorted_state_new();
5426 eina_inlist_sorted_state_init(sd->state, sd->items);
5427 sd->requeued = EINA_FALSE;
5431 sd->group_items = eina_list_append(sd->group_items, it);
5433 sd->items = eina_inlist_sorted_state_insert
5434 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
5437 if (EINA_INLIST_GET(it)->next)
5439 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5440 it->item->before = EINA_TRUE;
5442 else if (EINA_INLIST_GET(it)->prev)
5444 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5445 it->item->before = EINA_FALSE;
5451 it->item->rel = rel;
5452 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
5455 _item_queue(sd, it, _elm_genlist_item_list_compare);
5457 return (Elm_Object_Item *)it;
5461 _elm_genlist_fx_clear(Evas_Object *obj)
5463 ELM_GENLIST_DATA_GET(obj, sd);
5465 Elm_Gen_FX_Item *fi;
5469 EINA_LIST_FREE(sd->capture_before_items, pi)
5471 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
5472 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
5473 if (pi->proxy) evas_object_del(pi->proxy);
5476 EINA_LIST_FREE(sd->capture_after_items, pi)
5478 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
5479 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
5480 if (pi->proxy) evas_object_del(pi->proxy);
5484 EINA_LIST_FREE(sd->fx_items, fi)
5486 if (fi->trans) elm_transit_del(fi->trans);
5490 EINA_LIST_FREE (sd->pending_unrealized_items, it)
5491 _item_unrealize(it, EINA_FALSE);
5493 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
5494 _decorate_all_item_unrealize(it);
5496 EINA_LIST_FREE (sd->pending_del_items, it)
5499 _elm_widget_item_free((Elm_Widget_Item *)it);
5501 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5502 sd->alpha_bg = NULL;
5503 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
5504 sd->fx_timer = NULL;
5506 sd->genlist_clearing = EINA_TRUE;
5507 sd->fx_playing = EINA_FALSE;
5508 sd->sorting = EINA_FALSE;
5509 sd->fx_first_captured = EINA_FALSE;
5510 sd->fx_items_deleted = EINA_FALSE;
5514 elm_genlist_clear(Evas_Object *obj)
5516 ELM_GENLIST_CHECK(obj);
5517 ELM_GENLIST_DATA_GET(obj, sd);
5522 eina_inlist_sorted_state_free(sd->state);
5526 #if GENLIST_FX_SUPPORT
5529 _elm_genlist_fx_clear(obj);
5530 sd->genlist_clearing = EINA_TRUE;
5531 sd->rendered = EINA_FALSE;
5534 #if GENLIST_PINCH_ZOOM_SUPPORT
5535 sd->pinch_zoom_h = 0;
5536 sd->realized_top_item = NULL;
5537 sd->pinch_zoom_mode = ELM_GEN_PINCH_ZOOM_NONE;
5540 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5542 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
5543 // because sd->items can be modified inside elm_widget_item_del()
5546 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
5547 it->item->nocache_once = EINA_TRUE;
5548 elm_widget_item_del(it);
5552 _item_cache_all_free(sd);
5554 sd->pan_changed = EINA_TRUE;
5555 if (sd->selected) sd->selected = eina_list_free(sd->selected);
5556 sd->selected = NULL;
5558 sd->anchor_item = NULL;
5559 if (sd->multi_timer)
5561 ecore_timer_del(sd->multi_timer);
5562 sd->multi_timer = NULL;
5566 ecore_job_del(sd->update_job);
5567 sd->update_job = NULL;
5571 ecore_job_del(sd->calc_job);
5572 sd->calc_job = NULL;
5574 if (sd->queue_idle_enterer)
5576 ecore_idle_enterer_del(sd->queue_idle_enterer);
5577 sd->queue_idle_enterer = NULL;
5579 if (sd->must_recalc_idler)
5581 ecore_idler_del(sd->must_recalc_idler);
5582 sd->must_recalc_idler = NULL;
5584 if (sd->queue) sd->queue = eina_list_free(sd->queue);
5585 if (sd->reorder_move_animator)
5587 ecore_animator_del(sd->reorder_move_animator);
5588 sd->reorder_move_animator = NULL;
5590 sd->show_item = NULL;
5591 sd->reorder_old_pan_y = 0;
5598 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5599 sd->alpha_bg = NULL;
5603 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
5604 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
5606 elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
5607 sd->s_iface->content_region_show(obj, 0, 0, 0, 0);
5609 #if GENLIST_FX_SUPPORT
5610 sd->genlist_clearing = EINA_FALSE;
5612 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5613 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5617 elm_genlist_multi_select_set(Evas_Object *obj,
5620 ELM_GENLIST_CHECK(obj);
5621 ELM_GENLIST_DATA_GET(obj, sd);
5623 sd->multi = !!multi;
5627 elm_genlist_multi_select_get(const Evas_Object *obj)
5629 ELM_GENLIST_CHECK(obj) EINA_FALSE;
5630 ELM_GENLIST_DATA_GET(obj, sd);
5635 EAPI Elm_Object_Item *
5636 elm_genlist_selected_item_get(const Evas_Object *obj)
5638 ELM_GENLIST_CHECK(obj) NULL;
5639 ELM_GENLIST_DATA_GET(obj, sd);
5642 return sd->selected->data;
5648 elm_genlist_selected_items_get(const Evas_Object *obj)
5650 ELM_GENLIST_CHECK(obj) NULL;
5651 ELM_GENLIST_DATA_GET(obj, sd);
5653 return sd->selected;
5657 elm_genlist_realized_items_get(const Evas_Object *obj)
5660 Eina_List *list = NULL;
5661 Eina_Bool done = EINA_FALSE;
5663 ELM_GENLIST_CHECK(obj) NULL;
5664 ELM_GENLIST_DATA_GET(obj, sd);
5666 EINA_INLIST_FOREACH(sd->blocks, itb)
5674 EINA_LIST_FOREACH(itb->items, l, it)
5676 if (it->realized) list = eina_list_append(list, it);
5687 EAPI Elm_Object_Item *
5688 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5693 Evas_Coord ox, oy, ow, oh;
5697 ELM_GENLIST_CHECK(obj) NULL;
5698 ELM_GENLIST_DATA_GET(obj, sd);
5700 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
5702 EINA_INLIST_FOREACH(sd->blocks, itb)
5707 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
5708 oy + itb->y - itb->sd->pan_y,
5709 itb->w, itb->h, x, y, 1, 1))
5711 EINA_LIST_FOREACH(itb->items, l, it)
5713 Evas_Coord itx, ity;
5715 itx = ox + itb->x + it->x - itb->sd->pan_x;
5716 ity = oy + itb->y + it->y - itb->sd->pan_y;
5717 if (ELM_RECTS_INTERSECT
5718 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5722 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5723 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5728 return (Elm_Object_Item *)it;
5730 lasty = ity + it->item->h;
5735 if (y > lasty) *posret = 1;
5742 EAPI Elm_Object_Item *
5743 elm_genlist_first_item_get(const Evas_Object *obj)
5745 Elm_Gen_Item *tit, *it = NULL;
5747 ELM_GENLIST_CHECK(obj) NULL;
5748 ELM_GENLIST_DATA_GET(obj, sd);
5750 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
5752 return (Elm_Object_Item *)it;
5755 EAPI Elm_Object_Item *
5756 elm_genlist_last_item_get(const Evas_Object *obj)
5760 ELM_GENLIST_CHECK(obj) NULL;
5761 ELM_GENLIST_DATA_GET(obj, sd);
5762 if (!sd->items) return NULL;
5764 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
5765 return (Elm_Object_Item *)it;
5768 EAPI Elm_Object_Item *
5769 elm_genlist_item_next_get(const Elm_Object_Item *item)
5773 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
5775 it = (Elm_Gen_Item *)item;
5778 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5782 return (Elm_Object_Item *)it;
5785 EAPI Elm_Object_Item *
5786 elm_genlist_item_prev_get(const Elm_Object_Item *item)
5790 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
5792 it = (Elm_Gen_Item *)item;
5795 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5799 return (Elm_Object_Item *)it;
5802 EAPI Elm_Object_Item *
5803 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5805 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
5807 return (Elm_Object_Item *)((Elm_Gen_Item *)it)->parent;
5811 elm_genlist_item_subitems_clear(Elm_Object_Item *item)
5813 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5815 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5816 _item_sub_items_clear(it);
5820 elm_genlist_item_selected_set(Elm_Object_Item *item,
5823 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5824 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5826 if (elm_widget_item_disabled_get(it)) return;
5827 selected = !!selected;
5828 if (it->selected == selected) return;
5830 _item_select_unselect(it, selected);
5834 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5836 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5838 return ((Elm_Gen_Item *)it)->selected;
5841 static Elm_Gen_Item *
5842 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5846 if (it->item->expanded)
5848 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
5852 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
5855 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5856 it2 = (Elm_Gen_Item *)
5857 elm_genlist_item_next_get((Elm_Object_Item *)it2);
5863 static Evas_Object *
5864 _tray_alpha_bg_create(const Evas_Object *obj)
5866 Evas_Object *bg = NULL;
5867 Evas_Coord ox, oy, ow, oh;
5869 ELM_GENLIST_CHECK(obj) NULL;
5870 ELM_GENLIST_DATA_GET(obj, sd);
5872 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
5873 bg = evas_object_rectangle_add
5874 (evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5875 evas_object_color_set(bg, 0, 0, 0, 0);
5876 evas_object_resize(bg, ow, oh);
5877 evas_object_move(bg, ox, oy);
5883 elm_genlist_item_expanded_set(Elm_Object_Item *item,
5886 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5888 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5890 expanded = !!expanded;
5891 if (it->item->expanded == expanded) return;
5892 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
5893 it->item->expanded = expanded;
5894 GL_IT(it)->wsd->expanded_item = it;
5895 GL_IT(it)->wsd->expanded_next_item =
5896 _elm_genlist_expanded_next_item_get(it);
5898 if (it->item->expanded)
5901 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
5902 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
5903 GL_IT(it)->wsd->auto_scroll_enabled = EINA_TRUE;
5908 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
5909 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
5910 GL_IT(it)->wsd->auto_scroll_enabled = EINA_FALSE;
5915 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5917 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5919 return ((Elm_Gen_Item *)it)->item->expanded;
5923 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5925 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
5927 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5931 _elm_genlist_item_coordinates_calc(Elm_Object_Item *item,
5932 Elm_Genlist_Item_Scrollto_Type type,
5939 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5940 Evas_Coord gith = 0;
5942 if (!((GL_IT(it)->wsd->homogeneous) &&
5943 (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)))
5945 if ((it->item->queued) || (!it->item->mincalcd))
5947 GL_IT(it)->wsd->show_item = it;
5948 GL_IT(it)->wsd->bring_in = bring_in;
5949 GL_IT(it)->wsd->scroll_to_type = type;
5950 it->item->show_me = EINA_TRUE;
5954 if (GL_IT(it)->wsd->show_item)
5956 GL_IT(it)->wsd->show_item->item->show_me = EINA_FALSE;
5957 GL_IT(it)->wsd->show_item = NULL;
5960 evas_object_geometry_get(GL_IT(it)->wsd->pan_obj, NULL, NULL, w, h);
5963 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5964 if ((it->item->group_item) &&
5965 (GL_IT(it)->wsd->pan_y > (it->y + it->item->block->y)))
5966 gith = it->item->group_item->item->h;
5968 *y = it->y + it->item->block->y - gith;
5971 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5972 if (it->item->group_item) gith = it->item->group_item->item->h;
5973 *y = it->y + it->item->block->y - gith;
5976 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5977 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
5984 *x = it->x + it->item->block->x;
5985 *w = it->item->block->w;
5991 elm_genlist_item_promote(Elm_Object_Item *item)
5993 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5994 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5996 (it, (Elm_Gen_Item *)elm_genlist_first_item_get(WIDGET(it)));
6000 elm_genlist_item_demote(Elm_Object_Item *item)
6002 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6003 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6004 _item_move_after(it, (Elm_Gen_Item *)elm_genlist_last_item_get(WIDGET(it)));
6008 elm_genlist_item_show(Elm_Object_Item *item,
6009 Elm_Genlist_Item_Scrollto_Type type)
6011 Evas_Coord x, y, w, h;
6012 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6013 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6015 if (_elm_genlist_item_coordinates_calc
6016 (item, type, EINA_FALSE, &x, &y, &w, &h))
6017 GL_IT(it)->wsd->s_iface->content_region_show(WIDGET(item), x, y, w, h);
6021 elm_genlist_item_bring_in(Elm_Object_Item *item,
6022 Elm_Genlist_Item_Scrollto_Type type)
6024 Evas_Coord x, y, w, h;
6025 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6026 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6028 if (_elm_genlist_item_coordinates_calc
6029 (item, type, EINA_TRUE, &x, &y, &w, &h))
6030 GL_IT(it)->wsd->s_iface->region_bring_in(WIDGET(item), x, y, w, h);
6034 elm_genlist_item_all_contents_unset(Elm_Object_Item *item,
6037 Evas_Object *content;
6039 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6040 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6042 EINA_LIST_FREE (it->content_objs, content)
6044 evas_object_smart_member_del(content);
6045 evas_object_hide(content);
6046 if (l) *l = eina_list_append(*l, content);
6051 elm_genlist_item_update(Elm_Object_Item *item)
6053 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6054 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6056 if (!it->item->block) return;
6057 it->item->mincalcd = EINA_FALSE;
6058 it->item->updateme = EINA_TRUE;
6059 it->item->block->updateme = EINA_TRUE;
6060 #if GENLIST_ENTRY_SUPPORT
6061 it->item->unrealize_disabled = EINA_FALSE;
6064 #if GENLIST_FX_SUPPORT
6065 if (GL_IT(it)->wsd->fx_first_captured)
6066 _elm_genlist_fx_clear(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj);
6069 if (GL_IT(it)->wsd->update_job) ecore_job_del(GL_IT(it)->wsd->update_job);
6070 GL_IT(it)->wsd->update_job = ecore_job_add(_update_job, GL_IT(it)->wsd);
6074 elm_genlist_item_fields_update(Elm_Object_Item *item,
6076 Elm_Genlist_Item_Field_Type itf)
6078 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6079 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6081 if (!it->item->block) return;
6083 #if GENLIST_ENTRY_SUPPORT
6084 it->item->unrealize_disabled = EINA_FALSE;
6086 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
6088 _item_text_realize(it, VIEW(it), &it->texts, parts);
6090 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
6092 it->content_objs = _item_content_unrealize(it, VIEW(it),
6093 &it->contents, parts);
6094 it->content_objs = _item_content_realize(it, VIEW(it),
6095 &it->contents, parts);
6099 it->item->flip_content_objs =
6100 _item_mode_content_unrealize(it, VIEW(it),
6101 &it->item->flip_contents, parts,
6102 &it->item->flip_content_objs);
6103 it->item->flip_content_objs =
6104 _item_mode_content_realize(it, VIEW(it),
6105 &it->item->flip_contents, parts,
6106 &it->item->flip_content_objs);
6108 if (it->item->deco_it_view)
6110 it->item->deco_it_content_objs =
6111 _item_mode_content_unrealize(it, it->item->deco_it_view,
6112 &it->item->deco_it_contents, parts,
6113 &it->item->deco_it_content_objs);
6114 it->item->deco_it_content_objs =
6115 _item_mode_content_realize(it, it->item->deco_it_view,
6116 &it->item->deco_it_contents, parts,
6117 &it->item->deco_it_content_objs);
6119 if (GL_IT(it)->wsd->decorate_all_mode)
6121 it->item->deco_all_content_objs =
6122 _item_mode_content_unrealize
6123 (it, it->deco_all_view, &it->item->deco_all_contents, parts,
6124 &it->item->deco_all_content_objs);
6125 it->item->deco_all_content_objs =
6126 _item_mode_content_realize(it, it->deco_all_view,
6127 &it->item->deco_all_contents, parts,
6128 &it->item->deco_all_content_objs);
6132 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
6133 _item_state_realize(it, VIEW(it), &it->states, parts);
6137 elm_genlist_item_item_class_update(Elm_Object_Item *item,
6138 const Elm_Genlist_Item_Class *itc)
6140 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6141 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6143 if (!it->item->block) return;
6144 EINA_SAFETY_ON_NULL_RETURN(itc);
6146 it->item->nocache_once = EINA_TRUE;
6148 elm_widget_stringlist_free(it->texts);
6150 elm_widget_stringlist_free(it->contents);
6151 it->contents = NULL;
6152 elm_widget_stringlist_free(it->states);
6157 elm_widget_stringlist_free(it->item->flip_contents);
6158 it->item->flip_contents = NULL;
6160 if (it->item->deco_it_view)
6162 elm_widget_stringlist_free(it->item->deco_it_texts);
6163 it->item->deco_it_texts = NULL;
6164 elm_widget_stringlist_free(it->item->deco_it_contents);
6165 it->item->deco_it_contents = NULL;
6167 if (GL_IT(it)->wsd->decorate_all_mode)
6169 elm_widget_stringlist_free(it->item->deco_all_texts);
6170 it->item->deco_all_texts = NULL;
6171 elm_widget_stringlist_free(it->item->deco_all_contents);
6172 it->item->deco_all_contents = NULL;
6175 elm_genlist_item_update(item);
6178 EAPI const Elm_Genlist_Item_Class *
6179 elm_genlist_item_item_class_get(const Elm_Object_Item *item)
6181 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6182 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6186 static Evas_Object *
6187 _elm_genlist_item_label_create(void *data,
6188 Evas_Object *obj __UNUSED__,
6189 Evas_Object *tooltip,
6190 void *it __UNUSED__)
6192 Evas_Object *label = elm_label_add(tooltip);
6197 elm_object_style_set(label, "tooltip");
6198 elm_object_text_set(label, data);
6204 _elm_genlist_item_label_del_cb(void *data,
6205 Evas_Object *obj __UNUSED__,
6206 void *event_info __UNUSED__)
6208 eina_stringshare_del(data);
6212 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
6215 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6217 text = eina_stringshare_add(text);
6218 elm_genlist_item_tooltip_content_cb_set
6219 (it, _elm_genlist_item_label_create, text,
6220 _elm_genlist_item_label_del_cb);
6224 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
6225 Elm_Tooltip_Item_Content_Cb func,
6227 Evas_Smart_Cb del_cb)
6229 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6231 ELM_GENLIST_ITEM_CHECK_OR_GOTO(item, error);
6233 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
6236 if (it->tooltip.del_cb)
6237 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6239 it->tooltip.content_cb = func;
6240 it->tooltip.data = data;
6241 it->tooltip.del_cb = del_cb;
6245 elm_widget_item_tooltip_content_cb_set
6246 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
6247 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
6248 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
6254 if (del_cb) del_cb((void *)data, NULL, NULL);
6258 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
6260 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6262 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6264 if ((VIEW(it)) && (it->tooltip.content_cb))
6265 elm_widget_item_tooltip_unset(it);
6267 if (it->tooltip.del_cb)
6268 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6269 it->tooltip.del_cb = NULL;
6270 it->tooltip.content_cb = NULL;
6271 it->tooltip.data = NULL;
6272 it->tooltip.free_size = EINA_FALSE;
6273 if (it->tooltip.style)
6274 elm_genlist_item_tooltip_style_set(item, NULL);
6278 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
6281 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6283 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6285 eina_stringshare_replace(&it->tooltip.style, style);
6286 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
6290 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
6292 return elm_object_item_tooltip_style_get(it);
6296 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
6299 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6301 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
6303 it->tooltip.free_size = disable;
6304 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
6310 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
6312 return elm_object_tooltip_window_mode_get(VIEW(it));
6316 elm_genlist_item_cursor_set(Elm_Object_Item *item,
6319 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6321 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6322 eina_stringshare_replace(&it->mouse_cursor, cursor);
6323 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
6327 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
6329 return elm_widget_item_cursor_get(it);
6333 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
6335 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6337 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6339 if (!it->mouse_cursor) return;
6341 if (VIEW(it)) elm_widget_item_cursor_unset(it);
6343 eina_stringshare_del(it->mouse_cursor);
6344 it->mouse_cursor = NULL;
6348 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
6351 elm_widget_item_cursor_style_set(it, style);
6355 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
6357 return elm_widget_item_cursor_style_get(it);
6361 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
6362 Eina_Bool engine_only)
6364 elm_widget_item_cursor_engine_only_set(it, engine_only);
6368 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
6370 return elm_widget_item_cursor_engine_only_get(it);
6374 elm_genlist_item_index_get(const Elm_Object_Item *item)
6378 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6380 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, -1);
6382 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
6384 if (tmp == it) break;
6391 elm_genlist_mode_set(Evas_Object *obj,
6394 ELM_GENLIST_CHECK(obj);
6395 ELM_GENLIST_DATA_GET(obj, sd);
6397 if (sd->mode == mode) return;
6399 elm_layout_sizing_eval(obj);
6403 elm_genlist_mode_get(const Evas_Object *obj)
6405 ELM_GENLIST_CHECK(obj) ELM_LIST_LAST;
6406 ELM_GENLIST_DATA_GET(obj, sd);
6412 elm_genlist_bounce_set(Evas_Object *obj,
6416 ELM_GENLIST_CHECK(obj);
6417 ELM_GENLIST_DATA_GET(obj, sd);
6419 sd->h_bounce = !!h_bounce;
6420 sd->v_bounce = !!v_bounce;
6421 sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
6425 elm_genlist_bounce_get(const Evas_Object *obj,
6426 Eina_Bool *h_bounce,
6427 Eina_Bool *v_bounce)
6429 ELM_GENLIST_CHECK(obj);
6430 ELM_GENLIST_DATA_GET(obj, sd);
6432 if (h_bounce) *h_bounce = sd->h_bounce;
6433 if (v_bounce) *v_bounce = sd->v_bounce;
6437 elm_genlist_homogeneous_set(Evas_Object *obj,
6438 Eina_Bool homogeneous)
6440 ELM_GENLIST_CHECK(obj);
6441 ELM_GENLIST_DATA_GET(obj, sd);
6443 sd->homogeneous = !!homogeneous;
6447 elm_genlist_homogeneous_get(const Evas_Object *obj)
6449 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6450 ELM_GENLIST_DATA_GET(obj, sd);
6452 return sd->homogeneous;
6456 elm_genlist_block_count_set(Evas_Object *obj,
6459 ELM_GENLIST_CHECK(obj);
6460 ELM_GENLIST_DATA_GET(obj, sd);
6461 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
6463 sd->max_items_per_block = count;
6464 sd->item_cache_max = sd->max_items_per_block * 2;
6465 _item_cache_all_free(sd);
6469 elm_genlist_block_count_get(const Evas_Object *obj)
6471 ELM_GENLIST_CHECK(obj) 0;
6472 ELM_GENLIST_DATA_GET(obj, sd);
6474 return sd->max_items_per_block;
6478 elm_genlist_longpress_timeout_set(Evas_Object *obj,
6481 ELM_GENLIST_CHECK(obj);
6482 ELM_GENLIST_DATA_GET(obj, sd);
6484 sd->longpress_timeout = timeout;
6488 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
6490 ELM_GENLIST_CHECK(obj) 0;
6491 ELM_GENLIST_DATA_GET(obj, sd);
6493 return sd->longpress_timeout;
6497 elm_genlist_scroller_policy_set(Evas_Object *obj,
6498 Elm_Scroller_Policy policy_h,
6499 Elm_Scroller_Policy policy_v)
6501 ELM_GENLIST_CHECK(obj);
6502 ELM_GENLIST_DATA_GET(obj, sd);
6504 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
6505 (policy_v >= ELM_SCROLLER_POLICY_LAST))
6508 sd->s_iface->policy_set(obj, policy_h, policy_v);
6512 elm_genlist_scroller_policy_get(const Evas_Object *obj,
6513 Elm_Scroller_Policy *policy_h,
6514 Elm_Scroller_Policy *policy_v)
6516 Elm_Scroller_Policy s_policy_h, s_policy_v;
6518 ELM_GENLIST_CHECK(obj);
6519 ELM_GENLIST_DATA_GET(obj, sd);
6521 sd->s_iface->policy_get(obj, &s_policy_h, &s_policy_v);
6522 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
6523 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
6527 elm_genlist_realized_items_update(Evas_Object *obj)
6529 Eina_List *list, *l;
6530 Elm_Object_Item *it;
6532 ELM_GENLIST_CHECK(obj);
6534 list = elm_genlist_realized_items_get(obj);
6535 EINA_LIST_FOREACH(list, l, it)
6536 elm_genlist_item_update(it);
6540 elm_genlist_item_decorate_mode_set(Elm_Object_Item *item,
6541 const char *decorate_it_type,
6542 Eina_Bool decorate_it_set)
6544 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6545 Elm_Genlist_Smart_Data *sd;
6547 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6548 sd = GL_IT(it)->wsd;
6550 if (elm_widget_item_disabled_get(it)) return;
6551 if (!decorate_it_type) return;
6552 if (sd->decorate_all_mode) return;
6554 if ((sd->mode_item == it) &&
6555 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
6558 if (!it->itc->decorate_item_style) return;
6559 it->decorate_it_set = decorate_it_set;
6562 if (((sd->decorate_it_type)
6563 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
6564 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
6565 _decorate_item_unset(sd);
6567 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
6568 if (decorate_it_set) _decorate_item_set(it);
6572 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *item)
6574 Elm_Gen_Item *i = (Elm_Gen_Item *)item;
6576 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6577 return GL_IT(i)->wsd->decorate_it_type;
6580 EAPI Elm_Object_Item *
6581 elm_genlist_decorated_item_get(const Evas_Object *obj)
6583 ELM_GENLIST_CHECK(obj) NULL;
6584 ELM_GENLIST_DATA_GET(obj, sd);
6586 return (Elm_Object_Item *)sd->mode_item;
6590 elm_genlist_decorate_mode_get(const Evas_Object *obj)
6592 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6593 ELM_GENLIST_DATA_GET(obj, sd);
6595 return sd->decorate_all_mode;
6599 elm_genlist_decorate_mode_set(Evas_Object *obj,
6600 Eina_Bool decorated)
6603 Eina_List *list, *l;
6605 ELM_GENLIST_CHECK(obj);
6606 ELM_GENLIST_DATA_GET(obj, sd);
6608 decorated = !!decorated;
6609 if (sd->decorate_all_mode == decorated) return;
6610 // decorate_all_mode should be set first
6611 // because content_get func. will be called after this
6612 // and user can check whether deocrate_all_mode is enabeld.
6613 sd->decorate_all_mode = decorated;
6615 list = elm_genlist_realized_items_get(obj);
6616 if (!sd->decorate_all_mode)
6618 EINA_LIST_FOREACH(list, l, it)
6620 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6621 _decorate_all_item_unrealize(it);
6623 _item_cache_all_free(sd);
6627 EINA_LIST_FOREACH(list, l, it)
6629 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6631 if (it->itc->decorate_all_item_style)
6632 _decorate_all_item_realize(it, EINA_TRUE);
6636 #if GENLIST_FX_SUPPORT
6637 if (sd->fx_first_captured)
6638 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj);
6641 if (sd->calc_job) ecore_job_del(sd->calc_job);
6642 sd->calc_job = ecore_job_add(_calc_job, sd);
6646 elm_genlist_reorder_mode_set(Evas_Object *obj,
6647 Eina_Bool reorder_mode)
6649 #if 1 // FIXME: difference from upstream
6650 Eina_List *list, *l;
6653 ELM_GENLIST_CHECK(obj);
6654 ELM_GENLIST_DATA_GET(obj, sd);
6656 if (sd->reorder_mode == !!reorder_mode) return;
6657 sd->reorder_mode = !!reorder_mode;
6658 #if 1 // FIXME: difference from upstream
6659 list = elm_genlist_realized_items_get(obj);
6660 EINA_LIST_FOREACH(list, l, it)
6662 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6664 if (sd->reorder_mode)
6665 edje_object_signal_emit
6666 (VIEW(it), "elm,state,reorder,mode_set", "elm");
6668 edje_object_signal_emit
6669 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
6671 if (sd->decorate_all_mode)
6673 if (sd->reorder_mode)
6674 edje_object_signal_emit
6675 (it->deco_all_view, "elm,state,reorder,mode_set", "elm");
6677 edje_object_signal_emit
6678 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
6681 eina_list_free(list);
6686 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6688 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6689 ELM_GENLIST_DATA_GET(obj, sd);
6691 return sd->reorder_mode;
6694 EAPI Elm_Genlist_Item_Type
6695 elm_genlist_item_type_get(const Elm_Object_Item *item)
6697 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6699 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_GENLIST_ITEM_MAX);
6701 return it->item->type;
6704 EAPI Elm_Genlist_Item_Class *
6705 elm_genlist_item_class_new(void)
6707 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
6708 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6710 itc->version = CLASS_ALLOCATED;
6712 itc->delete_me = EINA_FALSE;
6718 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6720 if (itc && (itc->version == CLASS_ALLOCATED))
6722 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6723 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6733 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6735 if (itc && (itc->version == CLASS_ALLOCATED))
6738 if (itc->refcount == 0) itc->refcount--;
6743 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6745 if (itc && (itc->version == CLASS_ALLOCATED))
6747 if (itc->refcount > 0) itc->refcount--;
6748 if (itc->delete_me && (!itc->refcount))
6749 elm_genlist_item_class_free(itc);
6754 elm_genlist_item_flip_set(Elm_Object_Item *item,
6757 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6758 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6759 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
6762 if (it->flipped == flip) return;
6764 it->item->unrealize_disabled = EINA_FALSE;
6768 _item_unrealize(it, EINA_FALSE);
6769 it->flipped = EINA_TRUE;
6770 it->item->nocache = EINA_TRUE;
6774 _item_unrealize(it, EINA_FALSE);
6775 it->flipped = EINA_FALSE;
6776 it->item->nocache = EINA_FALSE;
6778 if (sd->calc_job) ecore_job_del(sd->calc_job);
6779 sd->calc_job = ecore_job_add(_calc_job, sd);
6783 elm_genlist_item_flip_get(const Elm_Object_Item *item)
6785 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6787 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
6793 elm_genlist_select_mode_set(Evas_Object *obj,
6794 Elm_Object_Select_Mode mode)
6796 ELM_GENLIST_CHECK(obj);
6797 ELM_GENLIST_DATA_GET(obj, sd);
6799 if (mode >= ELM_OBJECT_SELECT_MODE_MAX || (sd->select_mode == mode))
6802 sd->select_mode = mode;
6803 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
6804 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
6808 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it)
6813 EAPI Elm_Object_Select_Mode
6814 elm_genlist_select_mode_get(const Evas_Object *obj)
6816 ELM_GENLIST_CHECK(obj) ELM_OBJECT_SELECT_MODE_MAX;
6817 ELM_GENLIST_DATA_GET(obj, sd);
6819 return sd->select_mode;
6823 elm_genlist_highlight_mode_set(Evas_Object *obj,
6824 Eina_Bool highlight)
6826 ELM_GENLIST_CHECK(obj);
6827 ELM_GENLIST_DATA_GET(obj, sd);
6829 sd->highlight = !!highlight;
6833 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6835 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6836 ELM_GENLIST_DATA_GET(obj, sd);
6838 return sd->highlight;
6842 elm_genlist_item_select_mode_set(Elm_Object_Item *item,
6843 Elm_Object_Select_Mode mode)
6845 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6847 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6849 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6851 if (it->select_mode != mode)
6852 it->select_mode = mode;
6854 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
6855 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
6858 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6860 it->item->mincalcd = EINA_FALSE;
6861 it->item->updateme = EINA_TRUE;
6862 if (it->item->block) it->item->block->updateme = EINA_TRUE;
6863 if (GL_IT(it)->wsd->update_job)
6864 ecore_job_del(GL_IT(it)->wsd->update_job);
6865 GL_IT(it)->wsd->update_job =
6866 ecore_job_add(_update_job, GL_IT(it)->wsd);
6868 // reset homogeneous item size
6869 if (GL_IT(it)->wsd->homogeneous)
6872 GL_IT(it)->wsd->group_item_width =
6873 GL_IT(it)->wsd->group_item_height = 0;
6875 GL_IT(it)->wsd->item_width = GL_IT(it)->wsd->item_height = 0;
6880 EAPI Elm_Object_Select_Mode
6881 elm_genlist_item_select_mode_get(const Elm_Object_Item *item)
6883 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6885 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_OBJECT_SELECT_MODE_MAX);
6887 if (!it) return ELM_OBJECT_SELECT_MODE_MAX;
6889 return it->select_mode;
6892 // will be deprecated
6894 elm_genlist_tree_effect_enabled_set(Evas_Object *obj __UNUSED__,
6895 Eina_Bool enabled __UNUSED__)
6897 ELM_GENLIST_CHECK(obj);
6900 // will be deprecated
6902 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj __UNUSED__)
6904 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6909 EAPI Elm_Object_Item *
6910 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
6912 Elm_Gen_Item *it = NULL;
6916 ELM_GENLIST_CHECK(obj) NULL;
6917 ELM_GENLIST_DATA_GET(obj, sd);
6919 if (!sd->items) return NULL;
6921 a = eina_inlist_accessor_new(sd->items);
6922 if (!a) return NULL;
6923 if (eina_accessor_data_get(a, nth, &data))
6924 it = ELM_GEN_ITEM_FROM_INLIST(data);
6925 eina_accessor_free(a);
6926 return (Elm_Object_Item *)it;
6929 #if GENLIST_FX_SUPPORT
6931 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
6933 ELM_GENLIST_CHECK(obj);
6934 ELM_GENLIST_DATA_GET(obj, sd);
6940 elm_genlist_fx_mode_get(const Evas_Object *obj)
6942 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6943 ELM_GENLIST_DATA_GET(obj, sd);
6949 _elm_genlist_proxy_item_del(const Elm_Object_Item *item)
6951 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6952 if ((!it) || (!it->item)) return;
6954 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
6958 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
6959 if (pi->it == it) pi->it = NULL;
6961 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
6962 if (pi->it == it) pi->it = NULL;
6966 _elm_genlist_proxy_item_new(const Elm_Object_Item *item)
6968 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6969 if ((!it) || (!it->item)) return EINA_FALSE;
6972 Proxy_Item *pi = NULL;
6973 pi = calloc(1, sizeof(Proxy_Item));
6974 if (!pi) return NULL;
6976 pi->proxy = evas_object_image_filled_add
6977 (evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
6978 if (!pi->proxy) return EINA_FALSE;
6979 evas_object_clip_set(pi->proxy, evas_object_clip_get(GL_IT(it)->wsd->pan_obj));
6980 evas_object_smart_member_add(pi->proxy, GL_IT(it)->wsd->pan_obj);
6981 evas_object_hide(pi->proxy);
6983 if ((GL_IT(it)->wsd->decorate_all_mode) && (it->deco_all_view))
6984 evas_object_image_source_set(pi->proxy, it->deco_all_view);
6986 evas_object_image_source_set(pi->proxy, VIEW(it));
6988 GL_IT(it)->has_proxy_it = EINA_TRUE;
6990 pi->num = it->item->num;
6991 pi->x = it->item->scrl_x;
6992 pi->y = it->item->scrl_y;
6993 pi->w = it->item->w;
6994 pi->h = it->item->h;
6996 evas_object_geometry_get(VIEW(it), NULL, NULL, &w, &h);
6998 if (w <= 0 || h <= 0)
7000 evas_object_size_hint_min_get(VIEW(it), &w, &h);
7001 evas_object_size_hint_min_set(pi->proxy, w, h);
7003 else evas_object_resize(pi->proxy, w, h);
7009 _elm_genlist_fx_capture(Evas_Object *obj, int level)
7011 ELM_GENLIST_DATA_GET(obj, sd);
7015 Eina_Bool done = EINA_FALSE;
7018 Evas_Coord ox, oy, ow, oh;
7022 if ((!sd->rendered) || (sd->fx_playing)) return EINA_FALSE;
7023 if ((!level) && (sd->fx_first_captured)) return EINA_FALSE;
7024 if ((level) && (!sd->fx_first_captured)) return EINA_FALSE;
7026 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7030 sd->fx_first_captured = EINA_TRUE;
7031 EINA_LIST_FREE(sd->capture_before_items, pi)
7033 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
7034 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
7035 if (pi->proxy) evas_object_del(pi->proxy);
7041 EINA_LIST_FREE(sd->capture_after_items, pi)
7043 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
7044 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
7045 if (pi->proxy) evas_object_del(pi->proxy);
7049 EINA_INLIST_FOREACH(sd->blocks, itb)
7053 EINA_LIST_FOREACH(itb->items, l, it)
7055 if (it->realized && it->item->scrl_y >= oy)
7057 sd->realized_top_item = it;
7062 if (sd->realized_top_item) break;
7066 #if GENLIST_PINCH_ZOOM_SUPPORT
7067 if (sd->pinch_zoom_mode)
7069 EINA_INLIST_FOREACH(sd->blocks, itb)
7071 EINA_LIST_FOREACH(itb->items, l, it)
7074 if (IS_ROOT_PARENT_IT(it) && it->realized
7075 && (GL_IT(it)->scrl_y + GL_IT(it)->h >= oy && GL_IT(it)->scrl_y <= oy + oh))
7077 pi = _elm_genlist_proxy_item_new((Elm_Object_Item *)it);
7078 if (!level) sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
7079 else sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
7083 if ((sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT) && (level)) return EINA_TRUE;
7084 if ((sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND) && (!level)) return EINA_TRUE;
7088 EINA_INLIST_FOREACH(sd->blocks, itb)
7093 EINA_LIST_FOREACH(itb->items, l, it)
7095 #if GENLIST_PINCH_ZOOM_SUPPORT
7096 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7100 pi = _elm_genlist_proxy_item_new((Elm_Object_Item *)it);
7103 sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
7105 sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
7109 else if (done) break;
7114 static Elm_Gen_FX_Item *
7115 _elm_genlist_fx_item_find(const Elm_Object_Item *item)
7117 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
7118 if (!it) return EINA_FALSE;
7120 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
7121 if (!sd) return NULL;
7123 Elm_Gen_FX_Item *fi = NULL;
7126 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7128 if (fi->it == it) return fi;
7133 static Elm_Gen_FX_Item *
7134 _elm_genlist_fx_item_new(const Proxy_Item *pi)
7136 if ((!pi) || (!pi->it)) return NULL;
7138 Elm_Gen_FX_Item *fi = NULL;
7139 fi = calloc(1, sizeof(Elm_Gen_FX_Item));
7140 if (!fi) return NULL;
7143 GL_IT(fi->it)->fi = fi;
7144 fi->proxy = pi->proxy;
7146 fi->from.x = fi->to.x = pi->x;
7147 fi->from.y = fi->to.y = pi->y;
7148 fi->from.w = fi->to.w = pi->w;
7149 fi->from.h = fi->to.h = pi->h;
7150 fi->update = EINA_FALSE;
7155 static Elm_Object_Item *
7156 _elm_genlist_fx_item_prev_get(const Elm_Object_Item *item)
7159 it = (Elm_Gen_Item *)item;
7160 if (!it) return NULL;
7161 if (GL_IT(it)->wsd->pinch_zoom_mode) return NULL;
7165 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7169 return (Elm_Object_Item *)it;
7173 _elm_genlist_fx_items_make(Evas_Object *obj)
7175 ELM_GENLIST_CHECK(obj) EINA_FALSE;
7176 ELM_GENLIST_DATA_GET(obj, sd);
7178 Elm_Gen_FX_Item *fi;
7181 Elm_Gen_Item *prev = NULL;
7182 Evas_Coord ox, oy, ow, oh, mv_dist, max_mv_dist = 0;
7184 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7186 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7188 fi = _elm_genlist_fx_item_new(pi);
7189 if (fi) sd->fx_items = eina_list_append(sd->fx_items, fi);
7192 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
7194 fi = _elm_genlist_fx_item_find((Elm_Object_Item *)pi->it);
7196 if (fi) // pi exists in both before and after capture items
7198 fi->type = ELM_GEN_ITEM_FX_TYPE_SAME;
7199 fi->update = EINA_TRUE;
7205 // find the max distance between before and after capture items
7206 mv_dist = abs(fi->to.y - fi->from.y);
7207 if (max_mv_dist < mv_dist) max_mv_dist = mv_dist;
7209 else // pi only exists in after capture items
7211 fi = _elm_genlist_fx_item_new(pi);
7214 fi->type = ELM_GEN_ITEM_FX_TYPE_ADD;
7215 fi->update = EINA_TRUE;
7216 sd->fx_items = eina_list_append(sd->fx_items, fi);
7221 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7223 // find deleted items
7224 if (!fi->update) // pi only exists in before capture items
7226 fi->type = ELM_GEN_ITEM_FX_TYPE_DEL;
7227 fi->update = EINA_TRUE;
7229 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7230 if ((prev) && (GL_IT(prev)->fi))
7232 fi->to.y = GL_IT(prev)->fi->to.y + GL_IT(prev)->fi->to.h;
7235 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7237 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7238 if ((prev) && (prev->realized) && (GL_IT(prev)->fi))
7240 fi->from.y = GL_IT(prev)->fi->from.y + GL_IT(prev)->fi->from.h;
7244 if (sd->realized_top_item)
7247 if (fi->num <= sd->realized_top_item->item->num)
7248 fi->from.y -= max_mv_dist;
7250 fi->from.y += max_mv_dist;
7256 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7258 if ((GL_IT(fi->it)->items) && (GL_IT(fi->it)->expanded_depth == 0))
7260 #if GENLIST_PINCH_ZOOM_SUPPORT
7261 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7263 fi->from.y = oy + GL_IT(fi->it)->pan_scrl_y - sd->pinch_pan_y;
7266 if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7268 if (sd->realized_top_item)
7270 if (fi->num <= sd->realized_top_item->item->num)
7271 fi->to.y = oy - fi->from.h;
7282 static Elm_Gen_FX_Item *
7283 _fx_cover_item_get(const Elm_Gen_FX_Item *fi)
7285 Elm_Gen_FX_Item *cover_fi;
7287 if (!fi) return NULL;
7289 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7290 Evas_Coord ox, oy, ow, oh;
7291 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7293 EINA_LIST_FOREACH(sd->fx_items, l, cover_fi)
7295 if (fi == cover_fi) continue;
7296 if (sd->fx_items_deleted)
7298 if ((cover_fi->from.y >= oy+oh || cover_fi->from.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y > 0))
7303 if ((cover_fi->to.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y < 0))
7311 _item_fx_op(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__, double progress __UNUSED__)
7313 Elm_Gen_FX_Item *fi = data, *cover_it;
7314 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7315 Evas_Coord fi_ox, fi_oy, cover_it_ox, cover_it_oy, ox, oy, ow, oh;
7317 evas_object_show(VIEW(fi->it));
7318 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7319 evas_object_geometry_get(fi->proxy, &fi_ox, &fi_oy, NULL, NULL);
7320 evas_object_move(fi->proxy, ox, fi_oy);
7321 evas_object_show(fi->proxy);
7322 #if GENLIST_PINCH_ZOOM_SUPPORT
7323 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(fi->it))) evas_object_raise(fi->proxy);
7326 if ((!sd->expanded_next_item) || (sd->expanded_next_item == fi->it)) goto raise_event_block;
7327 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME) goto raise_event_block;
7329 // find the closest item that cover current item when deleting
7330 cover_it = _fx_cover_item_get(fi);
7333 evas_object_geometry_get(cover_it->proxy, &cover_it_ox, &cover_it_oy, NULL, NULL);
7335 if (sd->fx_items_deleted)
7338 && (fi_oy + fi->to.h >= cover_it_oy + cover_it->to.h ) && (fi->from.y < cover_it->from.y))
7339 evas_object_hide(fi->proxy);
7341 else if (cover_it_oy && (fi_oy >= cover_it_oy))
7342 evas_object_hide(fi->proxy);
7344 evas_object_show(fi->proxy);
7348 evas_object_raise(sd->alpha_bg);
7355 _item_fx_done(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__)
7357 Elm_Gen_FX_Item *fx_done_it = data;
7358 Elm_Genlist_Smart_Data *sd = GL_IT(fx_done_it->it)->wsd;
7360 if ((!fx_done_it) || (!fx_done_it->it) || (!sd)) return;
7362 evas_object_image_source_visible_set(fx_done_it->proxy, EINA_TRUE);
7363 evas_object_lower(fx_done_it->proxy);
7365 if ((sd->decorate_all_mode) && (fx_done_it->it->deco_all_view))
7366 evas_object_move(fx_done_it->it->deco_all_view, fx_done_it->to.x, fx_done_it->to.y);
7368 evas_object_move(VIEW(fx_done_it->it), fx_done_it->to.x, fx_done_it->to.y);
7369 GL_IT(fx_done_it->it)->has_proxy_it = EINA_FALSE;
7371 evas_object_clip_unset(fx_done_it->proxy);
7375 _item_fx_del_cb(void *data, Elm_Transit *transit __UNUSED__)
7377 Elm_Gen_FX_Item *fx_done_it = data;
7378 Elm_Gen_Item *it = NULL;
7379 Proxy_Item *pi = NULL;
7381 Elm_Genlist_Smart_Data *sd = GL_IT(fx_done_it->it)->wsd;
7383 if ((!fx_done_it) || (!fx_done_it->it) || (!sd)) return;
7385 sd->fx_items = eina_list_remove(sd->fx_items, fx_done_it);
7386 GL_IT(fx_done_it->it)->fi = NULL;
7389 if (!eina_list_count(sd->fx_items))
7391 EINA_LIST_FREE (sd->pending_unrealized_items, it)
7393 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7394 #if GENLIST_PINCH_ZOOM_SUPPORT
7395 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7397 _item_unrealize(it, EINA_FALSE);
7399 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
7401 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7402 #if GENLIST_PINCH_ZOOM_SUPPORT
7403 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7405 _decorate_all_item_unrealize(it);
7408 EINA_LIST_FREE (sd->pending_del_items, it)
7411 _elm_widget_item_free((Elm_Widget_Item *)it);
7414 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7415 evas_object_hide(pi->proxy);
7416 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
7417 evas_object_hide(pi->proxy);
7419 sd->fx_playing = EINA_FALSE;
7420 sd->sorting = EINA_FALSE;
7421 sd->fx_first_captured = EINA_FALSE;
7422 evas_object_hide(sd->alpha_bg);
7424 sd->realized_top_item = NULL;
7425 sd->pan_changed = EINA_TRUE;
7426 evas_object_smart_changed(sd->pan_obj);
7431 _sorting_effect_animator_cb(void *data)
7433 Elm_Genlist_Smart_Data *sd = data;
7434 Elm_Gen_FX_Item *fi;
7437 Evas_Coord ox, oy, ow, oh;
7438 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7440 sd->fx_timer = NULL;
7441 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7445 fi->changed = EINA_TRUE;
7446 evas_object_resize(fi->proxy, ow, fi->to.h);
7448 fi->trans = elm_transit_add();
7449 elm_transit_object_add(fi->trans, fi->proxy);
7450 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7451 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7453 elm_transit_effect_translation_add(fi->trans, fi->to.x, fi->to.y - 30 * elm_config_scale_get(), fi->to.x, fi->to.y);
7454 elm_transit_effect_color_add(fi->trans,0, 0, 0, 0, 255,255,255,255);
7456 elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
7457 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7458 elm_transit_duration_set(fi->trans,0.3);
7459 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7460 elm_transit_go(fi->trans);
7462 return ECORE_CALLBACK_RENEW;
7465 return ECORE_CALLBACK_CANCEL;
7469 _elm_genlist_fx_play(Evas_Object *obj)
7471 ELM_GENLIST_CHECK(obj);
7472 ELM_GENLIST_DATA_GET(obj, sd);
7474 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
7475 Elm_Gen_FX_Item *fi;
7478 if (!sd->fx_mode) return;
7480 EINA_LIST_FREE(sd->fx_items, fi)
7482 if (fi->trans) elm_transit_del(fi->trans);
7485 _item_cache_all_free(sd);
7487 _elm_genlist_fx_items_make(obj);
7488 if (!eina_list_count(sd->fx_items) || (sd->queue))
7490 _elm_genlist_fx_clear(obj);
7494 sd->fx_playing = EINA_TRUE;
7496 if (!sd->alpha_bg) sd->alpha_bg = _tray_alpha_bg_create(obj);
7497 evas_object_show(sd->alpha_bg);
7499 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7500 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
7504 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7505 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7506 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
7507 sd->fx_timer = ecore_timer_add(0.05, _sorting_effect_animator_cb, sd);
7511 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7513 if (!fi->proxy) continue;
7515 if ((fi->from.y <= oy) || (fi->from.y + fi->from.h >= oy + oh))
7517 if ((sd->decorate_all_mode) && (fi->it->deco_all_view))
7518 evas_object_move(fi->it->deco_all_view, cvx, fi->to.y);
7520 evas_object_move(VIEW(fi->it), cvx, fi->to.y);
7522 else if ((fi->to.y <= oy) || (fi->to.y + fi->to.h >= oy + oh))
7524 if ((sd->decorate_all_mode) && (fi->it->deco_all_view))
7525 evas_object_move(fi->it->deco_all_view, cvx, fi->from.y);
7527 evas_object_move(VIEW(fi->it), cvx, fi->from.y);
7530 evas_object_resize(fi->proxy, ow, fi->to.h);
7531 evas_object_show(fi->proxy);
7533 fi->trans = elm_transit_add();
7534 elm_transit_object_add(fi->trans, fi->proxy);
7536 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7537 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7539 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME)
7541 evas_object_raise(fi->proxy);
7542 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7545 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7547 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7548 elm_transit_effect_color_add(fi->trans, 0, 0, 0, 0, 255, 255, 255, 255);
7550 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7552 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7553 elm_transit_effect_color_add(fi->trans, 255, 255, 255, 255, 0, 0, 0, 0);
7555 elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
7556 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7558 elm_transit_duration_set(fi->trans, FX_MOVE_TIME);
7559 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7560 elm_transit_go(fi->trans);
7565 #if GENLIST_PINCH_ZOOM_SUPPORT
7567 elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Elm_Gen_Pinch_Zoom_Mode mode)
7569 ELM_GENLIST_DATA_GET(obj, sd);
7574 Eina_Bool done = EINA_FALSE;
7576 if ((sd->queue) || (!sd->rendered) || (sd->queue_idle_enterer)) return EINA_FALSE;
7578 EINA_INLIST_FOREACH(sd->blocks, itb)
7580 EINA_LIST_FOREACH(itb->items, l, it)
7583 if (IS_ROOT_PARENT_IT(it))
7591 if (!done) return EINA_FALSE;
7593 sd->pinch_zoom_mode = mode;
7595 _item_cache_all_free(sd);
7596 _elm_genlist_fx_capture(obj, 0);
7598 sd->pinch_pan_y = sd->pan_y;
7600 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7601 sd->s_iface->content_region_show(obj, 0,0,0,0);
7603 sd->pan_changed = EINA_TRUE;
7604 evas_object_smart_changed(sd->pan_obj);
7611 eina_list_sort_merge(Eina_List *a, Eina_List *b, Eina_Compare_Cb func)
7613 Eina_List *first, *last;
7615 if (func(a->data, b->data) > 0)
7617 _item_move_after(a->data, b->data);
7618 a = (last = first = a)->next;
7622 b = (last = first = b)->next;
7625 if (func(a->data, b->data) > 0)
7627 _item_move_after(a->data, b->data);
7628 a = (last = last->next = a)->next;
7631 b = (last = last->next = b)->next;
7633 last->next = a ? a : b;
7639 elm_genlist_sort(Evas_Object *obj, Eina_Compare_Cb func)
7641 ELM_GENLIST_CHECK(obj) NULL;
7642 ELM_GENLIST_DATA_GET(obj, sd);
7643 Eina_List *list = NULL;
7644 Elm_Gen_Item *it, *next;
7645 unsigned int limit = 0, i = 0, n = 0;
7646 Eina_List *tail = NULL, *unsort = NULL, *stack[32], *prev = NULL;
7648 sd->sorting = EINA_TRUE;
7650 it = (Elm_Gen_Item*)elm_genlist_first_item_get(obj);
7653 list = eina_list_append(list, it);
7654 next = (Elm_Gen_Item*)elm_genlist_item_next_get((Elm_Object_Item *)it);
7662 limit = eina_list_count(list);
7666 (limit > list->accounting->count))
7667 limit = list->accounting->count;
7669 if (limit != list->accounting->count)
7671 unsort = eina_list_nth_list(list, limit);
7673 unsort->prev->next = NULL;
7678 unsigned int idx, tmp;
7680 Eina_List *a = tail;
7681 Eina_List *b = tail->next;
7691 if (func(a->data, b->data) > 0)
7692 ((stack[i++] = a)->next = b)->next = 0;
7694 ((stack[i++] = b)->next = a)->next = 0;
7697 for (idx = n ^ tmp; idx &= idx - 1; i--)
7698 stack[i - 2] = eina_list_sort_merge(stack[i - 2], stack[i - 1], func);
7702 stack[i - 1] = eina_list_sort_merge(stack[i - 1], stack[i], func);
7706 for (; stack[0]; stack[0] = stack[0]->next)
7708 stack[0]->prev = prev;
7715 tail->next = unsort;
7716 unsort->prev = tail;
7719 list->accounting->last = tail;
7721 if (!sd->fx_mode) sd->sorting = EINA_FALSE;
7722 if (sd->decorate_all_mode) sd->sorting = EINA_FALSE;
7723 sd->s_iface->content_region_show(obj, 0,0,0,0);
7724 sd->pan_changed = EINA_TRUE;
7725 evas_object_smart_changed(sd->pan_obj);