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;
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 psd->wsd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(psd->wsd)->obj,
472 if (psd->wsd->mode == ELM_LIST_COMPRESS &&
473 vw != psd->wsd->prev_viewport_w)
474 psd->wsd->size_changed = EINA_TRUE;
475 if (vw != 0) psd->wsd->prev_viewport_w = vw;
477 psd->wsd->pan_changed = EINA_TRUE;
478 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
479 psd->wsd->calc_job = ecore_job_add(_calc_job, psd->wsd);
483 _item_scroll(Elm_Genlist_Smart_Data *sd)
486 Elm_Gen_Item *it = NULL;
487 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
489 if (!sd->show_item) return;
491 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &oh);
493 dx = it->x + it->item->block->x;
494 dy = it->y + it->item->block->y;
495 dw = it->item->block->w;
498 switch (sd->scroll_to_type)
500 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
501 if (it->item->group_item) gith = it->item->group_item->item->h;
505 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
506 dy += ((it->item->h / 2) - (oh / 2));
509 case ELM_GENLIST_ITEM_SCROLLTO_IN:
511 if ((sd->expanded_item) &&
512 ((sd->show_item->y + sd->show_item->item->block->y
513 + sd->show_item->item->h) -
514 (sd->expanded_item->y + sd->expanded_item->item->block->y) > oh))
516 it = sd->expanded_item;
517 if (it->item->group_item) gith = it->item->group_item->item->h;
518 dx = it->x + it->item->block->x;
519 dy = it->y + it->item->block->y - gith;
520 dw = it->item->block->w;
524 if ((it->item->group_item) &&
525 (sd->pan_y > (it->y + it->item->block->y)))
526 gith = it->item->group_item->item->h;
533 sd->s_iface->region_bring_in(ELM_WIDGET_DATA(sd)->obj, dx, dy, dw, dh);
535 sd->s_iface->content_region_show
536 (ELM_WIDGET_DATA(sd)->obj, dx, dy, dw, dh);
538 it->item->show_me = EINA_FALSE;
539 sd->show_item = NULL;
540 sd->auto_scroll_enabled = EINA_FALSE;
541 sd->check_scroll = EINA_FALSE;
545 _item_unrealize(Elm_Gen_Item *it,
548 Evas_Object *content;
552 if (!it->realized) return;
553 if (GL_IT(it)->wsd->reorder_it == it) return;
555 #if GENLIST_FX_SUPPORT
556 if ((GL_IT(it)->has_proxy_it) && (!GL_IT(it)->wsd->genlist_clearing))
558 if (!eina_list_data_find(GL_IT(it)->wsd->pending_unrealized_items, it))
559 GL_IT(it)->wsd->pending_unrealized_items =
560 eina_list_append(GL_IT(it)->wsd->pending_unrealized_items, it);
564 #if GENLIST_ENTRY_SUPPORT
565 if (it->item->unrealize_disabled)
567 evas_object_hide(VIEW(it));
572 //evas_event_freeze(evas_object_evas_get(WIDGET(it)));
574 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
577 ecore_timer_del(it->long_timer);
578 it->long_timer = NULL;
580 if (it->item->swipe_timer)
582 ecore_timer_del(it->item->swipe_timer);
583 it->item->swipe_timer = NULL;
587 EINA_LIST_FOREACH(it->texts, l, part)
588 edje_object_part_text_set(VIEW(it), part, NULL);
590 elm_widget_stringlist_free(it->texts);
592 elm_widget_stringlist_free(it->contents);
594 elm_widget_stringlist_free(it->states);
596 EINA_LIST_FREE(it->content_objs, content)
598 // FIXME: If parent-child relationship was broken before 'ic'
599 // is deleted, freeze_pop will not be called. ex) elm_slider
600 // If layout is used instead of edje, this problme can be
602 if (0 != elm_widget_scroll_freeze_get(content))
603 elm_widget_scroll_freeze_pop(content);
604 evas_object_del(content);
608 elm_widget_stringlist_free(it->item->flip_contents);
609 it->item->flip_contents = NULL;
610 EINA_LIST_FREE(it->item->flip_content_objs, content)
611 evas_object_del(content);
614 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
615 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
617 // unswallow VIEW(it) first then manipulate VIEW(it)
618 _decorate_item_unrealize(it);
619 _decorate_all_item_unrealize(it);
621 edje_object_signal_emit
622 (VIEW(it), "elm,state,decorate,disabled", "elm");
623 edje_object_signal_emit
624 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
625 edje_object_message_signal_process(VIEW(it));
627 it->realized = EINA_FALSE;
628 _item_cache_push(it);
630 #if GENLIST_ENTRY_SUPPORT
631 it->item->unrealize_disabled = EINA_FALSE;
633 it->want_unrealize = EINA_FALSE;
635 //evas_event_thaw(evas_object_evas_get(WIDGET(it)));
636 //evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
640 _item_block_unrealize(Item_Block *itb)
644 Eina_Bool dragging = EINA_FALSE;
646 if (!itb->realized) return;
647 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
649 EINA_LIST_FOREACH(itb->items, l, it)
651 if (itb->must_recalc || !it->group)
655 dragging = EINA_TRUE;
656 it->want_unrealize = EINA_TRUE;
659 _item_unrealize(it, EINA_FALSE);
664 itb->realized = EINA_FALSE;
665 itb->want_unrealize = EINA_TRUE;
668 itb->want_unrealize = EINA_FALSE;
669 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
670 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
674 _must_recalc_idler(void *data)
676 Elm_Genlist_Smart_Data *sd = data;
678 if (sd->calc_job) ecore_job_del(sd->calc_job);
679 sd->calc_job = ecore_job_add(_calc_job, sd);
680 sd->must_recalc_idler = NULL;
681 return ECORE_CALLBACK_CANCEL;
685 _calc_job(void *data)
688 Item_Block *itb, *chb = NULL;
689 Evas_Coord pan_w = 0, pan_h = 0;
690 Elm_Genlist_Smart_Data *sd = data;
691 Eina_Bool minw_change = EINA_FALSE;
692 Eina_Bool did_must_recalc = EINA_FALSE;
693 Evas_Coord minw = -1, minh = 0, y = 0, dy = 0, vw = 0;
695 sd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(sd)->obj, &sd->w, &sd->h);
697 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
698 EINA_INLIST_FOREACH(sd->blocks, itb)
700 Eina_Bool show_me = EINA_FALSE;
703 show_me = itb->show_me;
704 itb->show_me = EINA_FALSE;
707 if (itb->realized) _item_block_unrealize(itb);
709 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
711 if (itb->must_recalc)
716 EINA_LIST_FOREACH(itb->items, l, it)
717 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
718 itb->changed = EINA_TRUE;
719 did_must_recalc = EINA_TRUE;
720 if (itb->realized) _item_block_unrealize(itb);
721 itb->must_recalc = EINA_FALSE;
723 show_me = _item_block_recalc(itb, in, EINA_FALSE);
729 if (minw == -1) minw = itb->minw;
730 else if ((!itb->must_recalc) && (minw < itb->minw))
733 minw_change = EINA_TRUE;
735 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
738 minw_change = EINA_TRUE;
744 if ((show_me) && (sd->show_item) && (!sd->show_item->item->queued))
745 sd->check_scroll = EINA_TRUE;
749 EINA_INLIST_FOREACH(sd->blocks, itb)
755 if ((chb) && (EINA_INLIST_GET(chb)->next))
757 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
759 if (itb->realized) _item_block_unrealize(itb);
763 if (minw < sd->w) minw = sd->w;
764 if ((minw != sd->minw) || (minh != sd->minh))
768 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
769 elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
776 if ((sd->anchor_item) && (sd->anchor_item->item->block)
777 && (!sd->auto_scroll_enabled))
782 it = sd->anchor_item;
784 sd->s_iface->content_pos_set
785 (ELM_WIDGET_DATA(sd)->obj, sd->pan_x, it->item->block->y
786 + it->y + it_y, EINA_TRUE);
787 sd->anchor_item = it;
793 if (!sd->must_recalc_idler)
794 sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, sd);
796 if (sd->check_scroll)
798 _elm_genlist_pan_smart_content_size_get(sd->pan_obj, &pan_w, &pan_h);
799 if (EINA_INLIST_GET(sd->show_item) == sd->items->last)
800 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
802 switch (sd->scroll_to_type)
804 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
808 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
812 case ELM_GENLIST_ITEM_SCROLLTO_IN:
817 if ((sd->show_item) && (sd->show_item->item->block))
819 if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
820 && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
829 evas_object_smart_changed(sd->pan_obj);
830 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
831 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
835 _elm_genlist_smart_sizing_eval(Evas_Object *obj)
837 Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1, vw = 0;
839 ELM_GENLIST_DATA_GET(obj, sd);
841 /* parent class' early call */
842 if (!sd->s_iface) return;
843 if (sd->on_sub_del) return;;
845 evas_object_size_hint_min_get(obj, &minw, NULL);
846 evas_object_size_hint_max_get(obj, &maxw, &maxh);
847 edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
849 sd->s_iface->content_viewport_size_get(obj, &vw, NULL);
850 if (vw != 0) sd->prev_viewport_w = vw;
852 if (sd->mode == ELM_LIST_LIMIT)
855 minw = minw + sd->realminw;
858 evas_object_size_hint_min_set(obj, minw, minh);
859 evas_object_size_hint_max_set(obj, maxw, maxh);
863 _item_position(Elm_Gen_Item *it,
871 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
872 evas_object_resize(view, it->item->w, it->item->h);
873 evas_object_move(view, it_x, it_y);
874 evas_object_show(view);
875 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
876 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
880 _item_sub_items_clear(Elm_Gen_Item *it)
883 Elm_Object_Item *it2;
885 EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, it2)
886 elm_widget_item_del(it2);
890 _item_auto_scroll(Elm_Genlist_Smart_Data *sd)
892 Elm_Gen_Item *tmp_item = NULL;
894 #if GENLIST_FX_SUPPORT
895 if (sd->fx_first_captured) return;
897 if ((sd->expanded_item) && (sd->auto_scroll_enabled))
899 tmp_item = eina_list_data_get
900 (eina_list_last(sd->expanded_item->item->items));
901 if (!tmp_item) return;
902 sd->show_item = tmp_item;
903 sd->bring_in = EINA_TRUE;
904 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
905 if ((sd->show_item->item->queued) || (!sd->show_item->item->mincalcd))
907 sd->show_item->item->show_me = EINA_TRUE;
908 sd->auto_scroll_enabled = EINA_FALSE;
916 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
918 if (!it->item->nostacking)
920 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
922 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
923 else evas_object_lower(VIEW(it));
927 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
928 else evas_object_raise(VIEW(it));
932 if (it->item->order_num_in & 0x1)
934 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
935 if (it->deco_all_view)
936 edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
940 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
941 if (it->deco_all_view)
942 edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
947 _item_order_update(const Eina_Inlist *l,
950 Elm_Gen_Item *it, *it2;
952 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next,
953 it = ELM_GEN_ITEM_FROM_INLIST(l))
955 it->item->order_num_in = start++;
956 _elm_genlist_item_odd_even_update(it);
957 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
958 if (it2 && (it->item->order_num_in != it2->item->order_num_in))
964 _elm_genlist_item_state_update(Elm_Gen_Item *it)
968 if (it->deco_all_view)
969 edje_object_signal_emit
970 (it->deco_all_view, "elm,state,selected", "elm");
971 edje_object_signal_emit
972 (VIEW(it), "elm,state,selected", "elm");
973 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
975 if (elm_widget_item_disabled_get(it))
977 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
978 if (it->deco_all_view)
979 edje_object_signal_emit
980 (it->deco_all_view, "elm,state,disabled", "elm");
982 if (it->item->expanded)
984 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
985 if (it->deco_all_view)
986 edje_object_signal_emit
987 (it->deco_all_view, "elm,state,expanded", "elm");
992 _elm_genlist_item_index_update(Elm_Gen_Item *it)
994 if (it->position_update || it->item->block->position_update)
996 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
997 it->position_update = EINA_FALSE;
1002 _item_text_realize(Elm_Gen_Item *it,
1003 Evas_Object *target,
1007 if (it->itc->func.text_get)
1013 *source = elm_widget_stringlist_get
1014 (edje_object_data_get(target, "texts"));
1015 EINA_LIST_FOREACH(*source, l, key)
1017 if (parts && fnmatch(parts, key, FNM_PERIOD))
1020 char *s = it->itc->func.text_get
1021 ((void *)it->base.data, WIDGET(it), key);
1025 edje_object_part_text_escaped_set(target, key, s);
1030 edje_object_part_text_set(target, key, "");
1037 // FIXME: difference from upstream
1039 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1041 Elm_Gen_Item *it = data;
1042 if (it) it->defer_unrealize = EINA_TRUE;
1046 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1048 Elm_Gen_Item *it = data;
1049 if (it) it->defer_unrealize = EINA_FALSE;
1054 _item_mode_content_realize(Elm_Gen_Item *it,
1055 Evas_Object *target,
1058 Eina_List **contents_list)
1060 Eina_List *res = *contents_list;
1062 if (it->itc->func.content_get)
1068 EINA_LIST_FOREACH(*source, l, key)
1070 if (parts && fnmatch(parts, key, FNM_PERIOD))
1073 ic = it->itc->func.content_get
1074 ((void *)it->base.data, WIDGET(it), key);
1078 res = eina_list_append(res, ic);
1079 edje_object_part_swallow(target, key, ic);
1080 evas_object_show(ic);
1081 #if GENLIST_ENTRY_SUPPORT
1084 // For entry or editfield
1085 // 1. Add resize callback for multiline entry.
1086 // 2. Do not unrealize it for focus issue
1087 // ps. Only for entry because of performnace
1088 if (!strcmp("elm_layout", evas_object_type_get(ic)))
1090 // If editfield style, it can have entry.
1092 edje_object_file_get(elm_layout_edje_get(ic), NULL, &group);
1093 if (group && !strncmp("elm/layout/editfield/", group, 20))
1094 it->item->unrealize_disabled = EINA_TRUE;
1096 else if (!strcmp("elm_entry", evas_object_type_get(ic)))
1097 it->item->unrealize_disabled = EINA_TRUE;
1101 // FIXME: difference from upstream
1104 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1105 // genlist does not need to handle this focus thing.
1106 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1107 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1110 if (elm_widget_item_disabled_get(it))
1111 elm_widget_disabled_set(ic, EINA_TRUE);
1120 _item_state_realize(Elm_Gen_Item *it,
1121 Evas_Object *target,
1125 if (it->itc->func.state_get)
1132 *source = elm_widget_stringlist_get
1133 (edje_object_data_get(target, "states"));
1134 EINA_LIST_FOREACH(*source, l, key)
1136 if (parts && fnmatch(parts, key, FNM_PERIOD))
1139 Eina_Bool on = it->itc->func.state_get
1140 ((void *)it->base.data, WIDGET(it), key);
1144 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1145 edje_object_signal_emit(target, buf, "elm");
1149 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1150 edje_object_signal_emit(target, buf, "elm");
1157 _decorate_item_unrealize(Elm_Gen_Item *it)
1159 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
1160 Evas_Object *content;
1162 if (!it->item->deco_it_view) return;
1164 //evas_event_freeze(evas_object_evas_get(obj));
1165 elm_widget_stringlist_free(it->item->deco_it_texts);
1166 it->item->deco_it_texts = NULL;
1167 elm_widget_stringlist_free(it->item->deco_it_contents);
1168 it->item->deco_it_contents = NULL;
1169 elm_widget_stringlist_free(it->item->deco_it_states);
1171 EINA_LIST_FREE (it->item->deco_it_content_objs, content)
1172 evas_object_del(content);
1174 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
1175 evas_object_smart_member_add(VIEW(it), sd->pan_obj);
1176 evas_object_del(it->item->deco_it_view);
1177 it->item->deco_it_view = NULL;
1179 if (sd->mode_item == it) sd->mode_item = NULL;
1180 //evas_event_thaw(evas_object_evas_get(obj));
1181 //evas_event_thaw_eval(evas_object_evas_get(obj));
1186 _decorate_all_item_position(Elm_Gen_Item *it,
1190 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
1191 evas_object_move(it->deco_all_view, itx, ity);
1195 _decorate_all_item_realize(Elm_Gen_Item *it,
1196 Eina_Bool effect_on)
1199 const char *stacking;
1200 const char *stacking_even;
1202 if ((!it) || (it->item->decorate_all_item_realized)) return;
1204 if (it->item->deco_it_view) _decorate_item_unrealize(it);
1206 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1207 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
1208 elm_config_scale_get());
1209 evas_object_smart_member_add(it->deco_all_view, GL_IT(it)->wsd->pan_obj);
1210 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
1212 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1213 strncpy(buf, "tree", sizeof(buf));
1214 else strncpy(buf, "item", sizeof(buf));
1215 if (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)
1216 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1218 strncat(buf, "/", sizeof(buf) - strlen(buf));
1219 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
1221 elm_widget_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
1222 elm_widget_style_get(WIDGET(it)));
1224 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1225 if (!stacking_even) stacking_even = "above";
1226 it->item->stacking_even = !!strcmp("above", stacking_even);
1228 stacking = edje_object_data_get(VIEW(it), "stacking");
1229 if (!stacking) stacking = "yes";
1230 it->item->nostacking = !!strcmp("yes", stacking);
1232 edje_object_mirrored_set
1233 (it->deco_all_view, elm_widget_mirrored_get(WIDGET(it)));
1235 _elm_genlist_item_odd_even_update(it);
1236 _elm_genlist_item_state_update(it);
1238 #if 1 // FIXME: difference from upstream
1239 if (GL_IT(it)->wsd->reorder_mode)
1240 edje_object_signal_emit
1241 (it->deco_all_view, "elm,state,reorder,mode_set", "elm");
1243 edje_object_signal_emit
1244 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
1248 edje_object_signal_emit
1249 (it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
1250 edje_object_signal_emit
1251 (VIEW(it), "elm,state,decorate,enabled,effect", "elm");
1255 edje_object_signal_emit
1256 (it->deco_all_view, "elm,state,decorate,enabled", "elm");
1257 edje_object_signal_emit
1258 (VIEW(it), "elm,state,decorate,enabled", "elm");
1260 _item_mouse_callbacks_del(it, VIEW(it));
1261 _item_mouse_callbacks_add(it, it->deco_all_view);
1263 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
1265 edje_object_signal_emit
1266 (it->deco_all_view, "elm,state,flip,enabled", "elm");
1267 if (!it->item->deco_all_contents)
1268 it->item->deco_all_contents = elm_widget_stringlist_get
1269 (edje_object_data_get(it->deco_all_view, "contents"));
1270 it->item->deco_all_content_objs =
1271 _item_mode_content_realize(it, it->deco_all_view,
1272 &it->item->deco_all_contents, NULL,
1273 &it->item->deco_all_content_objs);
1275 (it, it->deco_all_view, &it->item->deco_all_states, NULL);
1276 edje_object_part_swallow
1277 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1279 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
1280 evas_object_show(it->deco_all_view);
1284 edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
1285 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
1288 it->item->decorate_all_item_realized = EINA_TRUE;
1289 it->want_unrealize = EINA_FALSE;
1293 _expand_toggle_signal_cb(void *data,
1294 Evas_Object *obj __UNUSED__,
1295 const char *emission __UNUSED__,
1296 const char *source __UNUSED__)
1298 Elm_Gen_Item *it = data;
1300 if (it->item->expanded)
1301 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1303 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1307 _expand_signal_cb(void *data,
1308 Evas_Object *obj __UNUSED__,
1309 const char *emission __UNUSED__,
1310 const char *source __UNUSED__)
1312 Elm_Gen_Item *it = data;
1314 if (!it->item->expanded)
1315 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1319 _contract_signal_cb(void *data,
1320 Evas_Object *obj __UNUSED__,
1321 const char *emission __UNUSED__,
1322 const char *source __UNUSED__)
1324 Elm_Gen_Item *it = data;
1326 if (it->item->expanded)
1327 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1330 #if GENLIST_ENTRY_SUPPORT
1332 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1334 Elm_Gen_Item *it = data;
1336 if (it->want_unrealize) return;
1337 GL_IT(it)->wsd->size_changed = EINA_TRUE;
1338 evas_object_smart_changed(GL_IT(it)->wsd->pan_obj);
1343 _item_content_realize(Elm_Gen_Item *it,
1344 Evas_Object *target,
1348 Eina_List *res = it->content_objs;
1350 if (it->itc->func.content_get)
1354 Evas_Object *ic = NULL;
1357 *source = elm_widget_stringlist_get
1358 (edje_object_data_get(target, "contents"));
1360 EINA_LIST_FOREACH(*source, l, key)
1362 if (parts && fnmatch(parts, key, FNM_PERIOD))
1365 if (it->itc->func.content_get)
1366 ic = it->itc->func.content_get
1367 ((void *)it->base.data, WIDGET(it), key);
1370 res = eina_list_append(res, ic);
1371 edje_object_part_swallow(target, key, ic);
1372 evas_object_show(ic);
1374 #if GENLIST_ENTRY_SUPPORT
1375 // For entry or editfield
1376 // 1. Add resize callback for multiline entry.
1377 // 2. Do not unrealize it for focus issue
1378 // ps. Only for entry because of performnace
1379 if (!strcmp("elm_layout", evas_object_type_get(ic)))
1381 // If editfield style, it can have entry.
1383 edje_object_file_get(elm_layout_edje_get(ic), NULL, &group);
1384 if (group && !strncmp("elm/layout/editfield/", group, 20))
1386 evas_object_event_callback_add
1387 (ic, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1388 _changed_size_hints, it);
1389 it->item->unrealize_disabled = EINA_TRUE;
1393 else if (!strcmp("elm_entry", evas_object_type_get(ic)))
1395 evas_object_event_callback_add
1396 (ic, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1397 _changed_size_hints, it);
1398 it->item->unrealize_disabled = EINA_TRUE;
1401 #if 0 // FIXME: difference from upstream
1404 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1405 // genlist does not need to handle this focus thing.
1406 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1407 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1410 if (elm_widget_item_disabled_get(it))
1411 elm_widget_disabled_set(ic, EINA_TRUE);
1420 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
1425 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1426 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1428 buf = eina_strbuf_new();
1430 if (it->itc->func.text_get)
1435 if (!(it->texts)) it->texts =
1436 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1438 EINA_LIST_FOREACH(it->texts, l, key)
1440 char *s = it->itc->func.text_get
1441 ((void *)it->base.data, WIDGET(it), key);
1443 s = _elm_util_mkup_to_text(s);
1447 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1448 eina_strbuf_append(buf, s);
1454 ret = eina_strbuf_string_steal(buf);
1455 eina_strbuf_free(buf);
1460 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
1462 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1463 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1465 if (it->base.disabled)
1466 return strdup(E_("State: Disabled"));
1472 _access_on_highlight_cb(void *data)
1474 Evas_Coord x, y, w, h;
1475 Evas_Coord sx, sy, sw, sh;
1476 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1477 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1479 ELM_GENLIST_DATA_GET(it->base.widget, sd);
1481 evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
1482 // XXX There would be a reason.
1483 if ((w == 0) && (h == 0)) return;
1485 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
1486 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
1487 elm_genlist_item_bring_in((Elm_Object_Item *)it,
1488 ELM_GENLIST_ITEM_SCROLLTO_IN);
1492 _access_widget_item_register(Elm_Gen_Item *it)
1494 Elm_Access_Info *ai;
1496 _elm_access_widget_item_register((Elm_Widget_Item *)it);
1498 ai = _elm_access_object_get(it->base.access_obj);
1500 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1501 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1502 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
1503 _elm_access_activate_callback_set(ai, _access_activate_cb, it);
1507 _item_realize(Elm_Gen_Item *it,
1511 const char *treesize;
1517 if (it->item->order_num_in != in)
1519 _item_order_update(EINA_INLIST_GET(it), in);
1520 _elm_genlist_item_state_update(it);
1521 _elm_genlist_item_index_update(it);
1525 it->item->order_num_in = in;
1527 if (it->item->nocache_once | it->item->nocache ||
1528 it->item->type == ELM_GENLIST_ITEM_TREE || it->parent ||
1529 !_item_cache_pop(it))
1531 const char *stacking_even;
1532 const char *stacking;
1534 it->item->nocache_once = EINA_FALSE;
1536 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1537 edje_object_scale_set(VIEW(it),
1538 elm_widget_scale_get(WIDGET(it)) *
1539 elm_config_scale_get());
1540 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
1541 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1543 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1544 snprintf(buf, sizeof(buf), "tree%s/%s",
1545 GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS ? "_compress" :
1546 "", it->itc->item_style ? : "default");
1548 snprintf(buf, sizeof(buf), "item%s/%s",
1549 GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS ? "_compress" :
1550 "", it->itc->item_style ? : "default");
1552 elm_widget_theme_object_set
1553 (WIDGET(it), VIEW(it), "genlist", buf,
1554 elm_widget_style_get(WIDGET(it)));
1556 #if 1 // FIXME: difference from upstream
1557 if (it->item->expanded_depth > 0)
1558 edje_object_signal_emit(VIEW(it), "bg_color_change", "elm");
1561 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1562 if (!stacking_even) stacking_even = "above";
1563 it->item->stacking_even = !!strcmp("above", stacking_even);
1565 stacking = edje_object_data_get(VIEW(it), "stacking");
1566 if (!stacking) stacking = "yes";
1567 it->item->nostacking = !!strcmp("yes", stacking);
1569 edje_object_mirrored_set
1570 (VIEW(it), elm_widget_mirrored_get(WIDGET(it)));
1572 edje_object_signal_callback_add
1573 (VIEW(it), "elm,action,expand,toggle", "elm",
1574 _expand_toggle_signal_cb, it);
1575 edje_object_signal_callback_add
1576 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1577 edje_object_signal_callback_add
1578 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1579 _item_mouse_callbacks_add(it, VIEW(it));
1583 if (_elm_config->access_mode) _access_widget_item_register(it);
1585 _item_order_update(EINA_INLIST_GET(it), in);
1586 #if 1 // FIXME: difference from upstream
1587 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
1589 if (GL_IT(it)->wsd->reorder_mode)
1590 edje_object_signal_emit
1591 (VIEW(it), "elm,state,reorder,mode_set", "elm");
1593 edje_object_signal_emit
1594 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
1597 treesize = edje_object_data_get(VIEW(it), "treesize");
1598 if (treesize) tsize = atoi(treesize);
1599 if (it->parent && GL_IT(it->parent)->type == ELM_GENLIST_ITEM_TREE &&
1600 !it->spacer && treesize)
1603 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1604 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1608 evas_object_size_hint_min_set
1609 (it->spacer, (it->item->expanded_depth * tsize) *
1610 elm_config_scale_get(), 1);
1611 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1615 if ((GL_IT(it)->wsd->decorate_all_mode) && (!it->deco_all_view) &&
1616 (it->item->type != ELM_GENLIST_ITEM_GROUP) &&
1617 (it->itc->decorate_all_item_style))
1618 _decorate_all_item_realize(it, EINA_FALSE);
1620 _elm_genlist_item_state_update(it);
1621 _elm_genlist_item_index_update(it);
1624 /* homogenous genlist shortcut */
1625 if ((calc) && (GL_IT(it)->wsd->homogeneous) && (!it->item->mincalcd) &&
1626 ((it->group && GL_IT(it)->wsd->group_item_width) ||
1627 (!it->group && GL_IT(it)->wsd->item_width)))
1631 it->item->w = it->item->minw = GL_IT(it)->wsd->group_item_width;
1632 it->item->h = it->item->minh = GL_IT(it)->wsd->group_item_height;
1636 it->item->w = it->item->minw = GL_IT(it)->wsd->item_width;
1637 it->item->h = it->item->minh = GL_IT(it)->wsd->item_height;
1639 it->item->mincalcd = EINA_TRUE;
1643 if (eina_list_count(it->content_objs) != 0)
1644 ERR_ABORT("If you see this error, please notify us and we"
1647 _item_text_realize(it, VIEW(it), &it->texts, NULL);
1649 _item_content_realize(it, VIEW(it), &it->contents, NULL);
1650 _item_state_realize(it, VIEW(it), &it->states, NULL);
1653 edje_object_signal_emit
1654 (VIEW(it), "elm,state,flip,enabled", "elm");
1655 // This is needed before contents are swallowed
1656 edje_object_message_signal_process(VIEW(it));
1658 if (!(it->item->flip_contents))
1659 it->item->flip_contents = elm_widget_stringlist_get
1660 (edje_object_data_get(VIEW(it), "flips"));
1661 it->item->flip_content_objs = _item_mode_content_realize
1662 (it, VIEW(it), &it->item->flip_contents, NULL,
1663 &it->item->flip_content_objs);
1666 /* access: unregister item which have no text and content */
1667 if (_elm_config->access_mode && !it->texts && !it->contents)
1668 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1671 // FIXME: difference from upstream
1672 if (!it->item->mincalcd || ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
1674 if (!it->item->mincalcd)
1677 Evas_Coord mw = 0, mh = 0;
1679 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1680 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1681 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
1682 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
1683 (mw < GL_IT(it)->wsd->prev_viewport_w))
1684 mw = GL_IT(it)->wsd->prev_viewport_w;
1685 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
1686 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
1687 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
1688 (mw > GL_IT(it)->wsd->prev_viewport_w))
1689 mw = GL_IT(it)->wsd->prev_viewport_w;
1692 it->item->w = it->item->minw = mw;
1693 it->item->h = it->item->minh = mh;
1694 it->item->mincalcd = EINA_TRUE;
1696 if ((!GL_IT(it)->wsd->group_item_width) && (it->group))
1698 GL_IT(it)->wsd->group_item_width = mw;
1699 GL_IT(it)->wsd->group_item_height = mh;
1701 else if ((!GL_IT(it)->wsd->item_width) &&
1702 (it->item->type == ELM_GENLIST_ITEM_NONE))
1704 GL_IT(it)->wsd->item_width = mw;
1705 GL_IT(it)->wsd->item_height = mh;
1708 if (!calc) evas_object_show(VIEW(it));
1711 if (it->tooltip.content_cb)
1713 elm_widget_item_tooltip_content_cb_set
1714 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
1715 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1716 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1719 if (it->mouse_cursor)
1720 elm_widget_item_cursor_set(it, it->mouse_cursor);
1722 it->realized = EINA_TRUE;
1723 it->want_unrealize = EINA_FALSE;
1725 if (!calc || it->item->unrealize_disabled)
1726 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1728 if ((!calc) && (GL_IT(it)->wsd->decorate_all_mode) &&
1729 (it->item->type != ELM_GENLIST_ITEM_GROUP))
1731 if (it->itc->decorate_all_item_style)
1733 if (!it->deco_all_view)
1734 _decorate_all_item_realize(it, EINA_FALSE);
1735 edje_object_message_signal_process(it->deco_all_view);
1738 if ((!calc) && (it->decorate_it_set) &&
1739 (it->item->type != ELM_GENLIST_ITEM_GROUP))
1741 if (it->itc->decorate_item_style)
1743 if (!it->item->deco_it_view)
1744 _decorate_item_set(it);
1745 edje_object_message_signal_process(it->item->deco_it_view);
1748 edje_object_message_signal_process(VIEW(it));
1751 #if GENLIST_PINCH_ZOOM_SUPPORT
1753 _pinch_items_recalc(void *data)
1755 Elm_Genlist_Smart_Data *sd = data;
1760 Evas_Coord tot_y = 0, ox, oy;
1761 evas_object_geometry_get(sd->pan_obj, &ox, &oy, NULL, NULL);
1763 EINA_INLIST_FOREACH(sd->blocks, itb)
1765 EINA_LIST_FOREACH(itb->items, l, it)
1768 if (IS_ROOT_PARENT_IT(it))
1770 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
1772 if (!it->realized) _item_realize(it, 0, EINA_FALSE);
1773 it->item->scrl_y = oy + tot_y - sd->pan_y;
1774 evas_object_resize(VIEW(it), sd->minw, it->item->h);
1775 evas_object_move(VIEW(it), it->item->scrl_x, it->item->scrl_y);
1776 evas_object_show(VIEW(it));
1777 evas_object_raise(VIEW(it));
1778 tot_y += it->item->h;
1779 sd->pinch_zoom_h = tot_y;
1782 else if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND)
1784 evas_object_resize(VIEW(it), sd->minw, it->item->h);
1785 it->item->scrl_y = oy + it->item->pan_scrl_y - sd->pan_y;
1786 evas_object_move(VIEW(it), it->item->scrl_x, it->item->scrl_y);
1795 #if GROUP_ITEMS_FEATURE
1797 _group_items_recalc(void *data)
1801 Elm_Genlist_Smart_Data *sd = data;
1803 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1804 EINA_LIST_FOREACH(sd->group_items, l, git)
1806 if (git->item->want_realize)
1808 if (!git->realized) _item_realize(git, 0, EINA_FALSE);
1809 evas_object_resize(VIEW(git), sd->minw, git->item->h);
1810 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
1811 evas_object_show(VIEW(git));
1812 evas_object_raise(VIEW(git));
1814 else if (!git->item->want_realize)
1817 _item_unrealize(git, EINA_FALSE);
1820 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1821 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1826 _reorder_move_animator_cb(void *data)
1829 Elm_Gen_Item *it = data;
1830 Eina_Bool down = EINA_FALSE;
1833 dy = 6 * elm_config_scale_get();
1834 t = ((0.0 > (t = ecore_loop_time_get()
1835 - GL_IT(it)->wsd->start_time)) ? 0.0 : t);
1837 if (t <= REORDER_EFFECT_TIME)
1838 y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
1841 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
1842 if (diff < dy) y = diff;
1844 if (it->item->old_scrl_y < it->item->scrl_y)
1846 it->item->old_scrl_y += y;
1849 else if (it->item->old_scrl_y > it->item->scrl_y)
1851 it->item->old_scrl_y -= y;
1855 if (it->deco_all_view)
1857 (it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
1858 else if (it->item->deco_it_view)
1860 (it, it->item->deco_it_view, it->item->scrl_x, it->item->old_scrl_y);
1862 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
1864 if ((GL_IT(it)->wsd->reorder_pan_move) ||
1865 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
1866 (!down && it->item->old_scrl_y <= it->item->scrl_y))
1868 it->item->old_scrl_y = it->item->scrl_y;
1869 it->item->move_effect_enabled = EINA_FALSE;
1870 GL_IT(it)->wsd->reorder_move_animator = NULL;
1871 return ECORE_CALLBACK_CANCEL;
1874 return ECORE_CALLBACK_RENEW;
1878 _reorder_item_space_get(Elm_Gen_Item *it)
1880 Elm_Gen_Item *reorder_it = GL_IT(it)->wsd->reorder_it;
1881 Evas_Coord rox, roy, row, roh, oy, oh;
1882 Eina_Bool top = EINA_FALSE;
1884 if (!reorder_it) return 0;
1885 if(it->deco_all_view) evas_object_lower(it->deco_all_view);
1887 evas_object_geometry_get(GL_IT(it)->wsd->pan_obj, NULL, &oy, NULL, &oh);
1888 evas_object_geometry_get
1889 (GL_IT(it)->wsd->VIEW(reorder_it), &rox, &roy, &row, &roh);
1891 if ((GL_IT(it)->wsd->reorder_start_y < it->item->block->y) &&
1892 (roy - oy + (roh / 2) >= it->item->block->y - GL_IT(it)->wsd->pan_y))
1894 it->item->block->reorder_offset =
1895 GL_IT(it)->wsd->reorder_it->item->h * -1;
1896 if (it->item->block->count == 1)
1897 GL_IT(it)->wsd->reorder_rel = it;
1899 else if ((GL_IT(it)->wsd->reorder_start_y >= it->item->block->y) &&
1900 (roy - oy + (roh / 2) <= it->item->block->y -
1901 GL_IT(it)->wsd->pan_y))
1903 it->item->block->reorder_offset = GL_IT(it)->wsd->reorder_it->item->h;
1906 it->item->block->reorder_offset = 0;
1908 it->item->scrl_y += it->item->block->reorder_offset;
1910 top = (ELM_RECTS_INTERSECT
1911 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
1912 rox, roy + (roh / 2), row, 1));
1915 GL_IT(it)->wsd->reorder_rel = it;
1916 it->item->scrl_y += GL_IT(it)->wsd->reorder_it->item->h;
1917 return GL_IT(it)->wsd->reorder_it->item->h;
1924 _item_block_position(Item_Block *itb,
1930 Eina_Bool vis = EINA_FALSE;
1931 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
1933 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
1934 evas_object_geometry_get(itb->sd->pan_obj, &ox, &oy, &ow, &oh);
1935 evas_output_viewport_get
1936 (evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj),
1937 &cvx, &cvy, &cvw, &cvh);
1939 EINA_LIST_FOREACH(itb->items, l, it)
1941 if ((GL_IT(it)->wsd->reorder_it == it) && it->highlighted) continue;
1945 it->item->w = itb->w;
1946 it->item->scrl_x = itb->x + it->x - GL_IT(it)->wsd->pan_x + ox;
1947 it->item->scrl_y = itb->y + it->y - GL_IT(it)->wsd->pan_y + oy;
1949 vis = (ELM_RECTS_INTERSECT
1950 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
1951 cvx, cvy, cvw, cvh));
1954 if ((itb->realized) && (!it->realized))
1956 if (vis) _item_realize(it, in, EINA_FALSE);
1960 if (vis || it->dragging)
1962 #if GENLIST_ENTRY_SUPPORT
1963 evas_object_show(VIEW(it));
1965 if (GL_IT(it)->wsd->reorder_mode &&
1966 GL_IT(it)->wsd->reorder_it &&
1967 GL_IT(it)->wsd->reorder_it->highlighted)
1968 y += _reorder_item_space_get(it);
1969 git = it->item->group_item;
1972 if (git->item->scrl_y < oy)
1973 git->item->scrl_y = oy;
1974 if ((git->item->scrl_y + git->item->h) >
1975 (it->item->scrl_y + it->item->h))
1976 git->item->scrl_y = (it->item->scrl_y +
1977 it->item->h) - git->item->h;
1978 git->item->scrl_x = it->item->scrl_x;
1979 git->item->want_realize = EINA_TRUE;
1981 if ((GL_IT(it)->wsd->reorder_it) &&
1982 GL_IT(it)->wsd->reorder_it->highlighted &&
1983 (it->item->old_scrl_y != it->item->scrl_y))
1985 if (!it->item->move_effect_enabled)
1987 it->item->move_effect_enabled = EINA_TRUE;
1988 GL_IT(it)->wsd->reorder_move_animator =
1990 _reorder_move_animator_cb, it);
1993 if (!it->item->move_effect_enabled)
1995 if ((GL_IT(it)->wsd->decorate_all_mode) &&
1996 (it->itc->decorate_all_item_style))
1997 _decorate_all_item_position
1998 (it, it->item->scrl_x, it->item->scrl_y);
2001 if (it->item->deco_it_view)
2003 (it, it->item->deco_it_view,
2008 (it, VIEW(it), it->item->scrl_x,
2011 it->item->old_scrl_y = it->item->scrl_y;
2012 #if GENLIST_PINCH_ZOOM_SUPPORT
2013 if (((GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
2014 && (!IS_ROOT_PARENT_IT(it))) || (GL_IT(it)->wsd->sorting))
2016 if (it->deco_all_view) evas_object_hide(it->deco_all_view);
2017 else evas_object_hide(VIEW(it));
2025 if ((GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
2026 && (!IS_ROOT_PARENT_IT(it)))
2028 if (it->deco_all_view) evas_object_hide(it->deco_all_view);
2029 else evas_object_hide(VIEW(it));
2032 _item_unrealize(it, EINA_FALSE);
2039 if (vis) it->item->want_realize = EINA_TRUE;
2043 // FIXME: diffrence from upstream
2044 minh += it->item->minh;
2048 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
2049 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
2053 _item_block_realize(Item_Block *itb)
2055 if (itb->realized) return;
2057 itb->realized = EINA_TRUE;
2058 itb->want_unrealize = EINA_FALSE;
2062 _changed_job(Elm_Genlist_Smart_Data *sd)
2068 Eina_Bool anything_changed = EINA_FALSE;
2069 Eina_Bool width_changed = EINA_FALSE;
2070 Eina_Bool height_changed = EINA_FALSE;
2072 EINA_INLIST_FOREACH(sd->blocks, itb)
2077 width_changed = height_changed = EINA_FALSE;
2078 EINA_LIST_FOREACH(itb->items, l2, it)
2082 Evas_Coord mw = 0, mh = 0;
2084 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2085 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2086 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
2087 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
2088 (mw < GL_IT(it)->wsd->prev_viewport_w))
2089 mw = GL_IT(it)->wsd->prev_viewport_w;
2090 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
2091 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
2092 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
2093 (mw > GL_IT(it)->wsd->prev_viewport_w))
2094 mw = GL_IT(it)->wsd->prev_viewport_w;
2096 if (it->item->minw != mw)
2098 it->item->w = it->item->minw = mw;
2099 width_changed = EINA_TRUE;
2101 if (it->item->minh != mh)
2103 it->item->h = it->item->minh = mh;
2104 height_changed = EINA_TRUE;
2111 if ((!sd->group_item_width) && (it->group))
2113 sd->group_item_width = mw;
2114 sd->group_item_height = mh;
2116 else if ((!sd->item_width) &&
2117 (it->item->type == ELM_GENLIST_ITEM_NONE))
2119 sd->item_width = mw;
2120 sd->item_height = mh;
2127 anything_changed = EINA_TRUE;
2128 itb->changed = EINA_TRUE;
2129 _item_block_recalc(itb, num0, 0);
2130 _item_block_position(itb, num0);
2132 else if (width_changed)
2134 _item_block_position(itb, num0);
2137 if (anything_changed)
2139 if (sd->calc_job) ecore_job_del(sd->calc_job);
2140 sd->calc_job = ecore_job_add(_calc_job, sd);
2145 _elm_genlist_pan_smart_calculate(Evas_Object *obj)
2147 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2148 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
2154 ELM_GENLIST_PAN_DATA_GET(obj, psd);
2156 //evas_event_freeze(evas_object_evas_get(obj));
2158 #if GENLIST_FX_SUPPORT
2159 if (psd->wsd->fx_playing) return;
2161 if (psd->wsd->pan_changed)
2163 _calc_job(psd->wsd);
2164 psd->wsd->pan_changed = EINA_FALSE;
2167 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2168 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2169 EINA_LIST_FOREACH(psd->wsd->group_items, l, git)
2171 #if GROUP_ITEMS_FEATURE
2172 git->item->want_realize = EINA_FALSE;
2174 _item_unrealize(git, EINA_TRUE);
2178 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
2180 itb->w = psd->wsd->minw;
2181 if (ELM_RECTS_INTERSECT(itb->x - psd->wsd->pan_x + ox,
2182 itb->y - psd->wsd->pan_y + oy,
2184 cvx, cvy, cvw, cvh))
2186 if ((!itb->realized) || (itb->changed))
2188 _item_block_realize(itb);
2190 // FIXME: difference from opensource
2191 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2192 sd->wd->calc_job = NULL;
2196 _item_block_position(itb, in);
2200 if (itb->realized) _item_block_unrealize(itb);
2204 #if GENLIST_PINCH_ZOOM_SUPPORT
2205 if (psd->wsd->pinch_zoom_mode) _pinch_items_recalc(psd->wsd);
2208 #if GROUP_ITEMS_FEATURE
2209 if ((!psd->wsd->reorder_it) || (psd->wsd->reorder_pan_move))
2210 _group_items_recalc(psd->wsd);
2212 if ((psd->wsd->reorder_mode) && (psd->wsd->reorder_it))
2214 if (psd->wsd->pan_y != psd->wsd->reorder_old_pan_y)
2215 psd->wsd->reorder_pan_move = EINA_TRUE;
2216 else psd->wsd->reorder_pan_move = EINA_FALSE;
2218 evas_object_raise(psd->wsd->VIEW(reorder_it));
2219 psd->wsd->reorder_old_pan_y = psd->wsd->pan_y;
2220 psd->wsd->start_time = ecore_loop_time_get();
2222 _item_auto_scroll(psd->wsd);
2224 psd->wsd->s_iface->content_pos_get(ELM_WIDGET_DATA(psd->wsd)->obj, &vx, &vy);
2225 psd->wsd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(psd->wsd)->obj,
2228 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);
2231 else if (psd->wsd->reorder_fast == -1)
2232 psd->wsd->s_iface->content_region_show(ELM_WIDGET_DATA(psd->wsd)->obj,
2233 vx, vy + 10, vw, vh);
2235 if (psd->wsd->size_changed)
2237 _changed_job(psd->wsd);
2238 psd->wsd->size_changed = EINA_FALSE;
2241 #if GENLIST_FX_SUPPORT
2242 psd->wsd->rendered = EINA_TRUE;
2243 if ((psd->wsd->fx_mode) && (!psd->wsd->queue))
2245 if (_elm_genlist_fx_capture(ELM_WIDGET_DATA(psd->wsd)->obj, 1))
2246 _elm_genlist_fx_play(ELM_WIDGET_DATA(psd->wsd)->obj);
2249 #if GENLIST_PINCH_ZOOM_SUPPORT
2250 if (psd->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND)
2251 psd->wsd->pinch_zoom_mode = ELM_GEN_PINCH_ZOOM_NONE;
2253 //evas_event_thaw(evas_object_evas_get(obj));
2254 //evas_event_thaw_eval(evas_object_evas_get(obj));
2258 _elm_genlist_pan_smart_set_user(Elm_Genlist_Pan_Smart_Class *sc)
2260 ELM_PAN_CLASS(sc)->base.add = _elm_genlist_pan_smart_add;
2261 ELM_PAN_CLASS(sc)->base.del = _elm_genlist_pan_smart_del;
2262 ELM_PAN_CLASS(sc)->base.move = _elm_genlist_pan_smart_move;
2263 ELM_PAN_CLASS(sc)->base.resize = _elm_genlist_pan_smart_resize;
2264 ELM_PAN_CLASS(sc)->base.calculate = _elm_genlist_pan_smart_calculate;
2266 ELM_PAN_CLASS(sc)->pos_set = _elm_genlist_pan_smart_pos_set;
2267 ELM_PAN_CLASS(sc)->pos_get = _elm_genlist_pan_smart_pos_get;
2268 ELM_PAN_CLASS(sc)->pos_max_get = _elm_genlist_pan_smart_pos_max_get;
2269 ELM_PAN_CLASS(sc)->pos_min_get = _elm_genlist_pan_smart_pos_min_get;
2270 ELM_PAN_CLASS(sc)->content_size_get =
2271 _elm_genlist_pan_smart_content_size_get;
2275 _item_multi_select_up(Elm_Genlist_Smart_Data *sd)
2277 Elm_Object_Item *prev;
2279 if (!sd->selected) return EINA_FALSE;
2280 if (!sd->multi) return EINA_FALSE;
2282 prev = elm_genlist_item_prev_get(sd->last_selected_item);
2283 if (!prev) return EINA_TRUE;
2285 if (elm_genlist_item_selected_get(prev))
2287 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2288 sd->last_selected_item = prev;
2289 elm_genlist_item_show
2290 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2294 elm_genlist_item_selected_set(prev, EINA_TRUE);
2295 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2301 _item_multi_select_down(Elm_Genlist_Smart_Data *sd)
2303 Elm_Object_Item *next;
2305 if (!sd->selected) return EINA_FALSE;
2306 if (!sd->multi) return EINA_FALSE;
2308 next = elm_genlist_item_next_get(sd->last_selected_item);
2309 if (!next) return EINA_TRUE;
2311 if (elm_genlist_item_selected_get(next))
2313 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2314 sd->last_selected_item = next;
2315 elm_genlist_item_show
2316 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2320 elm_genlist_item_selected_set(next, EINA_TRUE);
2321 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2328 _all_items_deselect(Elm_Genlist_Smart_Data *sd)
2330 if (!sd->selected) return EINA_FALSE;
2332 while (sd->selected)
2333 elm_genlist_item_selected_set(sd->selected->data, EINA_FALSE);
2339 _item_single_select_up(Elm_Genlist_Smart_Data *sd)
2345 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2347 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2350 prev = (Elm_Gen_Item *)elm_genlist_item_prev_get
2351 (sd->last_selected_item);
2353 if (!prev) return EINA_FALSE;
2355 _all_items_deselect(sd);
2357 elm_genlist_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
2358 elm_genlist_item_show((Elm_Object_Item *)prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2363 _item_single_select_down(Elm_Genlist_Smart_Data *sd)
2369 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2371 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2374 next = (Elm_Gen_Item *)elm_genlist_item_next_get
2375 (sd->last_selected_item);
2377 if (!next) return EINA_FALSE;
2379 _all_items_deselect(sd);
2381 elm_genlist_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
2382 elm_genlist_item_show
2383 ((Elm_Object_Item *)next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2389 _elm_genlist_smart_event(Evas_Object *obj,
2390 Evas_Object *src __UNUSED__,
2391 Evas_Callback_Type type,
2398 Evas_Coord step_x = 0;
2399 Evas_Coord step_y = 0;
2400 Evas_Coord page_x = 0;
2401 Evas_Coord page_y = 0;
2402 Elm_Object_Item *it;
2403 Evas_Event_Key_Down *ev = event_info;
2404 Evas_Coord pan_max_x = 0, pan_max_y = 0;
2406 ELM_GENLIST_DATA_GET(obj, sd);
2408 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2409 if (!sd->items) return EINA_FALSE;
2410 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
2411 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
2413 sd->s_iface->content_pos_get(obj, &x, &y);
2414 sd->s_iface->step_size_get(obj, &step_x, &step_y);
2415 sd->s_iface->page_size_get(obj, &page_x, &page_y);
2416 sd->s_iface->content_viewport_size_get(obj, &v_w, &v_h);
2418 if ((!strcmp(ev->keyname, "Left")) ||
2419 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
2423 else if ((!strcmp(ev->keyname, "Right")) ||
2424 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
2428 else if ((!strcmp(ev->keyname, "Up")) ||
2429 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
2431 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
2432 (_item_multi_select_up(sd)))
2433 || (_item_single_select_up(sd)))
2435 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2441 else if ((!strcmp(ev->keyname, "Down")) ||
2442 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
2444 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
2445 (_item_multi_select_down(sd)))
2446 || (_item_single_select_down(sd)))
2448 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2454 else if ((!strcmp(ev->keyname, "Home")) ||
2455 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
2457 it = elm_genlist_first_item_get(obj);
2458 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
2459 elm_genlist_item_selected_set(it, EINA_TRUE);
2460 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2463 else if ((!strcmp(ev->keyname, "End")) ||
2464 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
2466 it = elm_genlist_last_item_get(obj);
2467 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
2468 elm_genlist_item_selected_set(it, EINA_TRUE);
2469 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2472 else if ((!strcmp(ev->keyname, "Prior")) ||
2473 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
2476 y -= -(page_y * v_h) / 100;
2480 else if ((!strcmp(ev->keyname, "Next")) ||
2481 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
2484 y += -(page_y * v_h) / 100;
2488 else if (!strcmp(ev->keyname, "Escape"))
2490 if (!_all_items_deselect(sd)) return EINA_FALSE;
2491 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2494 else if (((!strcmp(ev->keyname, "Return")) ||
2495 (!strcmp(ev->keyname, "KP_Enter")) ||
2496 (!strcmp(ev->keyname, "space")))
2497 && (!sd->multi) && (sd->selected))
2499 it = elm_genlist_selected_item_get(obj);
2500 elm_genlist_item_expanded_set(it, !elm_genlist_item_expanded_get(it));
2501 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
2503 else return EINA_FALSE;
2505 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2506 _elm_genlist_pan_smart_pos_max_get(sd->pan_obj, &pan_max_x, &pan_max_y);
2508 if (x > pan_max_x) x = pan_max_x;
2510 if (y > pan_max_y) y = pan_max_y;
2512 sd->s_iface->content_pos_set(obj, x, y, EINA_TRUE);
2518 _elm_genlist_smart_sub_object_add(Evas_Object *obj,
2521 Elm_Widget_Smart_Class *parent_parent;
2523 parent_parent = (Elm_Widget_Smart_Class *)((Evas_Smart_Class *)
2524 _elm_genlist_parent_sc)->parent;
2526 /* skipping layout's code, which registers size hint changing
2527 * callback on sub objects. this is here because items'
2528 * content_get() routines may change hints on the objects after
2529 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
2530 * not needed at here anyway, so let's skip listening to those
2532 if (!parent_parent->sub_object_add(obj, sobj))
2539 _elm_genlist_smart_sub_object_del(Evas_Object *obj,
2542 ELM_GENLIST_DATA_GET(obj, sd);
2544 /* XXX: hack -- also skipping sizing recalculation on
2545 * sub-object-del. genlist's crazy code paths (like groups and
2546 * such) seem to issue a whole lot of deletions and Evas bitches
2547 * about too many recalculations */
2548 sd->on_sub_del = EINA_TRUE;
2550 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->sub_object_del(obj, sobj))
2553 sd->on_sub_del = EINA_FALSE;
2559 _elm_genlist_smart_on_focus(Evas_Object *obj)
2561 ELM_GENLIST_DATA_GET(obj, sd);
2563 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->on_focus(obj))
2566 if (elm_widget_focus_get(obj) && (sd->items) && (sd->selected) &&
2567 (!sd->last_selected_item))
2568 sd->last_selected_item = eina_list_data_get(sd->selected);
2574 _elm_genlist_smart_focus_next(const Evas_Object *obj,
2575 Elm_Focus_Direction dir,
2578 Evas_Coord x, y, w, h;
2579 Evas_Coord sx, sy, sw, sh;
2581 Eina_List *items = NULL;
2582 Eina_Bool done = EINA_FALSE;
2584 ELM_GENLIST_CHECK(obj) EINA_FALSE;
2585 ELM_GENLIST_DATA_GET(obj, sd);
2587 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
2589 EINA_INLIST_FOREACH(sd->blocks, itb)
2597 EINA_LIST_FOREACH(itb->items, l, it)
2601 evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
2603 /* check item which displays more than half of its size */
2604 if (ELM_RECTS_INTERSECT
2605 (x + (w / 2), y + (h / 2), 0, 0, sx, sy, sw, sh))
2606 items = eina_list_append(items, it->base.access_obj);
2608 if (!it->base.access_order) continue;
2612 EINA_LIST_FOREACH(it->base.access_order, subl, subo)
2613 items = eina_list_append(items, subo);
2617 else if (done) break;
2620 return elm_widget_focus_list_next_get
2621 (obj, items, eina_list_data_get, dir, next);
2625 _mirrored_set(Evas_Object *obj,
2628 ELM_GENLIST_DATA_GET(obj, sd);
2630 sd->s_iface->mirrored_set(obj, rtl);
2634 _elm_genlist_smart_theme(Evas_Object *obj)
2638 ELM_GENLIST_DATA_GET(obj, sd);
2640 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->theme(obj))
2643 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2644 _item_cache_all_free(sd);
2645 _mirrored_set(obj, elm_widget_mirrored_get(obj));
2648 // FIXME: difference from opensource
2649 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
2652 sd->item_width = sd->item_height = 0;
2653 sd->group_item_width = sd->group_item_height = 0;
2654 sd->minw = sd->minh = sd->realminw = 0;
2655 EINA_INLIST_FOREACH(sd->blocks, itb)
2660 if (itb->realized) _item_block_unrealize(itb);
2661 EINA_LIST_FOREACH(itb->items, l, it)
2662 it->item->mincalcd = EINA_FALSE;
2664 itb->changed = EINA_TRUE;
2666 if (sd->calc_job) ecore_job_del(sd->calc_job);
2667 sd->calc_job = NULL;
2668 elm_layout_sizing_eval(obj);
2669 sd->pan_changed = EINA_TRUE;
2670 evas_object_smart_changed(sd->pan_obj);
2671 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2672 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2677 /* FIXME: take off later. maybe this show region coords belong in the
2678 * interface (new api functions, set/get)? */
2680 _show_region_hook(void *data,
2683 Evas_Coord x, y, w, h;
2685 ELM_GENLIST_DATA_GET(data, sd);
2687 elm_widget_show_region_get(obj, &x, &y, &w, &h);
2688 //x & y are screen coordinates, Add with pan coordinates
2691 sd->s_iface->content_region_show(obj, x, y, w, h);
2695 _elm_genlist_smart_translate(Evas_Object *obj)
2697 evas_object_smart_callback_call(obj, "language,changed", NULL);
2703 _item_highlight(Elm_Gen_Item *it)
2705 const char *selectraise;
2706 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2708 if (elm_widget_item_disabled_get(it)) return;
2709 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2710 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2711 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2712 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2715 if (!sd->highlight || it->highlighted) return;
2716 #if GENLIST_PINCH_ZOOM_SUPPORT
2717 if (sd->pinch_zoom_mode) return;
2720 selectraise = edje_object_data_get(VIEW(it), "selectraise");
2721 if ((selectraise) && (!strcmp(selectraise, "on")))
2723 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2724 else evas_object_raise(VIEW(it));
2725 if ((it->item->group_item) && (it->item->group_item->realized))
2726 evas_object_raise(it->item->VIEW(group_item));
2728 it->highlighted = EINA_TRUE;
2730 if (it->deco_all_view)
2731 edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
2732 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
2733 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
2737 _item_unhighlight(Elm_Gen_Item *it)
2739 if (!it->highlighted) return;
2741 if (!it->item->nostacking)
2743 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
2745 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
2746 else evas_object_lower(VIEW(it));
2750 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2751 else evas_object_raise(VIEW(it));
2754 it->highlighted = EINA_FALSE;
2756 if (it->deco_all_view)
2757 edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
2758 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
2759 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it);
2763 _item_unselect(Elm_Gen_Item *it)
2765 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2766 _item_unhighlight(it);
2767 if (!it->selected) return;
2769 it->selected = EINA_FALSE;
2770 sd->selected = eina_list_remove(sd->selected, it);
2771 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
2775 _item_select(Elm_Gen_Item *it)
2777 Evas_Object *obj = WIDGET(it);
2778 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2779 if (elm_widget_item_disabled_get(it)) return;
2780 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2781 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
2782 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2783 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
2786 #if GENLIST_PINCH_ZOOM_SUPPORT
2787 if (IS_ROOT_PARENT_IT(it) && (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
2789 elm_genlist_pinch_zoom_mode_set(obj, ELM_GEN_PINCH_ZOOM_EXPAND);
2790 elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
2796 // FIXME: difference from upstream
2797 if ((GL_IT(it)->wsd->last_selected_item) &&
2798 (it != (Elm_Gen_Item *) GL_IT(it)->wsd->last_selected_item))
2799 _item_unfocusable_set
2800 ((Elm_Gen_Item *)GL_IT(it)->wsd->last_selected_item, EINA_TRUE);
2803 // Do not check selected because always select mode can be used
2804 _item_highlight(it);
2805 it->selected = EINA_TRUE;
2806 sd->selected = eina_list_append(sd->selected, it);
2807 sd->last_selected_item = (Elm_Object_Item *)it;
2809 if (it->func.func) it->func.func((void *)it->func.data, obj, it);
2810 if (!EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC))
2812 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
2816 _item_select_unselect(Elm_Gen_Item *it, Eina_Bool selected)
2818 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2819 Evas_Object *obj = ELM_WIDGET_DATA(sd)->obj;
2820 if (elm_widget_item_disabled_get(it)) return;
2822 evas_object_ref(obj);
2825 const Eina_List *l, *ll;
2827 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
2828 if (it2 != it) _item_unselect(it2);
2830 if (selected) _item_select(it);
2831 else _item_unselect(it);
2832 evas_object_unref(obj);
2836 _item_block_position_update(Eina_Inlist *list,
2841 EINA_INLIST_FOREACH(list, tmp)
2843 tmp->position = idx++;
2844 tmp->position_update = EINA_TRUE;
2849 _item_position_update(Eina_List *list,
2855 EINA_LIST_FOREACH(list, l, it)
2857 it->position = idx++;
2858 it->position_update = EINA_TRUE;
2863 _item_block_merge(Item_Block *left,
2869 EINA_LIST_FOREACH(right->items, l, it2)
2871 it2->item->block = left;
2873 left->changed = EINA_TRUE;
2875 left->items = eina_list_merge(left->items, right->items);
2879 _item_block_del(Elm_Gen_Item *it)
2882 Item_Block *itb = it->item->block;
2883 Eina_Bool block_changed = EINA_FALSE;
2885 itb->items = eina_list_remove(itb->items, it);
2887 itb->changed = EINA_TRUE;
2888 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
2889 GL_IT(it)->wsd->calc_job = ecore_job_add(_calc_job, GL_IT(it)->wsd);
2894 il = EINA_INLIST_GET(itb);
2895 itbn = (Item_Block *)(il->next);
2897 it->parent->item->items =
2898 eina_list_remove(it->parent->item->items, it);
2901 _item_block_position_update(il->next, itb->position);
2903 GL_IT(it)->wsd->blocks =
2904 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
2907 if (itbn) itbn->changed = EINA_TRUE;
2911 if (itb->count < (itb->sd->max_items_per_block / 2))
2916 il = EINA_INLIST_GET(itb);
2917 itbp = (Item_Block *)(il->prev);
2918 itbn = (Item_Block *)(il->next);
2920 /* merge block with previous */
2922 ((itbp->count + itb->count) <
2923 (itb->sd->max_items_per_block +
2924 (itb->sd->max_items_per_block / 2))))
2926 _item_block_merge(itbp, itb);
2927 _item_block_position_update
2928 (EINA_INLIST_GET(itb)->next, itb->position);
2929 GL_IT(it)->wsd->blocks = eina_inlist_remove
2930 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
2932 block_changed = EINA_TRUE;
2934 /* merge block with next */
2936 ((itbn->count + itb->count) <
2937 (itb->sd->max_items_per_block +
2938 (itb->sd->max_items_per_block / 2))))
2940 _item_block_merge(itb, itbn);
2941 _item_block_position_update
2942 (EINA_INLIST_GET(itbn)->next, itbn->position);
2943 GL_IT(it)->wsd->blocks =
2944 eina_inlist_remove(GL_IT(it)->wsd->blocks,
2945 EINA_INLIST_GET(itbn));
2947 block_changed = EINA_TRUE;
2954 GL_IT(it)->wsd->pan_changed = EINA_TRUE;
2955 evas_object_smart_changed(GL_IT(it)->wsd->pan_obj);
2956 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
2957 GL_IT(it)->wsd->calc_job = NULL;
2959 #if GENLIST_FX_SUPPORT
2960 it->item->block = NULL;
2965 _decorate_all_item_unrealize(Elm_Gen_Item *it)
2969 if ((!it) || (!it->item->decorate_all_item_realized)) return;
2971 #if GENLIST_FX_SUPPORT
2972 if ((GL_IT(it)->has_proxy_it) && (!GL_IT(it)->wsd->genlist_clearing))
2974 if (!eina_list_data_find(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it))
2975 GL_IT(it)->wsd->pending_unrealized_decorate_all_items =
2976 eina_list_append(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it);
2981 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
2982 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
2983 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2984 _elm_genlist_item_odd_even_update(it);
2985 _elm_genlist_item_state_update(it);
2987 edje_object_signal_emit
2988 (it->deco_all_view, "elm,state,decorate,disabled", "elm");
2989 edje_object_signal_emit
2990 (VIEW(it), "elm,state,decorate,disabled", "elm");
2991 edje_object_signal_emit
2992 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
2993 edje_object_message_signal_process(VIEW(it));
2994 edje_object_message_signal_process(it->deco_all_view);
2996 evas_object_del(it->deco_all_view);
2997 it->deco_all_view = NULL;
2998 elm_widget_stringlist_free(it->item->deco_all_texts);
2999 it->item->deco_all_texts = NULL;
3000 elm_widget_stringlist_free(it->item->deco_all_contents);
3001 it->item->deco_all_contents = NULL;
3002 elm_widget_stringlist_free(it->item->deco_all_states);
3003 it->item->deco_all_states = NULL;
3004 EINA_LIST_FREE (it->item->deco_all_content_objs, icon)
3005 evas_object_del(icon);
3007 _item_mouse_callbacks_del(it, it->deco_all_view);
3008 _item_mouse_callbacks_add(it, VIEW(it));
3010 it->item->decorate_all_item_realized = EINA_FALSE;
3014 _item_free_common(Elm_Gen_Item *it)
3016 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
3017 elm_widget_item_pre_notify_del(it);
3018 if (it->itc->func.del)
3019 it->itc->func.del((void *)it->base.data, WIDGET(it));
3020 if (it->tooltip.del_cb)
3021 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
3022 if (it->item->block) _item_block_del(it);
3024 it->parent->item->items =
3025 eina_list_remove(it->parent->item->items, it);
3026 if (it->item->queued) sd->queue = eina_list_remove(sd->queue, it);
3027 if (it->group) sd->group_items = eina_list_remove(sd->group_items, it);
3029 // FIXME: relative will be better to be fixed. it is too harsh.
3031 it->item->rel->item->rel_revs =
3032 eina_list_remove(it->item->rel->item->rel_revs, it);
3033 if (it->item->rel_revs)
3036 EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
3038 _item_sub_items_clear(it);
3040 #if GENLIST_ENTRY_SUPPORT
3041 it->item->unrealize_disabled = EINA_FALSE;
3044 if (it->selected) sd->selected = eina_list_remove(sd->selected, it);
3045 if (sd->show_item == it) sd->show_item = NULL;
3046 if (sd->anchor_item == it)
3049 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3050 if (!sd->anchor_item) sd->anchor_item =
3051 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3053 if (sd->expanded_item == it) sd->expanded_item = NULL;
3054 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3055 if (sd->state) eina_inlist_sorted_state_free(sd->state);
3057 if (sd->last_selected_item == (Elm_Object_Item *)it)
3058 sd->last_selected_item = NULL;
3062 ecore_timer_del(it->long_timer);
3063 it->long_timer = NULL;
3065 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
3067 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3072 _item_mouse_move_cb(void *data,
3073 Evas *evas __UNUSED__,
3077 EINA_SAFETY_ON_NULL_RETURN(data);
3078 Elm_Gen_Item *it = data;
3079 Elm_Genlist_Smart_Data *sd;
3080 Evas_Event_Mouse_Move *ev = event_info;
3081 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
3082 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
3084 sd = GL_IT(it)->wsd;
3086 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3088 if (!sd->on_hold) _item_unselect(it);
3089 sd->on_hold = EINA_TRUE;
3091 if (sd->multi_touched)
3093 sd->cur_x = ev->cur.canvas.x;
3094 sd->cur_y = ev->cur.canvas.y;
3097 if ((it->dragging) && (it->down))
3099 if (sd->movements == SWIPE_MOVES)
3100 sd->swipe = EINA_TRUE;
3103 sd->history[sd->movements].x = ev->cur.canvas.x;
3104 sd->history[sd->movements].y = ev->cur.canvas.y;
3105 if (abs((sd->history[sd->movements].x -
3106 sd->history[0].x)) > 40)
3107 sd->swipe = EINA_TRUE;
3113 ecore_timer_del(it->long_timer);
3114 it->long_timer = NULL;
3116 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
3119 if ((!it->down) || (sd->longpressed))
3123 ecore_timer_del(it->long_timer);
3124 it->long_timer = NULL;
3126 if ((sd->reorder_mode) && (sd->reorder_it))
3128 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3130 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
3131 sd->reorder_fast = 1;
3132 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
3133 sd->reorder_fast = -1;
3134 else sd->reorder_fast = 0;
3136 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
3138 if (!sd->reorder_start_y)
3139 sd->reorder_start_y = it->item->block->y + it->y;
3143 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
3144 y_pos = oy + oh - sd->reorder_it->item->h;
3148 if (it->deco_all_view)
3149 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
3150 else if (it->item->deco_it_view)
3152 (it, it->item->deco_it_view, it->item->scrl_x, y_pos);
3154 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
3156 if (sd->calc_job) ecore_job_del(sd->calc_job);
3157 sd->calc_job = ecore_job_add(_calc_job, sd);
3161 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3162 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3164 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3165 x = ev->cur.canvas.x - x;
3166 y = ev->cur.canvas.y - y;
3169 if (adx < 0) adx = -dx;
3173 if (ady < 0) ady = -dy;
3177 if ((adx > minw) || (ady > minh))
3179 it->dragging = EINA_TRUE;
3182 ecore_timer_del(it->long_timer);
3183 it->long_timer = NULL;
3188 evas_object_smart_callback_call
3189 (WIDGET(it), SIG_DRAG_START_UP, it);
3193 evas_object_smart_callback_call
3194 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3196 evas_object_smart_callback_call
3197 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3203 evas_object_smart_callback_call
3204 (WIDGET(it), SIG_DRAG_START_DOWN, it);
3208 evas_object_smart_callback_call
3209 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3211 evas_object_smart_callback_call
3212 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3219 _long_press_cb(void *data)
3221 Elm_Gen_Item *it = data, *it2;
3222 Elm_Genlist_Smart_Data *sd;
3225 sd = GL_IT(it)->wsd;
3227 it->long_timer = NULL;
3228 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
3229 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3230 return ECORE_CALLBACK_CANCEL;
3232 GL_IT(it)->wsd->longpressed = EINA_TRUE;
3233 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
3234 if ((GL_IT(it)->wsd->reorder_mode) && (!it->group))
3236 GL_IT(it)->wsd->reorder_it = it;
3237 GL_IT(it)->wsd->reorder_start_y = 0;
3238 if (it->deco_all_view)
3239 evas_object_raise(it->deco_all_view);
3241 evas_object_raise(VIEW(it));
3243 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
3244 sd->s_iface->bounce_allow_set
3245 (ELM_WIDGET_DATA(sd)->obj, EINA_FALSE, EINA_FALSE);
3247 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
3249 if (it != it2) _item_unselect(it2);
3252 // FIXME: difference from opensource
3253 if (it->item->items)
3255 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
3257 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
3259 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
3261 return ECORE_CALLBACK_RENEW;
3266 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
3268 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
3269 return ECORE_CALLBACK_RENEW;
3272 if (!GL_IT(it)->wsd->decorate_all_mode)
3273 edje_object_signal_emit
3274 (VIEW(it), "elm,state,reorder,enabled", "elm");
3277 return ECORE_CALLBACK_CANCEL;
3281 _swipe_do(Elm_Gen_Item *it)
3286 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3287 elm_widget_item_disabled_get(it)) return;
3289 GL_IT(it)->wsd->swipe = EINA_FALSE;
3290 for (i = 0; i < GL_IT(it)->wsd->movements; i++)
3292 sum += GL_IT(it)->wsd->history[i].x;
3293 if (abs(GL_IT(it)->wsd->history[0].y -
3294 GL_IT(it)->wsd->history[i].y) > 10) return;
3297 sum /= GL_IT(it)->wsd->movements;
3298 if (abs(sum - GL_IT(it)->wsd->history[0].x) <= 10) return;
3299 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
3303 _swipe_cancel(void *data)
3305 Elm_Gen_Item *it = data;
3307 if (!it) return ECORE_CALLBACK_CANCEL;
3308 GL_IT(it)->wsd->swipe = EINA_FALSE;
3309 GL_IT(it)->wsd->movements = 0;
3311 return ECORE_CALLBACK_RENEW;
3315 _multi_cancel(void *data)
3317 Elm_Genlist_Smart_Data *sd = data;
3319 if (!sd) return ECORE_CALLBACK_CANCEL;
3320 sd->multi_timeout = EINA_TRUE;
3322 return ECORE_CALLBACK_RENEW;
3326 _multi_touch_gesture_eval(void *data)
3328 Elm_Gen_Item *it = data;
3329 Evas_Coord minw = 0, minh = 0;
3330 Evas_Coord off_x, off_y, off_mx, off_my;
3332 GL_IT(it)->wsd->multi_touched = EINA_FALSE;
3333 if (GL_IT(it)->wsd->multi_timer)
3335 ecore_timer_del(GL_IT(it)->wsd->multi_timer);
3336 GL_IT(it)->wsd->multi_timer = NULL;
3338 if (GL_IT(it)->wsd->multi_timeout)
3340 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3344 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3345 off_x = abs(GL_IT(it)->wsd->cur_x - GL_IT(it)->wsd->prev_x);
3346 off_y = abs(GL_IT(it)->wsd->cur_y - GL_IT(it)->wsd->prev_y);
3347 off_mx = abs(GL_IT(it)->wsd->cur_mx - GL_IT(it)->wsd->prev_mx);
3348 off_my = abs(GL_IT(it)->wsd->cur_my - GL_IT(it)->wsd->prev_my);
3350 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
3351 || (off_my > minh)))
3353 if ((off_x + off_mx) > (off_y + off_my))
3355 if ((GL_IT(it)->wsd->cur_x > GL_IT(it)->wsd->prev_x)
3356 && (GL_IT(it)->wsd->cur_mx > GL_IT(it)->wsd->prev_mx))
3357 evas_object_smart_callback_call
3358 (WIDGET(it), SIG_MULTI_SWIPE_RIGHT, it);
3359 else if ((GL_IT(it)->wsd->cur_x < GL_IT(it)->wsd->prev_x)
3360 && (GL_IT(it)->wsd->cur_mx < GL_IT(it)->wsd->prev_mx))
3361 evas_object_smart_callback_call
3362 (WIDGET(it), SIG_MULTI_SWIPE_LEFT, it);
3363 else if (abs(GL_IT(it)->wsd->cur_x - GL_IT(it)->wsd->cur_mx) >
3364 abs(GL_IT(it)->wsd->prev_x - GL_IT(it)->wsd->prev_mx))
3365 evas_object_smart_callback_call
3366 (WIDGET(it), SIG_MULTI_PINCH_OUT, it);
3368 evas_object_smart_callback_call
3369 (WIDGET(it), SIG_MULTI_PINCH_IN, it);
3373 if ((GL_IT(it)->wsd->cur_y > GL_IT(it)->wsd->prev_y)
3374 && (GL_IT(it)->wsd->cur_my > GL_IT(it)->wsd->prev_my))
3375 evas_object_smart_callback_call
3376 (WIDGET(it), SIG_MULTI_SWIPE_DOWN, it);
3377 else if ((GL_IT(it)->wsd->cur_y < GL_IT(it)->wsd->prev_y)
3378 && (GL_IT(it)->wsd->cur_my < GL_IT(it)->wsd->prev_my))
3379 evas_object_smart_callback_call
3380 (WIDGET(it), SIG_MULTI_SWIPE_UP, it);
3381 else if (abs(GL_IT(it)->wsd->cur_y - GL_IT(it)->wsd->cur_my) >
3382 abs(GL_IT(it)->wsd->prev_y - GL_IT(it)->wsd->prev_my))
3384 evas_object_smart_callback_call
3385 (WIDGET(it), SIG_MULTI_PINCH_OUT, it);
3386 #if GENLIST_PINCH_ZOOM_SUPPORT
3387 if (IS_ROOT_PARENT_IT(it) && (GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
3389 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj, ELM_GEN_PINCH_ZOOM_EXPAND);
3390 elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
3396 evas_object_smart_callback_call
3397 (WIDGET(it), SIG_MULTI_PINCH_IN, it);
3398 #if GENLIST_PINCH_ZOOM_SUPPORT
3399 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj,
3400 ELM_GEN_PINCH_ZOOM_CONTRACT);
3406 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3410 _item_multi_down_cb(void *data,
3411 Evas *evas __UNUSED__,
3412 Evas_Object *obj __UNUSED__,
3415 Elm_Gen_Item *it = data;
3416 Evas_Event_Multi_Down *ev = event_info;
3418 if ((GL_IT(it)->wsd->multi_device != 0) || (GL_IT(it)->wsd->multi_touched)
3419 || (GL_IT(it)->wsd->multi_timeout))
3422 GL_IT(it)->wsd->multi_device = ev->device;
3423 GL_IT(it)->wsd->multi_down = EINA_TRUE;
3424 GL_IT(it)->wsd->multi_touched = EINA_TRUE;
3425 GL_IT(it)->wsd->prev_mx = ev->canvas.x;
3426 GL_IT(it)->wsd->prev_my = ev->canvas.y;
3428 if (!GL_IT(it)->wsd->wasselected)
3430 GL_IT(it)->wsd->wasselected = EINA_FALSE;
3434 ecore_timer_del(it->long_timer);
3435 it->long_timer = NULL;
3439 it->dragging = EINA_FALSE;
3440 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
3442 if (it->item->swipe_timer)
3444 ecore_timer_del(it->item->swipe_timer);
3445 it->item->swipe_timer = NULL;
3447 GL_IT(it)->wsd->longpressed = EINA_FALSE;
3448 if (GL_IT(it)->wsd->on_hold)
3450 GL_IT(it)->wsd->swipe = EINA_FALSE;
3451 GL_IT(it)->wsd->movements = 0;
3452 GL_IT(it)->wsd->on_hold = EINA_FALSE;
3457 _item_multi_up_cb(void *data,
3458 Evas *evas __UNUSED__,
3459 Evas_Object *obj __UNUSED__,
3462 Elm_Gen_Item *it = data;
3463 Evas_Event_Multi_Up *ev = event_info;
3465 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3466 GL_IT(it)->wsd->multi_device = 0;
3467 GL_IT(it)->wsd->multi_down = EINA_FALSE;
3468 if (GL_IT(it)->wsd->mouse_down) return;
3469 _multi_touch_gesture_eval(data);
3473 _item_multi_move_cb(void *data,
3474 Evas *evas __UNUSED__,
3475 Evas_Object *obj __UNUSED__,
3478 Elm_Gen_Item *it = data;
3479 Evas_Event_Multi_Move *ev = event_info;
3481 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3482 GL_IT(it)->wsd->cur_mx = ev->cur.canvas.x;
3483 GL_IT(it)->wsd->cur_my = ev->cur.canvas.y;
3487 // FIXME: difference from upstream
3489 _item_unfocusable_set(Elm_Gen_Item *it, Eina_Bool unfocus)
3492 Evas_Object *item_obj;
3493 Evas_Object *obj = WIDGET(it);
3497 EINA_LIST_FOREACH(it->content_objs, l, item_obj)
3499 if (unfocus) elm_widget_focused_object_clear(item_obj);
3500 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3502 EINA_LIST_FOREACH(it->item->flip_content_objs, l, item_obj)
3504 if (unfocus) elm_widget_focused_object_clear(item_obj);
3505 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3507 EINA_LIST_FOREACH(it->item->deco_all_content_objs, l, item_obj)
3509 if (unfocus) elm_widget_focused_object_clear(item_obj);
3510 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3512 it->can_focus = !unfocus;
3518 _item_mouse_down_cb(void *data,
3519 Evas *evas __UNUSED__,
3523 Evas_Event_Mouse_Down *ev = event_info;
3524 Elm_Gen_Item *it = data;
3525 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
3528 if (ev->button != 1) return;
3530 _item_unfocusable_set(it, EINA_FALSE);
3532 it->down = EINA_TRUE;
3533 it->dragging = EINA_FALSE;
3534 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3535 it->dx = ev->canvas.x - x;
3536 it->dy = ev->canvas.y - y;
3537 sd->mouse_down = EINA_TRUE;
3538 if (!sd->multi_touched)
3540 sd->prev_x = ev->canvas.x;
3541 sd->prev_y = ev->canvas.y;
3542 sd->multi_timeout = EINA_FALSE;
3543 if (sd->multi_timer) ecore_timer_del(sd->multi_timer);
3544 sd->multi_timer = ecore_timer_add(1, _multi_cancel, sd);
3546 sd->longpressed = EINA_FALSE;
3547 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3549 sd->on_hold = EINA_TRUE;
3552 else sd->on_hold = EINA_FALSE;
3553 _item_highlight(it);
3554 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
3555 if ((!elm_widget_item_disabled_get(it)) &&
3556 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3558 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
3559 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
3561 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
3562 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
3563 if (it->long_timer) ecore_timer_del(it->long_timer);
3565 it->long_timer = ecore_timer_add
3566 (sd->longpress_timeout, _long_press_cb, it);
3568 it->long_timer = NULL;
3569 sd->swipe = EINA_FALSE;
3574 _item_block_new(Elm_Genlist_Smart_Data *sd,
3579 itb = calloc(1, sizeof(Item_Block));
3580 if (!itb) return NULL;
3584 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
3585 _item_block_position_update(sd->blocks, 0);
3589 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3590 itb->position_update = EINA_TRUE;
3591 if (sd->blocks != EINA_INLIST_GET(itb))
3594 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
3606 _item_block_add(Elm_Genlist_Smart_Data *sd,
3609 Item_Block *itb = NULL;
3616 itb = calloc(1, sizeof(Item_Block));
3617 if (!itb) return EINA_FALSE;
3619 if (!it->item->rel->item->block)
3622 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3623 itb->items = eina_list_append(itb->items, it);
3624 itb->position_update = EINA_TRUE;
3625 it->position = eina_list_count(itb->items);
3626 it->position_update = EINA_TRUE;
3628 if (sd->blocks != EINA_INLIST_GET(itb))
3632 (EINA_INLIST_GET(itb)->prev))->position + 1;
3643 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3644 if (it->item->before)
3646 sd->blocks = eina_inlist_prepend_relative
3647 (sd->blocks, EINA_INLIST_GET(itb),
3648 EINA_INLIST_GET(it->item->rel->item->block));
3650 eina_list_prepend_relative_list(itb->items, it, tmp);
3652 /* Update index from where we prepended */
3653 _item_position_update
3654 (eina_list_prev(tmp), it->item->rel->position);
3655 _item_block_position_update
3656 (EINA_INLIST_GET(itb),
3657 it->item->rel->item->block->position);
3661 sd->blocks = eina_inlist_append_relative
3662 (sd->blocks, EINA_INLIST_GET(itb),
3663 EINA_INLIST_GET(it->item->rel->item->block));
3665 eina_list_append_relative_list(itb->items, it, tmp);
3667 /* Update block index from where we appended */
3668 _item_position_update
3669 (eina_list_next(tmp), it->item->rel->position + 1);
3670 _item_block_position_update
3671 (EINA_INLIST_GET(itb),
3672 it->item->rel->item->block->position + 1);
3678 if (it->item->before)
3682 itb = (Item_Block *)(sd->blocks);
3683 if (itb->count >= sd->max_items_per_block)
3685 itb = _item_block_new(sd, EINA_TRUE);
3686 if (!itb) return EINA_FALSE;
3691 itb = _item_block_new(sd, EINA_TRUE);
3692 if (!itb) return EINA_FALSE;
3694 itb->items = eina_list_prepend(itb->items, it);
3696 _item_position_update(itb->items, 0);
3702 itb = (Item_Block *)(sd->blocks->last);
3703 if (itb->count >= sd->max_items_per_block)
3705 itb = _item_block_new(sd, EINA_FALSE);
3706 if (!itb) return EINA_FALSE;
3711 itb = _item_block_new(sd, EINA_FALSE);
3712 if (!itb) return EINA_FALSE;
3714 itb->items = eina_list_append(itb->items, it);
3715 it->position = eina_list_count(itb->items);
3723 if (it->item->rel->item->queued)
3725 /* NOTE: for a strange reason eina_list and eina_inlist
3726 don't have the same property on sorted insertion
3727 order, so the queue is not always ordered like the
3728 item list. This lead to issue where we depend on an
3729 item that is not yet created. As a quick work around,
3730 we reschedule the calc of the item and stop reordering
3731 the list to prevent any nasty issue to show up here.
3733 sd->queue = eina_list_append(sd->queue, it);
3734 sd->requeued = EINA_TRUE;
3735 it->item->queued = EINA_TRUE;
3739 itb = it->item->rel->item->block;
3740 if (!itb) goto newblock;
3741 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3742 if (it->item->before)
3744 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3745 _item_position_update
3746 (eina_list_prev(tmp), it->item->rel->position);
3750 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3751 _item_position_update
3752 (eina_list_next(tmp), it->item->rel->position + 1);
3757 itb->changed = EINA_TRUE;
3758 it->item->block = itb;
3759 if (itb->sd->calc_job) ecore_job_del(itb->sd->calc_job);
3760 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd);
3762 if (itb->count > itb->sd->max_items_per_block)
3767 Eina_Bool done = EINA_FALSE;
3769 newc = itb->count / 2;
3771 if (EINA_INLIST_GET(itb)->prev)
3773 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3775 if (itbp->count + newc < sd->max_items_per_block / 2)
3777 /* moving items to previous block */
3778 while ((itb->count > newc) && (itb->items))
3780 it2 = eina_list_data_get(itb->items);
3781 itb->items = eina_list_remove_list
3782 (itb->items, itb->items);
3785 itbp->items = eina_list_append(itbp->items, it2);
3786 it2->item->block = itbp;
3794 if (!done && EINA_INLIST_GET(itb)->next)
3796 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3798 if (itbn->count + newc < sd->max_items_per_block / 2)
3800 /* moving items to next block */
3801 while ((itb->count > newc) && (itb->items))
3805 l = eina_list_last(itb->items);
3806 it2 = eina_list_data_get(l);
3807 itb->items = eina_list_remove_list(itb->items, l);
3810 itbn->items = eina_list_prepend(itbn->items, it2);
3811 it2->item->block = itbn;
3821 /* moving items to new block */
3822 itb2 = calloc(1, sizeof(Item_Block));
3823 if (!itb2) return EINA_FALSE;
3826 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
3827 EINA_INLIST_GET(itb));
3828 itb2->changed = EINA_TRUE;
3829 while ((itb->count > newc) && (itb->items))
3833 l = eina_list_last(itb->items);
3835 itb->items = eina_list_remove_list(itb->items, l);
3838 itb2->items = eina_list_prepend(itb2->items, it2);
3839 it2->item->block = itb2;
3849 _item_process(Elm_Genlist_Smart_Data *sd,
3852 if (!_item_block_add(sd, it)) return 1;
3854 _item_block_realize(it->item->block);
3860 _item_process_post(Elm_Genlist_Smart_Data *sd,
3864 Eina_Bool show_me = EINA_FALSE;
3866 if (it->item->block->changed)
3868 show_me = _item_block_recalc
3869 (it->item->block, it->item->block->num, qadd);
3870 it->item->block->changed = 0;
3871 if (sd->pan_changed)
3873 if (sd->calc_job) ecore_job_del(sd->calc_job);
3874 sd->calc_job = NULL;
3876 sd->pan_changed = EINA_FALSE;
3879 if (show_me) it->item->block->show_me = EINA_TRUE;
3881 /* when prepending, move the scroller along with the first selected
3882 * item to create the illusion that we're watching the selected
3883 * item this prevents the selected item being scrolled off the
3886 if (sd->selected && it->item->before)
3891 it2 = sd->selected->data;
3892 if (!it2->item->block) return;
3893 sd->s_iface->content_pos_get(ELM_WIDGET_DATA(sd)->obj, NULL, &y);
3894 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
3895 if ((it->y + it->item->block->y > y + h) ||
3896 (it->y + it->item->block->y + it->item->h < y))
3897 /* offscreen, just update */
3898 sd->s_iface->content_region_show
3899 (ELM_WIDGET_DATA(sd)->obj, it2->x + it2->item->block->x, y,
3900 it2->item->block->w, h);
3902 sd->s_iface->content_region_show
3903 (ELM_WIDGET_DATA(sd)->obj, it->x + it->item->block->x,
3904 y + it->item->h, it->item->block->w, h);
3909 _queue_process(Elm_Genlist_Smart_Data *sd)
3914 t0 = ecore_loop_time_get();
3915 for (n = 0; (sd->queue) && (n < 128); n++)
3919 it = eina_list_data_get(sd->queue);
3920 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
3921 it->item->queued = EINA_FALSE;
3922 if (_item_process(sd, it)) continue;
3923 t = ecore_time_get();
3924 _item_process_post(sd, it, EINA_TRUE);
3925 /* same as eina_inlist_count > 1 */
3926 if (sd->blocks && sd->blocks->next)
3928 if ((t - t0) > (ecore_animator_frametime_get())) break;
3935 _item_idle_enterer(void *data)
3937 Elm_Genlist_Smart_Data *sd = data;
3939 if (sd->prev_viewport_w == 0) return ECORE_CALLBACK_RENEW;
3940 if (_queue_process(sd) > 0)
3943 // Job always be alive because idle_enterer should be alive
3944 if (sd->calc_job) ecore_job_del(sd->calc_job);
3945 sd->calc_job = ecore_job_add(_calc_job, sd);
3949 sd->queue_idle_enterer = NULL;
3950 return ECORE_CALLBACK_CANCEL;
3953 #if GENLIST_FX_SUPPORT
3954 if (sd->fx_first_captured)
3955 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj);
3957 return ECORE_CALLBACK_RENEW;
3961 _item_queue(Elm_Genlist_Smart_Data *sd,
3965 if (it->item->queued) return;
3967 it->item->queued = EINA_TRUE;
3968 if (cb && !sd->requeued)
3969 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
3971 sd->queue = eina_list_append(sd->queue, it);
3973 if (sd->queue_idle_enterer)
3974 ecore_idle_enterer_del(sd->queue_idle_enterer);
3975 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd);
3977 if (sd->prev_viewport_w != 0)
3979 while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
3982 while ((sd->queue) && (sd->blocks) &&
3983 (sd->homogeneous) && (sd->mode == ELM_LIST_COMPRESS))
3988 /* If the application wants to know the relative item, use
3989 * elm_genlist_item_prev_get(it)*/
3991 _item_move_after(Elm_Gen_Item *it,
3992 Elm_Gen_Item *after)
3996 if (it == after) return;
3998 GL_IT(it)->wsd->items =
3999 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
4000 if (it->item->block) _item_block_del(it);
4002 GL_IT(it)->wsd->items = eina_inlist_append_relative
4003 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4004 it->item->rel = after;
4005 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
4006 it->item->before = EINA_FALSE;
4007 if (after->item->group_item) it->item->group_item = after->item->group_item;
4008 _item_queue(GL_IT(it)->wsd, it, NULL);
4010 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4014 _access_activate_cb(void *data __UNUSED__,
4015 Evas_Object *part_obj __UNUSED__,
4016 Elm_Object_Item *item)
4018 _item_select_unselect((Elm_Gen_Item *)item, EINA_TRUE);
4021 /* If the application wants to know the relative item, use
4022 * elm_genlist_item_next_get(it)*/
4024 _item_move_before(Elm_Gen_Item *it,
4025 Elm_Gen_Item *before)
4028 if (!before) return;
4029 if (it == before) return;
4031 GL_IT(it)->wsd->items =
4032 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
4033 if (it->item->block) _item_block_del(it);
4034 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
4035 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4036 it->item->rel = before;
4037 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
4038 it->item->before = EINA_TRUE;
4039 if (before->item->group_item)
4040 it->item->group_item = before->item->group_item;
4041 _item_queue(GL_IT(it)->wsd, it, NULL);
4043 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4047 _item_mouse_up_cb(void *data,
4048 Evas *evas __UNUSED__,
4049 Evas_Object *obj __UNUSED__,
4052 Evas_Event_Mouse_Up *ev = event_info;
4053 Eina_Bool dragged = EINA_FALSE;
4054 Elm_Genlist_Smart_Data *sd;
4055 Elm_Gen_Item *it = data;
4057 if (ev->button != 1) return;
4058 it->down = EINA_FALSE;
4059 sd = GL_IT(it)->wsd;
4061 sd->mouse_down = EINA_FALSE;
4062 if (sd->multi_touched)
4064 if ((!sd->multi) && (!it->selected) && (it->highlighted))
4065 _item_unhighlight(it);
4066 if (sd->multi_down) return;
4067 _multi_touch_gesture_eval(data);
4072 ecore_timer_del(it->long_timer);
4073 it->long_timer = NULL;
4077 it->dragging = EINA_FALSE;
4078 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
4081 if (it->item->swipe_timer)
4083 ecore_timer_del(it->item->swipe_timer);
4084 it->item->swipe_timer = NULL;
4086 if (sd->multi_timer)
4088 ecore_timer_del(sd->multi_timer);
4089 sd->multi_timer = NULL;
4090 sd->multi_timeout = EINA_FALSE;
4092 sd->on_hold = EINA_FALSE;
4093 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4095 if (sd->swipe) _swipe_do(data);
4096 sd->longpressed = EINA_FALSE;
4099 if ((sd->reorder_mode) && (sd->reorder_it))
4101 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
4102 sd->reorder_fast = 0;
4104 if (sd->reorder_rel &&
4105 (sd->reorder_it->parent == sd->reorder_rel->parent))
4107 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
4108 _item_move_before(sd->reorder_it, sd->reorder_rel);
4110 _item_move_after(sd->reorder_it, sd->reorder_rel);
4111 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4115 if (sd->calc_job) ecore_job_del(sd->calc_job);
4116 sd->calc_job = ecore_job_add(_calc_job, sd);
4118 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
4119 sd->reorder_it = sd->reorder_rel = NULL;
4120 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4121 sd->s_iface->bounce_allow_set
4122 (ELM_WIDGET_DATA(sd)->obj, sd->h_bounce, sd->v_bounce);
4126 if (it->want_unrealize && !(it->item->unrealize_disabled))
4128 _item_unrealize(it, EINA_FALSE);
4129 if (it->item->block->want_unrealize)
4130 _item_block_unrealize(it->item->block);
4135 if (!sd->longpressed)
4136 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
4137 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
4138 _item_select_unselect(it, EINA_TRUE);
4139 else _item_select_unselect(it, !it->selected);
4141 _item_unhighlight(it);
4145 _item_mouse_callbacks_add(Elm_Gen_Item *it,
4148 evas_object_event_callback_add
4149 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4150 evas_object_event_callback_add
4151 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4152 evas_object_event_callback_add
4153 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4154 evas_object_event_callback_add
4155 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4156 evas_object_event_callback_add
4157 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4158 evas_object_event_callback_add
4159 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4163 _item_mouse_callbacks_del(Elm_Gen_Item *it,
4166 evas_object_event_callback_del_full
4167 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4168 evas_object_event_callback_del_full
4169 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4170 evas_object_event_callback_del_full
4171 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4172 evas_object_event_callback_del_full
4173 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4174 evas_object_event_callback_del_full
4175 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4176 evas_object_event_callback_del_full
4177 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4181 _scroll_hold_timer_cb(void *data)
4183 Elm_Genlist_Smart_Data *sd = data;
4185 if (!data) return ECORE_CALLBACK_CANCEL;
4187 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4188 sd->scr_hold_timer = NULL;
4190 return ECORE_CALLBACK_CANCEL;
4194 _decorate_item_finished_signal_cb(void *data,
4196 const char *emission __UNUSED__,
4197 const char *source __UNUSED__)
4199 Elm_Gen_Item *it = data;
4202 if (!data || !obj) return;
4203 if ((!it->realized) || (!it->item->deco_it_view)) return;
4205 it->item->nocache_once = EINA_FALSE;
4206 _decorate_item_unrealize(it);
4207 if (it->item->group_item)
4208 evas_object_raise(it->item->VIEW(group_item));
4210 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
4211 GL_IT(it)->wsd->decorate_it_type);
4212 edje_object_signal_callback_del_full
4213 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
4217 _item_mode_content_unrealize(Elm_Gen_Item *it,
4218 Evas_Object *target,
4221 Eina_List **contents_list)
4223 Eina_List *res = *contents_list;
4225 if (it->itc->func.content_get)
4229 Evas_Object *ic = NULL;
4231 EINA_LIST_FOREACH(*source, l, key)
4233 if (parts && fnmatch(parts, key, FNM_PERIOD))
4236 ic = edje_object_part_swallow_get(target, key);
4239 res = eina_list_remove(res, ic);
4240 edje_object_part_unswallow(target, ic);
4241 evas_object_del(ic);
4250 _item_content_unrealize(Elm_Gen_Item *it,
4251 Evas_Object *target,
4255 Eina_List *res = it->content_objs;
4257 if (it->itc->func.content_get)
4261 Evas_Object *ic = NULL;
4263 EINA_LIST_FOREACH(*source, l, key)
4265 if (parts && fnmatch(parts, key, FNM_PERIOD))
4268 ic = edje_object_part_swallow_get(target, key);
4271 res = eina_list_remove(res, ic);
4272 edje_object_part_unswallow(target, ic);
4273 // FIXME: If parent-child relationship was broken before 'ic'
4274 // is deleted, freeze_pop will not be called. ex) elm_slider
4275 // If layout is used instead of edje, this problme can be
4277 if (0 != elm_widget_scroll_freeze_get(ic))
4278 elm_widget_scroll_freeze_pop(ic);
4279 evas_object_del(ic);
4288 _item_block_recalc(Item_Block *itb,
4292 const Eina_List *l, *ll;
4294 Evas_Coord minw = 0, minh = 0;
4295 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
4299 EINA_LIST_FOREACH_SAFE(itb->items, l, ll, it)
4301 show_me |= it->item->show_me;
4306 if (!it->item->mincalcd) changed = EINA_TRUE;
4309 _item_realize(it, in, EINA_TRUE);
4310 _item_unrealize(it, EINA_TRUE);
4315 if ((itb->sd->homogeneous) &&
4316 (itb->sd->mode == ELM_LIST_COMPRESS))
4320 it->item->w = it->item->minw =
4321 GL_IT(it)->wsd->group_item_width;
4322 it->item->h = it->item->minh =
4323 GL_IT(it)->wsd->group_item_height;
4327 it->item->w = it->item->minw =
4328 GL_IT(it)->wsd->item_width;
4329 it->item->h = it->item->minh =
4330 GL_IT(it)->wsd->item_height;
4335 _item_realize(it, in, EINA_TRUE);
4336 _item_unrealize(it, EINA_TRUE);
4342 if (!it->item->mincalcd) changed = EINA_TRUE;
4343 _item_realize(it, in, EINA_FALSE);
4345 minh += it->item->minh;
4346 if (minw < it->item->minw) minw = it->item->minw;
4350 #if GENLIST_PINCH_ZOOM_SUPPORT
4351 if (IS_ROOT_PARENT_IT(it))
4352 it->item->pan_scrl_y = itb->y + it->y;
4356 if (changed) itb->sd->pan_changed = changed;
4359 itb->changed = EINA_FALSE;
4360 itb->position_update = EINA_FALSE;
4366 _update_job(void *data)
4368 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
4369 Elm_Genlist_Smart_Data *sd = data;
4374 sd->update_job = NULL;
4377 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4378 EINA_INLIST_FOREACH(sd->blocks, itb)
4380 Evas_Coord itminw, itminh;
4387 _item_block_position(itb, num);
4391 recalc = EINA_FALSE;
4392 EINA_LIST_FOREACH(itb->items, l2, it)
4394 if (it->item->updateme)
4396 itminw = it->item->minw;
4397 itminh = it->item->minh;
4399 it->item->updateme = EINA_FALSE;
4402 _item_unrealize(it, EINA_FALSE);
4403 _item_realize(it, num, EINA_FALSE);
4404 position = EINA_TRUE;
4408 _item_realize(it, num, EINA_TRUE);
4409 _item_unrealize(it, EINA_TRUE);
4411 if ((it->item->minw != itminw) || (it->item->minh != itminh))
4416 itb->updateme = EINA_FALSE;
4419 position = EINA_TRUE;
4420 itb->changed = EINA_TRUE;
4421 _item_block_recalc(itb, num0, EINA_FALSE);
4422 _item_block_position(itb, num0);
4427 if (sd->calc_job) ecore_job_del(sd->calc_job);
4428 sd->calc_job = ecore_job_add(_calc_job, sd);
4430 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4431 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4435 _scroll_animate_start_cb(Evas_Object *obj,
4436 void *data __UNUSED__)
4438 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
4442 _scroll_animate_stop_cb(Evas_Object *obj,
4443 void *data __UNUSED__)
4445 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
4449 _scroll_drag_start_cb(Evas_Object *obj,
4450 void *data __UNUSED__)
4452 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
4456 _scroll_drag_stop_cb(Evas_Object *obj,
4457 void *data __UNUSED__)
4459 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
4463 _edge_left_cb(Evas_Object *obj,
4464 void *data __UNUSED__)
4466 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
4470 _edge_right_cb(Evas_Object *obj,
4471 void *data __UNUSED__)
4473 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
4477 _edge_top_cb(Evas_Object *obj,
4478 void *data __UNUSED__)
4480 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
4484 _edge_bottom_cb(Evas_Object *obj,
4485 void *data __UNUSED__)
4487 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
4491 _vbar_drag_cb(Evas_Object *obj,
4492 void *data __UNUSED__)
4494 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
4498 _vbar_press_cb(Evas_Object *obj,
4499 void *data __UNUSED__)
4501 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
4505 _vbar_unpress_cb(Evas_Object *obj,
4506 void *data __UNUSED__)
4508 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
4512 _hbar_drag_cb(Evas_Object *obj,
4513 void *data __UNUSED__)
4515 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
4519 _hbar_press_cb(Evas_Object *obj,
4520 void *data __UNUSED__)
4522 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
4526 _hbar_unpress_cb(Evas_Object *obj,
4527 void *data __UNUSED__)
4529 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
4533 _decorate_item_realize(Elm_Gen_Item *it)
4536 if (it->item->deco_it_view) return;
4538 //evas_event_freeze(evas_object_evas_get(obj));
4539 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
4540 edje_object_scale_set
4541 (it->item->deco_it_view, elm_widget_scale_get(WIDGET(it)) *
4542 elm_config_scale_get());
4543 evas_object_smart_member_add
4544 (it->item->deco_it_view, GL_IT(it)->wsd->pan_obj);
4545 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
4547 strncpy(buf, "item", sizeof(buf));
4548 if (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)
4549 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
4551 if (it->item->order_num_in & 0x1)
4552 strncat(buf, "_odd", sizeof(buf) - strlen(buf));
4553 strncat(buf, "/", sizeof(buf) - strlen(buf));
4554 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
4556 elm_widget_theme_object_set
4557 (WIDGET(it), it->item->deco_it_view, "genlist", buf,
4558 elm_widget_style_get(WIDGET(it)));
4559 edje_object_mirrored_set
4560 (it->item->deco_it_view, elm_widget_mirrored_get(WIDGET(it)));
4562 /* signal callback add */
4563 evas_object_event_callback_add
4564 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb,
4566 evas_object_event_callback_add
4567 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4568 evas_object_event_callback_add
4569 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb,
4572 if (eina_list_count(it->item->deco_it_content_objs) != 0)
4573 ERR_ABORT("If you see this error, please notify us and we"
4576 /* text_get, content_get, state_get */
4578 (it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
4579 if (!it->item->deco_it_contents)
4580 it->item->deco_it_contents =
4581 elm_widget_stringlist_get
4582 (edje_object_data_get(it->item->deco_it_view, "contents"));
4583 it->item->deco_it_content_objs =
4584 _item_mode_content_realize
4585 (it, it->item->deco_it_view, &it->item->deco_it_contents, NULL,
4586 &it->item->deco_it_content_objs);
4588 (it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
4589 edje_object_part_swallow
4590 (it->item->deco_it_view,
4591 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
4593 it->want_unrealize = EINA_FALSE;
4594 //evas_event_thaw(evas_object_evas_get(obj));
4595 //evas_event_thaw_eval(evas_object_evas_get(obj));
4599 _decorate_item_set(Elm_Gen_Item *it)
4601 Elm_Genlist_Smart_Data *sd;
4606 sd = GL_IT(it)->wsd;
4609 it->item->nocache_once = EINA_TRUE;
4611 if (sd->scr_hold_timer)
4613 ecore_timer_del(sd->scr_hold_timer);
4614 sd->scr_hold_timer = NULL;
4616 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
4617 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
4619 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4620 _decorate_item_realize(it);
4621 if (it->item->group_item)
4622 evas_object_raise(it->item->VIEW(group_item));
4624 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
4625 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4626 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4628 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
4629 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4633 _decorate_item_unset(Elm_Genlist_Smart_Data *sd)
4635 char buf[1024], buf2[1024];
4638 if (!sd->mode_item) return;
4641 it->item->nocache_once = EINA_TRUE;
4643 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
4644 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
4645 sd->decorate_it_type);
4646 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4647 edje_object_signal_callback_add
4648 (it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb,
4650 sd->mode_item = NULL;
4654 // FIXME: difference from upstream
4656 _mouse_down_scroller(void *data,
4657 Evas *evas __UNUSED__,
4658 Evas_Object *obj __UNUSED__,
4659 void *event_info __UNUSED__)
4661 Widget_Data *wd = elm_widget_data_get(data);
4664 wd->drag_started = EINA_FALSE;
4668 _mouse_up_scroller(void *data,
4669 Evas *evas __UNUSED__,
4670 Evas_Object *obj __UNUSED__,
4671 void *event_info __UNUSED__)
4673 Widget_Data *wd = elm_widget_data_get(data);
4676 wd->drag_started = EINA_FALSE;
4680 _mouse_move_scroller(void *data,
4681 Evas *evas __UNUSED__,
4682 Evas_Object *obj __UNUSED__,
4685 Widget_Data *wd = elm_widget_data_get(data);
4686 Evas_Event_Mouse_Move *ev = event_info;
4687 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
4690 if (wd->drag_started) return;
4692 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4693 dx = ev->cur.canvas.x - ev->prev.canvas.x;
4694 dy = ev->cur.canvas.y - ev->prev.canvas.y;
4697 if (adx < 0) adx = -dx;
4698 if (ady < 0) ady = -dy;
4699 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
4703 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
4704 wd->drag_started = EINA_TRUE;
4708 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
4709 wd->drag_started = EINA_TRUE;
4716 _elm_genlist_smart_add(Evas_Object *obj)
4718 Evas_Coord minw, minh;
4719 Elm_Genlist_Pan_Smart_Data *pan_data;
4721 EVAS_SMART_DATA_ALLOC(obj, Elm_Genlist_Smart_Data);
4723 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.add(obj);
4725 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
4726 evas_object_smart_member_add(priv->hit_rect, obj);
4727 elm_widget_sub_object_add(obj, priv->hit_rect);
4729 /* common scroller hit rectangle setup */
4730 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
4731 evas_object_show(priv->hit_rect);
4732 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
4734 elm_widget_can_focus_set(obj, EINA_TRUE);
4735 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
4737 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
4739 /* interface's add() routine issued AFTER the object's smart_add() */
4740 priv->s_iface = evas_object_smart_interface_get
4741 (obj, ELM_SCROLLABLE_IFACE_NAME);
4743 priv->s_iface->objects_set
4744 (obj, ELM_WIDGET_DATA(priv)->resize_obj, priv->hit_rect);
4746 priv->s_iface->bounce_allow_set
4747 (obj, EINA_FALSE, _elm_config->thumbscroll_bounce_enable);
4748 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
4750 priv->s_iface->animate_start_cb_set(obj, _scroll_animate_start_cb);
4751 priv->s_iface->animate_stop_cb_set(obj, _scroll_animate_stop_cb);
4752 priv->s_iface->drag_start_cb_set(obj, _scroll_drag_start_cb);
4753 priv->s_iface->drag_stop_cb_set(obj, _scroll_drag_stop_cb);
4754 priv->s_iface->edge_left_cb_set(obj, _edge_left_cb);
4755 priv->s_iface->edge_right_cb_set(obj, _edge_right_cb);
4756 priv->s_iface->edge_top_cb_set(obj, _edge_top_cb);
4757 priv->s_iface->edge_bottom_cb_set(obj, _edge_bottom_cb);
4758 priv->s_iface->vbar_drag_cb_set(obj, _vbar_drag_cb);
4759 priv->s_iface->vbar_press_cb_set(obj, _vbar_press_cb);
4760 priv->s_iface->vbar_unpress_cb_set(obj, _vbar_unpress_cb);
4761 priv->s_iface->hbar_drag_cb_set(obj, _hbar_drag_cb);
4762 priv->s_iface->hbar_press_cb_set(obj, _hbar_press_cb);
4763 priv->s_iface->hbar_unpress_cb_set(obj, _hbar_unpress_cb);
4765 priv->mode = ELM_LIST_SCROLL;
4766 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
4767 priv->item_cache_max = priv->max_items_per_block * 2;
4768 priv->longpress_timeout = _elm_config->longpress_timeout;
4769 priv->highlight = EINA_TRUE;
4771 #if GENLIST_FX_SUPPORT
4772 priv->fx_mode = EINA_FALSE;
4773 priv->rendered = EINA_FALSE;
4774 priv->fx_first_captured = EINA_FALSE;
4775 priv->fx_playing = EINA_FALSE;
4776 priv->fx_items_deleted = EINA_FALSE;
4777 priv->genlist_clearing = EINA_FALSE;
4780 priv->pan_obj = evas_object_smart_add
4781 (evas_object_evas_get(obj), _elm_genlist_pan_smart_class_new());
4782 pan_data = evas_object_smart_data_get(priv->pan_obj);
4783 pan_data->wsd = priv;
4786 // FIXME: difference from upstream
4787 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
4788 _mouse_down_scroller, obj);
4789 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
4790 _mouse_up_scroller, obj);
4791 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
4792 _mouse_move_scroller, obj);
4795 priv->s_iface->extern_pan_set(obj, priv->pan_obj);
4797 edje_object_size_min_calc(ELM_WIDGET_DATA(priv)->resize_obj, &minw, &minh);
4798 evas_object_size_hint_min_set(obj, minw, minh);
4800 _item_cache_all_free(priv);
4801 _mirrored_set(obj, elm_widget_mirrored_get(obj));
4803 elm_layout_sizing_eval(obj);
4807 _elm_genlist_smart_del(Evas_Object *obj)
4809 ELM_GENLIST_DATA_GET(obj, sd);
4811 elm_genlist_clear(obj);
4812 if (sd->calc_job) ecore_job_del(sd->calc_job);
4813 if (sd->update_job) ecore_job_del(sd->update_job);
4814 if (sd->queue_idle_enterer) ecore_idle_enterer_del(sd->queue_idle_enterer);
4815 if (sd->must_recalc_idler) ecore_idler_del(sd->must_recalc_idler);
4816 if (sd->multi_timer) ecore_timer_del(sd->multi_timer);
4817 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
4818 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
4820 evas_object_del(sd->pan_obj);
4821 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.del(obj);
4825 _elm_genlist_smart_move(Evas_Object *obj,
4829 ELM_GENLIST_DATA_GET(obj, sd);
4831 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.move(obj, x, y);
4833 evas_object_move(sd->hit_rect, x, y);
4837 _elm_genlist_smart_resize(Evas_Object *obj,
4841 ELM_GENLIST_DATA_GET(obj, sd);
4843 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.resize(obj, w, h);
4845 evas_object_resize(sd->hit_rect, w, h);
4849 _elm_genlist_smart_member_add(Evas_Object *obj,
4850 Evas_Object *member)
4852 ELM_GENLIST_DATA_GET(obj, sd);
4854 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.member_add(obj, member);
4857 evas_object_raise(sd->hit_rect);
4861 _access_obj_process(Elm_Genlist_Smart_Data *sd, Eina_Bool is_access)
4864 Eina_Bool done = EINA_FALSE;
4866 EINA_INLIST_FOREACH(sd->blocks, itb)
4874 EINA_LIST_FOREACH(itb->items, l, it)
4876 if (!it->realized) continue;
4877 if (is_access) _access_widget_item_register(it);
4879 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
4882 else if (done) break;
4887 _elm_genlist_smart_access(Evas_Object *obj, Eina_Bool is_access)
4889 ELM_GENLIST_CHECK(obj);
4890 ELM_GENLIST_DATA_GET(obj, sd);
4893 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
4894 _elm_genlist_smart_focus_next;
4896 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
4897 _access_obj_process(sd, is_access);
4901 _elm_genlist_smart_set_user(Elm_Genlist_Smart_Class *sc)
4903 ELM_WIDGET_CLASS(sc)->base.add = _elm_genlist_smart_add;
4904 ELM_WIDGET_CLASS(sc)->base.del = _elm_genlist_smart_del;
4905 ELM_WIDGET_CLASS(sc)->base.move = _elm_genlist_smart_move;
4906 ELM_WIDGET_CLASS(sc)->base.resize = _elm_genlist_smart_resize;
4907 ELM_WIDGET_CLASS(sc)->base.member_add = _elm_genlist_smart_member_add;
4909 ELM_WIDGET_CLASS(sc)->sub_object_add = _elm_genlist_smart_sub_object_add;
4910 ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_genlist_smart_sub_object_del;
4911 ELM_WIDGET_CLASS(sc)->on_focus = _elm_genlist_smart_on_focus;
4912 ELM_WIDGET_CLASS(sc)->theme = _elm_genlist_smart_theme;
4913 ELM_WIDGET_CLASS(sc)->event = _elm_genlist_smart_event;
4914 ELM_WIDGET_CLASS(sc)->translate = _elm_genlist_smart_translate;
4916 /* not a 'focus chain manager' */
4917 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
4918 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
4920 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_genlist_smart_sizing_eval;
4923 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
4924 ELM_WIDGET_CLASS(sc)->focus_next = _elm_genlist_smart_focus_next;
4926 ELM_WIDGET_CLASS(sc)->access = _elm_genlist_smart_access;
4929 EAPI const Elm_Genlist_Smart_Class *
4930 elm_genlist_smart_class_get(void)
4932 static Elm_Genlist_Smart_Class _sc =
4933 ELM_GENLIST_SMART_CLASS_INIT_NAME_VERSION(ELM_GENLIST_SMART_NAME);
4934 static const Elm_Genlist_Smart_Class *class = NULL;
4935 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
4940 _elm_genlist_smart_set(&_sc);
4941 esc->callbacks = _smart_callbacks;
4948 elm_genlist_add(Evas_Object *parent)
4952 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
4954 obj = elm_widget_add(_elm_genlist_smart_class_new(), parent);
4955 if (!obj) return NULL;
4957 if (!elm_widget_sub_object_add(parent, obj))
4958 ERR("could not add %p as sub object of %p", obj, parent);
4964 static Evas_Object *
4965 _item_content_get_hook(Elm_Gen_Item *it,
4968 Evas_Object *ret = NULL;
4969 if (it->deco_all_view)
4970 ret = edje_object_part_swallow_get(it->deco_all_view, part);
4971 else if (it->decorate_it_set)
4972 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
4974 ret = edje_object_part_swallow_get(VIEW(it), part);
4979 _item_text_get_hook(Elm_Gen_Item *it,
4982 if (!it->itc->func.text_get) return NULL;
4983 const char *ret = NULL;
4984 if (it->deco_all_view)
4985 ret = edje_object_part_text_get(it->deco_all_view, part);
4986 else if (it->decorate_it_set)
4987 ret = edje_object_part_text_get(it->item->deco_it_view, part);
4989 ret = edje_object_part_text_get(VIEW(it), part);
4994 _item_disable_hook(Elm_Object_Item *item)
4998 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5001 elm_genlist_item_selected_set(item, EINA_FALSE);
5005 if (elm_widget_item_disabled_get(it))
5007 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
5008 if (it->deco_all_view)
5009 edje_object_signal_emit
5010 (it->deco_all_view, "elm,state,disabled", "elm");
5014 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
5015 if (it->deco_all_view)
5016 edje_object_signal_emit
5017 (it->deco_all_view, "elm,state,enabled", "elm");
5019 EINA_LIST_FOREACH(it->content_objs, l, obj)
5020 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(it));
5025 _item_free(Elm_Gen_Item *it)
5027 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5029 #if GENLIST_FX_SUPPORT
5030 if (sd->fx_mode) GL_IT(it)->has_proxy_it = EINA_FALSE;
5031 _elm_genlist_proxy_item_del((Elm_Object_Item *)it);
5032 if ((!sd->fx_mode) || (sd->genlist_clearing))
5035 _item_free_common(it);
5037 _item_unrealize(it, EINA_FALSE);
5038 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
5041 if (sd->calc_job) ecore_job_del(sd->calc_job);
5042 sd->calc_job = ecore_job_add(_calc_job, sd);
5045 #if GENLIST_FX_SUPPORT
5047 _item_del_pre_fx_process(Elm_Gen_Item *it)
5049 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5051 sd->fx_items_deleted = EINA_TRUE;
5052 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5053 if (!eina_list_data_find(sd->pending_del_items, it))
5054 sd->pending_del_items = eina_list_append(sd->pending_del_items, it);
5056 _item_free_common(it);
5062 _item_del_pre_hook(Elm_Object_Item *item)
5064 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5066 #if GENLIST_FX_SUPPORT
5067 if ((GL_IT(it)->wsd->fx_mode) && (!GL_IT(it)->wsd->genlist_clearing))
5069 _item_del_pre_fx_process(it);
5078 _item_signal_emit_hook(Elm_Object_Item *it,
5079 const char *emission,
5082 edje_object_signal_emit(VIEW(it), emission, source);
5085 static Elm_Gen_Item *
5086 _elm_genlist_item_new(Elm_Genlist_Smart_Data *sd,
5087 const Elm_Genlist_Item_Class *itc,
5089 Elm_Gen_Item *parent,
5090 Elm_Genlist_Item_Type type,
5092 const void *func_data)
5094 Elm_Gen_Item *it, *it2;
5097 if (!itc) return NULL;
5099 it = elm_widget_item_new(ELM_WIDGET_DATA(sd)->obj, Elm_Gen_Item);
5100 if (!it) return NULL;
5103 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
5105 it->base.data = data;
5106 it->parent = parent;
5107 it->func.func = func;
5108 it->func.data = func_data;
5110 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
5111 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
5112 elm_widget_item_disable_hook_set(it, _item_disable_hook);
5113 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
5114 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
5116 #if 0 // FIXME: difference from upstream
5117 it->can_focus = EINA_TRUE;
5119 //it->del_cb = (Ecore_Cb)_item_free;
5120 //it->highlight_cb = (Ecore_Cb)_item_highlight;
5121 //it->unhighlight_cb = (Ecore_Cb)_item_unhighlight;
5122 //it->sel_cb = (Ecore_Cb)_item_select;
5123 //it->unsel_cb = (Ecore_Cb)_item_unselect;
5124 //it->unrealize_cb = (Ecore_Cb)_item_unrealize_cb;
5126 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
5127 GL_IT(it)->wsd = sd;
5128 GL_IT(it)->type = type;
5129 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
5133 if (it->parent->group)
5134 GL_IT(it)->group_item = parent;
5135 else if (GL_IT(it->parent)->group_item)
5136 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
5138 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
5140 if (!it2->parent->group) depth += 1;
5142 GL_IT(it)->expanded_depth = depth;
5145 #if GENLIST_FX_SUPPORT
5146 it->item->num = sd->item_count;
5149 sd->fx_items_deleted = EINA_FALSE;
5150 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5157 _elm_genlist_item_compare(const void *data,
5160 const Elm_Gen_Item *it, *item1;
5162 it = ELM_GEN_ITEM_FROM_INLIST(data);
5163 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
5164 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5168 _elm_genlist_item_list_compare(const void *data,
5171 const Elm_Gen_Item *it = data;
5172 const Elm_Gen_Item *item1 = data1;
5174 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5178 elm_genlist_items_count(const Evas_Object *obj)
5180 ELM_GENLIST_CHECK(obj) 0;
5181 ELM_GENLIST_DATA_GET(obj, sd);
5183 return sd->item_count;
5186 EAPI Elm_Object_Item *
5187 elm_genlist_item_append(Evas_Object *obj,
5188 const Elm_Genlist_Item_Class *itc,
5190 Elm_Object_Item *parent,
5191 Elm_Genlist_Item_Type type,
5193 const void *func_data)
5197 ELM_GENLIST_CHECK(obj) NULL;
5198 ELM_GENLIST_DATA_GET(obj, sd);
5200 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(((Elm_Widget_Item *)parent),NULL);
5202 it = _elm_genlist_item_new
5203 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5204 if (!it) return NULL;
5209 sd->group_items = eina_list_append(sd->group_items, it);
5210 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
5211 it->item->rel = NULL;
5215 Elm_Gen_Item *it2 = NULL;
5216 Eina_List *ll = eina_list_last(it->parent->item->items);
5218 if (ll) it2 = ll->data;
5219 it->parent->item->items =
5220 eina_list_append(it->parent->item->items, it);
5221 if (!it2) it2 = it->parent;
5222 sd->items = eina_inlist_append_relative
5223 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5224 it->item->rel = it2;
5225 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5227 it->item->before = EINA_FALSE;
5228 _item_queue(sd, it, NULL);
5230 return (Elm_Object_Item *)it;
5233 EAPI Elm_Object_Item *
5234 elm_genlist_item_prepend(Evas_Object *obj,
5235 const Elm_Genlist_Item_Class *itc,
5237 Elm_Object_Item *parent,
5238 Elm_Genlist_Item_Type type,
5240 const void *func_data)
5244 ELM_GENLIST_CHECK(obj) NULL;
5245 ELM_GENLIST_DATA_GET(obj, sd);
5246 it = _elm_genlist_item_new
5247 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5248 if (!it) return NULL;
5253 sd->group_items = eina_list_prepend(sd->group_items, it);
5254 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
5255 it->item->rel = NULL;
5259 Elm_Gen_Item *it2 = NULL;
5260 Eina_List *ll = it->parent->item->items;
5262 if (ll) it2 = ll->data;
5263 it->parent->item->items =
5264 eina_list_prepend(it->parent->item->items, it);
5265 if (!it2) it2 = it->parent;
5266 sd->items = eina_inlist_prepend_relative
5267 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5268 it->item->rel = it2;
5269 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5271 it->item->before = EINA_TRUE;
5272 _item_queue(sd, it, NULL);
5274 return (Elm_Object_Item *)it;
5277 EAPI Elm_Object_Item *
5278 elm_genlist_item_insert_after(Evas_Object *obj,
5279 const Elm_Genlist_Item_Class *itc,
5281 Elm_Object_Item *parent,
5282 Elm_Object_Item *after_it,
5283 Elm_Genlist_Item_Type type,
5285 const void *func_data)
5287 Elm_Gen_Item *after = (Elm_Gen_Item *)after_it;
5290 ELM_GENLIST_CHECK(obj) NULL;
5291 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
5292 ELM_GENLIST_DATA_GET(obj, sd);
5294 /* It makes no sense to insert after in an empty list with after !=
5295 * NULL, something really bad is happening in your app. */
5296 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5298 it = _elm_genlist_item_new
5299 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5300 if (!it) return NULL;
5304 if ((it->group) && (after->group))
5305 sd->group_items = eina_list_append_relative
5306 (sd->group_items, it, after);
5310 it->parent->item->items =
5311 eina_list_append_relative(it->parent->item->items, it, after);
5313 sd->items = eina_inlist_append_relative
5314 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5316 it->item->rel = after;
5317 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5318 it->item->before = EINA_FALSE;
5319 _item_queue(sd, it, NULL);
5321 return (Elm_Object_Item *)it;
5324 EAPI Elm_Object_Item *
5325 elm_genlist_item_insert_before(Evas_Object *obj,
5326 const Elm_Genlist_Item_Class *itc,
5328 Elm_Object_Item *parent,
5329 Elm_Object_Item *before_it,
5330 Elm_Genlist_Item_Type type,
5332 const void *func_data)
5334 Elm_Gen_Item *before = (Elm_Gen_Item *)before_it;
5337 ELM_GENLIST_CHECK(obj) NULL;
5338 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
5339 ELM_GENLIST_DATA_GET(obj, sd);
5341 /* It makes no sense to insert before in an empty list with before
5342 * != NULL, something really bad is happening in your app. */
5343 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5345 it = _elm_genlist_item_new
5346 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5347 if (!it) return NULL;
5351 if (it->group && before->group)
5353 eina_list_prepend_relative(sd->group_items, it, before);
5357 it->parent->item->items =
5358 eina_list_prepend_relative(it->parent->item->items, it, before);
5360 sd->items = eina_inlist_prepend_relative
5361 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5363 it->item->rel = before;
5364 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5365 it->item->before = EINA_TRUE;
5366 _item_queue(sd, it, NULL);
5368 return (Elm_Object_Item *)it;
5371 EAPI Elm_Object_Item *
5372 elm_genlist_item_sorted_insert(Evas_Object *obj,
5373 const Elm_Genlist_Item_Class *itc,
5375 Elm_Object_Item *parent,
5376 Elm_Genlist_Item_Type type,
5377 Eina_Compare_Cb comp,
5379 const void *func_data)
5381 Elm_Gen_Item *rel = NULL;
5384 ELM_GENLIST_CHECK(obj) NULL;
5385 ELM_GENLIST_DATA_GET(obj, sd);
5387 it = _elm_genlist_item_new
5388 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5389 if (!it) return NULL;
5391 sd->item_compare_cb = comp;
5398 l = eina_list_search_sorted_near_list
5399 (it->parent->item->items, _elm_genlist_item_list_compare, it,
5403 rel = eina_list_data_get(l);
5407 if (cmp_result >= 0)
5409 it->parent->item->items = eina_list_prepend_relative_list
5410 (it->parent->item->items, it, l);
5411 sd->items = eina_inlist_prepend_relative
5412 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5413 it->item->before = EINA_FALSE;
5415 else if (cmp_result < 0)
5417 it->parent->item->items = eina_list_append_relative_list
5418 (it->parent->item->items, it, l);
5419 sd->items = eina_inlist_append_relative
5420 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5421 it->item->before = EINA_TRUE;
5428 sd->state = eina_inlist_sorted_state_new();
5429 eina_inlist_sorted_state_init(sd->state, sd->items);
5430 sd->requeued = EINA_FALSE;
5434 sd->group_items = eina_list_append(sd->group_items, it);
5436 sd->items = eina_inlist_sorted_state_insert
5437 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
5440 if (EINA_INLIST_GET(it)->next)
5442 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5443 it->item->before = EINA_TRUE;
5445 else if (EINA_INLIST_GET(it)->prev)
5447 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5448 it->item->before = EINA_FALSE;
5454 it->item->rel = rel;
5455 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
5458 _item_queue(sd, it, _elm_genlist_item_list_compare);
5460 return (Elm_Object_Item *)it;
5464 _elm_genlist_fx_clear(Evas_Object *obj)
5466 ELM_GENLIST_DATA_GET(obj, sd);
5468 Elm_Gen_FX_Item *fi;
5472 EINA_LIST_FREE(sd->capture_before_items, pi)
5474 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
5475 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
5476 if (pi->proxy) evas_object_del(pi->proxy);
5479 EINA_LIST_FREE(sd->capture_after_items, pi)
5481 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
5482 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
5483 if (pi->proxy) evas_object_del(pi->proxy);
5487 EINA_LIST_FREE(sd->fx_items, fi)
5489 if (fi->trans) elm_transit_del(fi->trans);
5493 EINA_LIST_FREE (sd->pending_unrealized_items, it)
5494 _item_unrealize(it, EINA_FALSE);
5496 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
5497 _decorate_all_item_unrealize(it);
5499 EINA_LIST_FREE (sd->pending_del_items, it)
5502 _elm_widget_item_free((Elm_Widget_Item *)it);
5504 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5505 sd->alpha_bg = NULL;
5506 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
5507 sd->fx_timer = NULL;
5509 sd->genlist_clearing = EINA_TRUE;
5510 sd->fx_playing = EINA_FALSE;
5511 sd->sorting = EINA_FALSE;
5512 sd->fx_first_captured = EINA_FALSE;
5513 sd->fx_items_deleted = EINA_FALSE;
5517 elm_genlist_clear(Evas_Object *obj)
5519 ELM_GENLIST_CHECK(obj);
5520 ELM_GENLIST_DATA_GET(obj, sd);
5525 eina_inlist_sorted_state_free(sd->state);
5529 #if GENLIST_FX_SUPPORT
5532 _elm_genlist_fx_clear(obj);
5533 sd->genlist_clearing = EINA_TRUE;
5534 sd->rendered = EINA_FALSE;
5537 #if GENLIST_PINCH_ZOOM_SUPPORT
5538 sd->pinch_zoom_h = 0;
5539 sd->realized_top_item = NULL;
5540 sd->pinch_zoom_mode = ELM_GEN_PINCH_ZOOM_NONE;
5543 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5545 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
5546 // because sd->items can be modified inside elm_widget_item_del()
5549 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
5550 it->item->nocache_once = EINA_TRUE;
5551 elm_widget_item_del(it);
5555 _item_cache_all_free(sd);
5557 sd->pan_changed = EINA_TRUE;
5558 if (sd->selected) sd->selected = eina_list_free(sd->selected);
5559 sd->selected = NULL;
5561 sd->anchor_item = NULL;
5562 if (sd->multi_timer)
5564 ecore_timer_del(sd->multi_timer);
5565 sd->multi_timer = NULL;
5569 ecore_job_del(sd->update_job);
5570 sd->update_job = NULL;
5574 ecore_job_del(sd->calc_job);
5575 sd->calc_job = NULL;
5577 if (sd->queue_idle_enterer)
5579 ecore_idle_enterer_del(sd->queue_idle_enterer);
5580 sd->queue_idle_enterer = NULL;
5582 if (sd->must_recalc_idler)
5584 ecore_idler_del(sd->must_recalc_idler);
5585 sd->must_recalc_idler = NULL;
5587 if (sd->queue) sd->queue = eina_list_free(sd->queue);
5588 if (sd->reorder_move_animator)
5590 ecore_animator_del(sd->reorder_move_animator);
5591 sd->reorder_move_animator = NULL;
5593 sd->show_item = NULL;
5594 sd->reorder_old_pan_y = 0;
5601 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5602 sd->alpha_bg = NULL;
5606 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
5607 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
5609 elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
5610 sd->s_iface->content_region_show(obj, 0, 0, 0, 0);
5612 #if GENLIST_FX_SUPPORT
5613 sd->genlist_clearing = EINA_FALSE;
5615 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5616 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5620 elm_genlist_multi_select_set(Evas_Object *obj,
5623 ELM_GENLIST_CHECK(obj);
5624 ELM_GENLIST_DATA_GET(obj, sd);
5626 sd->multi = !!multi;
5630 elm_genlist_multi_select_get(const Evas_Object *obj)
5632 ELM_GENLIST_CHECK(obj) EINA_FALSE;
5633 ELM_GENLIST_DATA_GET(obj, sd);
5638 EAPI Elm_Object_Item *
5639 elm_genlist_selected_item_get(const Evas_Object *obj)
5641 ELM_GENLIST_CHECK(obj) NULL;
5642 ELM_GENLIST_DATA_GET(obj, sd);
5645 return sd->selected->data;
5651 elm_genlist_selected_items_get(const Evas_Object *obj)
5653 ELM_GENLIST_CHECK(obj) NULL;
5654 ELM_GENLIST_DATA_GET(obj, sd);
5656 return sd->selected;
5660 elm_genlist_realized_items_get(const Evas_Object *obj)
5663 Eina_List *list = NULL;
5664 Eina_Bool done = EINA_FALSE;
5666 ELM_GENLIST_CHECK(obj) NULL;
5667 ELM_GENLIST_DATA_GET(obj, sd);
5669 EINA_INLIST_FOREACH(sd->blocks, itb)
5677 EINA_LIST_FOREACH(itb->items, l, it)
5679 if (it->realized) list = eina_list_append(list, it);
5690 EAPI Elm_Object_Item *
5691 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5696 Evas_Coord ox, oy, ow, oh;
5700 ELM_GENLIST_CHECK(obj) NULL;
5701 ELM_GENLIST_DATA_GET(obj, sd);
5703 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
5705 EINA_INLIST_FOREACH(sd->blocks, itb)
5710 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
5711 oy + itb->y - itb->sd->pan_y,
5712 itb->w, itb->h, x, y, 1, 1))
5714 EINA_LIST_FOREACH(itb->items, l, it)
5716 Evas_Coord itx, ity;
5718 itx = ox + itb->x + it->x - itb->sd->pan_x;
5719 ity = oy + itb->y + it->y - itb->sd->pan_y;
5720 if (ELM_RECTS_INTERSECT
5721 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5725 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5726 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5731 return (Elm_Object_Item *)it;
5733 lasty = ity + it->item->h;
5738 if (y > lasty) *posret = 1;
5745 EAPI Elm_Object_Item *
5746 elm_genlist_first_item_get(const Evas_Object *obj)
5748 Elm_Gen_Item *tit, *it = NULL;
5750 ELM_GENLIST_CHECK(obj) NULL;
5751 ELM_GENLIST_DATA_GET(obj, sd);
5753 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
5755 return (Elm_Object_Item *)it;
5758 EAPI Elm_Object_Item *
5759 elm_genlist_last_item_get(const Evas_Object *obj)
5763 ELM_GENLIST_CHECK(obj) NULL;
5764 ELM_GENLIST_DATA_GET(obj, sd);
5765 if (!sd->items) return NULL;
5767 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
5768 return (Elm_Object_Item *)it;
5771 EAPI Elm_Object_Item *
5772 elm_genlist_item_next_get(const Elm_Object_Item *item)
5776 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
5778 it = (Elm_Gen_Item *)item;
5781 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5785 return (Elm_Object_Item *)it;
5788 EAPI Elm_Object_Item *
5789 elm_genlist_item_prev_get(const Elm_Object_Item *item)
5793 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
5795 it = (Elm_Gen_Item *)item;
5798 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5802 return (Elm_Object_Item *)it;
5805 EAPI Elm_Object_Item *
5806 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5808 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
5810 return (Elm_Object_Item *)((Elm_Gen_Item *)it)->parent;
5814 elm_genlist_item_subitems_clear(Elm_Object_Item *item)
5816 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5818 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5819 _item_sub_items_clear(it);
5823 elm_genlist_item_selected_set(Elm_Object_Item *item,
5826 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5827 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5829 if (elm_widget_item_disabled_get(it)) return;
5830 selected = !!selected;
5831 if (it->selected == selected) return;
5833 _item_select_unselect(it, selected);
5837 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5839 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5841 return ((Elm_Gen_Item *)it)->selected;
5844 static Elm_Gen_Item *
5845 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5849 if (it->item->expanded)
5851 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
5855 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
5858 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5859 it2 = (Elm_Gen_Item *)
5860 elm_genlist_item_next_get((Elm_Object_Item *)it2);
5866 static Evas_Object *
5867 _tray_alpha_bg_create(const Evas_Object *obj)
5869 Evas_Object *bg = NULL;
5870 Evas_Coord ox, oy, ow, oh;
5872 ELM_GENLIST_CHECK(obj) NULL;
5873 ELM_GENLIST_DATA_GET(obj, sd);
5875 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
5876 bg = evas_object_rectangle_add
5877 (evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5878 evas_object_color_set(bg, 0, 0, 0, 0);
5879 evas_object_resize(bg, ow, oh);
5880 evas_object_move(bg, ox, oy);
5886 elm_genlist_item_expanded_set(Elm_Object_Item *item,
5889 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5891 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5893 expanded = !!expanded;
5894 if (it->item->expanded == expanded) return;
5895 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
5896 it->item->expanded = expanded;
5897 GL_IT(it)->wsd->expanded_item = it;
5898 GL_IT(it)->wsd->expanded_next_item =
5899 _elm_genlist_expanded_next_item_get(it);
5901 if (it->item->expanded)
5904 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
5905 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
5906 GL_IT(it)->wsd->auto_scroll_enabled = EINA_TRUE;
5911 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
5912 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
5913 GL_IT(it)->wsd->auto_scroll_enabled = EINA_FALSE;
5918 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5920 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5922 return ((Elm_Gen_Item *)it)->item->expanded;
5926 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5928 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
5930 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5934 _elm_genlist_item_coordinates_calc(Elm_Object_Item *item,
5935 Elm_Genlist_Item_Scrollto_Type type,
5942 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5943 Evas_Coord gith = 0;
5945 if (!((GL_IT(it)->wsd->homogeneous) &&
5946 (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)))
5948 if ((it->item->queued) || (!it->item->mincalcd))
5950 GL_IT(it)->wsd->show_item = it;
5951 GL_IT(it)->wsd->bring_in = bring_in;
5952 GL_IT(it)->wsd->scroll_to_type = type;
5953 it->item->show_me = EINA_TRUE;
5957 if (GL_IT(it)->wsd->show_item)
5959 GL_IT(it)->wsd->show_item->item->show_me = EINA_FALSE;
5960 GL_IT(it)->wsd->show_item = NULL;
5963 evas_object_geometry_get(GL_IT(it)->wsd->pan_obj, NULL, NULL, w, h);
5966 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5967 if ((it->item->group_item) &&
5968 (GL_IT(it)->wsd->pan_y > (it->y + it->item->block->y)))
5969 gith = it->item->group_item->item->h;
5971 *y = it->y + it->item->block->y - gith;
5974 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5975 if (it->item->group_item) gith = it->item->group_item->item->h;
5976 *y = it->y + it->item->block->y - gith;
5979 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5980 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
5987 *x = it->x + it->item->block->x;
5988 *w = it->item->block->w;
5994 elm_genlist_item_promote(Elm_Object_Item *item)
5996 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5997 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5999 (it, (Elm_Gen_Item *)elm_genlist_first_item_get(WIDGET(it)));
6003 elm_genlist_item_demote(Elm_Object_Item *item)
6005 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6006 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6007 _item_move_after(it, (Elm_Gen_Item *)elm_genlist_last_item_get(WIDGET(it)));
6011 elm_genlist_item_show(Elm_Object_Item *item,
6012 Elm_Genlist_Item_Scrollto_Type type)
6014 Evas_Coord x, y, w, h;
6015 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6016 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6018 if (_elm_genlist_item_coordinates_calc
6019 (item, type, EINA_FALSE, &x, &y, &w, &h))
6020 GL_IT(it)->wsd->s_iface->content_region_show(WIDGET(item), x, y, w, h);
6024 elm_genlist_item_bring_in(Elm_Object_Item *item,
6025 Elm_Genlist_Item_Scrollto_Type type)
6027 Evas_Coord x, y, w, h;
6028 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6029 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6031 if (_elm_genlist_item_coordinates_calc
6032 (item, type, EINA_TRUE, &x, &y, &w, &h))
6033 GL_IT(it)->wsd->s_iface->region_bring_in(WIDGET(item), x, y, w, h);
6037 elm_genlist_item_all_contents_unset(Elm_Object_Item *item,
6040 Evas_Object *content;
6042 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6043 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6045 EINA_LIST_FREE (it->content_objs, content)
6047 evas_object_smart_member_del(content);
6048 evas_object_hide(content);
6049 if (l) *l = eina_list_append(*l, content);
6054 elm_genlist_item_update(Elm_Object_Item *item)
6056 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6057 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6059 if (!it->item->block) return;
6060 it->item->mincalcd = EINA_FALSE;
6061 it->item->updateme = EINA_TRUE;
6062 it->item->block->updateme = EINA_TRUE;
6063 #if GENLIST_ENTRY_SUPPORT
6064 it->item->unrealize_disabled = EINA_FALSE;
6067 #if GENLIST_FX_SUPPORT
6068 if (GL_IT(it)->wsd->fx_first_captured)
6069 _elm_genlist_fx_clear(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj);
6072 if (GL_IT(it)->wsd->update_job) ecore_job_del(GL_IT(it)->wsd->update_job);
6073 GL_IT(it)->wsd->update_job = ecore_job_add(_update_job, GL_IT(it)->wsd);
6077 elm_genlist_item_fields_update(Elm_Object_Item *item,
6079 Elm_Genlist_Item_Field_Type itf)
6081 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6082 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6084 if (!it->item->block) return;
6086 #if GENLIST_ENTRY_SUPPORT
6087 it->item->unrealize_disabled = EINA_FALSE;
6089 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
6091 _item_text_realize(it, VIEW(it), &it->texts, parts);
6093 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
6095 it->content_objs = _item_content_unrealize(it, VIEW(it),
6096 &it->contents, parts);
6097 it->content_objs = _item_content_realize(it, VIEW(it),
6098 &it->contents, parts);
6102 it->item->flip_content_objs =
6103 _item_mode_content_unrealize(it, VIEW(it),
6104 &it->item->flip_contents, parts,
6105 &it->item->flip_content_objs);
6106 it->item->flip_content_objs =
6107 _item_mode_content_realize(it, VIEW(it),
6108 &it->item->flip_contents, parts,
6109 &it->item->flip_content_objs);
6111 if (it->item->deco_it_view)
6113 it->item->deco_it_content_objs =
6114 _item_mode_content_unrealize(it, it->item->deco_it_view,
6115 &it->item->deco_it_contents, parts,
6116 &it->item->deco_it_content_objs);
6117 it->item->deco_it_content_objs =
6118 _item_mode_content_realize(it, it->item->deco_it_view,
6119 &it->item->deco_it_contents, parts,
6120 &it->item->deco_it_content_objs);
6122 if (GL_IT(it)->wsd->decorate_all_mode)
6124 it->item->deco_all_content_objs =
6125 _item_mode_content_unrealize
6126 (it, it->deco_all_view, &it->item->deco_all_contents, parts,
6127 &it->item->deco_all_content_objs);
6128 it->item->deco_all_content_objs =
6129 _item_mode_content_realize(it, it->deco_all_view,
6130 &it->item->deco_all_contents, parts,
6131 &it->item->deco_all_content_objs);
6135 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
6136 _item_state_realize(it, VIEW(it), &it->states, parts);
6140 elm_genlist_item_item_class_update(Elm_Object_Item *item,
6141 const Elm_Genlist_Item_Class *itc)
6143 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6144 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6146 if (!it->item->block) return;
6147 EINA_SAFETY_ON_NULL_RETURN(itc);
6149 it->item->nocache_once = EINA_TRUE;
6151 elm_widget_stringlist_free(it->texts);
6153 elm_widget_stringlist_free(it->contents);
6154 it->contents = NULL;
6155 elm_widget_stringlist_free(it->states);
6160 elm_widget_stringlist_free(it->item->flip_contents);
6161 it->item->flip_contents = NULL;
6163 if (it->item->deco_it_view)
6165 elm_widget_stringlist_free(it->item->deco_it_texts);
6166 it->item->deco_it_texts = NULL;
6167 elm_widget_stringlist_free(it->item->deco_it_contents);
6168 it->item->deco_it_contents = NULL;
6170 if (GL_IT(it)->wsd->decorate_all_mode)
6172 elm_widget_stringlist_free(it->item->deco_all_texts);
6173 it->item->deco_all_texts = NULL;
6174 elm_widget_stringlist_free(it->item->deco_all_contents);
6175 it->item->deco_all_contents = NULL;
6178 elm_genlist_item_update(item);
6181 EAPI const Elm_Genlist_Item_Class *
6182 elm_genlist_item_item_class_get(const Elm_Object_Item *item)
6184 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6185 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6189 static Evas_Object *
6190 _elm_genlist_item_label_create(void *data,
6191 Evas_Object *obj __UNUSED__,
6192 Evas_Object *tooltip,
6193 void *it __UNUSED__)
6195 Evas_Object *label = elm_label_add(tooltip);
6200 elm_object_style_set(label, "tooltip");
6201 elm_object_text_set(label, data);
6207 _elm_genlist_item_label_del_cb(void *data,
6208 Evas_Object *obj __UNUSED__,
6209 void *event_info __UNUSED__)
6211 eina_stringshare_del(data);
6215 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
6218 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6220 text = eina_stringshare_add(text);
6221 elm_genlist_item_tooltip_content_cb_set
6222 (it, _elm_genlist_item_label_create, text,
6223 _elm_genlist_item_label_del_cb);
6227 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
6228 Elm_Tooltip_Item_Content_Cb func,
6230 Evas_Smart_Cb del_cb)
6232 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6234 ELM_GENLIST_ITEM_CHECK_OR_GOTO(item, error);
6236 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
6239 if (it->tooltip.del_cb)
6240 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6242 it->tooltip.content_cb = func;
6243 it->tooltip.data = data;
6244 it->tooltip.del_cb = del_cb;
6248 elm_widget_item_tooltip_content_cb_set
6249 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
6250 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
6251 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
6257 if (del_cb) del_cb((void *)data, NULL, NULL);
6261 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
6263 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6265 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6267 if ((VIEW(it)) && (it->tooltip.content_cb))
6268 elm_widget_item_tooltip_unset(it);
6270 if (it->tooltip.del_cb)
6271 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6272 it->tooltip.del_cb = NULL;
6273 it->tooltip.content_cb = NULL;
6274 it->tooltip.data = NULL;
6275 it->tooltip.free_size = EINA_FALSE;
6276 if (it->tooltip.style)
6277 elm_genlist_item_tooltip_style_set(item, NULL);
6281 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
6284 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6286 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6288 eina_stringshare_replace(&it->tooltip.style, style);
6289 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
6293 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
6295 return elm_object_item_tooltip_style_get(it);
6299 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
6302 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6304 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
6306 it->tooltip.free_size = disable;
6307 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
6313 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
6315 return elm_object_tooltip_window_mode_get(VIEW(it));
6319 elm_genlist_item_cursor_set(Elm_Object_Item *item,
6322 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6324 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6325 eina_stringshare_replace(&it->mouse_cursor, cursor);
6326 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
6330 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
6332 return elm_widget_item_cursor_get(it);
6336 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
6338 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6340 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6342 if (!it->mouse_cursor) return;
6344 if (VIEW(it)) elm_widget_item_cursor_unset(it);
6346 eina_stringshare_del(it->mouse_cursor);
6347 it->mouse_cursor = NULL;
6351 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
6354 elm_widget_item_cursor_style_set(it, style);
6358 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
6360 return elm_widget_item_cursor_style_get(it);
6364 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
6365 Eina_Bool engine_only)
6367 elm_widget_item_cursor_engine_only_set(it, engine_only);
6371 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
6373 return elm_widget_item_cursor_engine_only_get(it);
6377 elm_genlist_item_index_get(const Elm_Object_Item *item)
6381 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6383 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, -1);
6385 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
6387 if (tmp == it) break;
6394 elm_genlist_mode_set(Evas_Object *obj,
6397 ELM_GENLIST_CHECK(obj);
6398 ELM_GENLIST_DATA_GET(obj, sd);
6400 if (sd->mode == mode) return;
6402 elm_layout_sizing_eval(obj);
6406 elm_genlist_mode_get(const Evas_Object *obj)
6408 ELM_GENLIST_CHECK(obj) ELM_LIST_LAST;
6409 ELM_GENLIST_DATA_GET(obj, sd);
6415 elm_genlist_bounce_set(Evas_Object *obj,
6419 ELM_GENLIST_CHECK(obj);
6420 ELM_GENLIST_DATA_GET(obj, sd);
6422 sd->h_bounce = !!h_bounce;
6423 sd->v_bounce = !!v_bounce;
6424 sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
6428 elm_genlist_bounce_get(const Evas_Object *obj,
6429 Eina_Bool *h_bounce,
6430 Eina_Bool *v_bounce)
6432 ELM_GENLIST_CHECK(obj);
6433 ELM_GENLIST_DATA_GET(obj, sd);
6435 if (h_bounce) *h_bounce = sd->h_bounce;
6436 if (v_bounce) *v_bounce = sd->v_bounce;
6440 elm_genlist_homogeneous_set(Evas_Object *obj,
6441 Eina_Bool homogeneous)
6443 ELM_GENLIST_CHECK(obj);
6444 ELM_GENLIST_DATA_GET(obj, sd);
6446 sd->homogeneous = !!homogeneous;
6450 elm_genlist_homogeneous_get(const Evas_Object *obj)
6452 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6453 ELM_GENLIST_DATA_GET(obj, sd);
6455 return sd->homogeneous;
6459 elm_genlist_block_count_set(Evas_Object *obj,
6462 ELM_GENLIST_CHECK(obj);
6463 ELM_GENLIST_DATA_GET(obj, sd);
6464 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
6466 sd->max_items_per_block = count;
6467 sd->item_cache_max = sd->max_items_per_block * 2;
6468 _item_cache_all_free(sd);
6472 elm_genlist_block_count_get(const Evas_Object *obj)
6474 ELM_GENLIST_CHECK(obj) 0;
6475 ELM_GENLIST_DATA_GET(obj, sd);
6477 return sd->max_items_per_block;
6481 elm_genlist_longpress_timeout_set(Evas_Object *obj,
6484 ELM_GENLIST_CHECK(obj);
6485 ELM_GENLIST_DATA_GET(obj, sd);
6487 sd->longpress_timeout = timeout;
6491 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
6493 ELM_GENLIST_CHECK(obj) 0;
6494 ELM_GENLIST_DATA_GET(obj, sd);
6496 return sd->longpress_timeout;
6500 elm_genlist_scroller_policy_set(Evas_Object *obj,
6501 Elm_Scroller_Policy policy_h,
6502 Elm_Scroller_Policy policy_v)
6504 ELM_GENLIST_CHECK(obj);
6505 ELM_GENLIST_DATA_GET(obj, sd);
6507 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
6508 (policy_v >= ELM_SCROLLER_POLICY_LAST))
6511 sd->s_iface->policy_set(obj, policy_h, policy_v);
6515 elm_genlist_scroller_policy_get(const Evas_Object *obj,
6516 Elm_Scroller_Policy *policy_h,
6517 Elm_Scroller_Policy *policy_v)
6519 Elm_Scroller_Policy s_policy_h, s_policy_v;
6521 ELM_GENLIST_CHECK(obj);
6522 ELM_GENLIST_DATA_GET(obj, sd);
6524 sd->s_iface->policy_get(obj, &s_policy_h, &s_policy_v);
6525 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
6526 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
6530 elm_genlist_realized_items_update(Evas_Object *obj)
6532 Eina_List *list, *l;
6533 Elm_Object_Item *it;
6535 ELM_GENLIST_CHECK(obj);
6537 list = elm_genlist_realized_items_get(obj);
6538 EINA_LIST_FOREACH(list, l, it)
6539 elm_genlist_item_update(it);
6543 elm_genlist_item_decorate_mode_set(Elm_Object_Item *item,
6544 const char *decorate_it_type,
6545 Eina_Bool decorate_it_set)
6547 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6548 Elm_Genlist_Smart_Data *sd;
6550 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6551 sd = GL_IT(it)->wsd;
6553 if (elm_widget_item_disabled_get(it)) return;
6554 if (!decorate_it_type) return;
6555 if (sd->decorate_all_mode) return;
6557 if ((sd->mode_item == it) &&
6558 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
6561 if (!it->itc->decorate_item_style) return;
6562 it->decorate_it_set = decorate_it_set;
6565 if (((sd->decorate_it_type)
6566 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
6567 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
6568 _decorate_item_unset(sd);
6570 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
6571 if (decorate_it_set) _decorate_item_set(it);
6575 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *item)
6577 Elm_Gen_Item *i = (Elm_Gen_Item *)item;
6579 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6580 return GL_IT(i)->wsd->decorate_it_type;
6583 EAPI Elm_Object_Item *
6584 elm_genlist_decorated_item_get(const Evas_Object *obj)
6586 ELM_GENLIST_CHECK(obj) NULL;
6587 ELM_GENLIST_DATA_GET(obj, sd);
6589 return (Elm_Object_Item *)sd->mode_item;
6593 elm_genlist_decorate_mode_get(const Evas_Object *obj)
6595 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6596 ELM_GENLIST_DATA_GET(obj, sd);
6598 return sd->decorate_all_mode;
6602 elm_genlist_decorate_mode_set(Evas_Object *obj,
6603 Eina_Bool decorated)
6606 Eina_List *list, *l;
6608 ELM_GENLIST_CHECK(obj);
6609 ELM_GENLIST_DATA_GET(obj, sd);
6611 decorated = !!decorated;
6612 if (sd->decorate_all_mode == decorated) return;
6613 // decorate_all_mode should be set first
6614 // because content_get func. will be called after this
6615 // and user can check whether deocrate_all_mode is enabeld.
6616 sd->decorate_all_mode = decorated;
6618 list = elm_genlist_realized_items_get(obj);
6619 if (!sd->decorate_all_mode)
6621 EINA_LIST_FOREACH(list, l, it)
6623 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6624 _decorate_all_item_unrealize(it);
6626 _item_cache_all_free(sd);
6630 EINA_LIST_FOREACH(list, l, it)
6632 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6634 if (it->itc->decorate_all_item_style)
6635 _decorate_all_item_realize(it, EINA_TRUE);
6639 #if GENLIST_FX_SUPPORT
6640 if (sd->fx_first_captured)
6641 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj);
6644 if (sd->calc_job) ecore_job_del(sd->calc_job);
6645 sd->calc_job = ecore_job_add(_calc_job, sd);
6649 elm_genlist_reorder_mode_set(Evas_Object *obj,
6650 Eina_Bool reorder_mode)
6652 #if 1 // FIXME: difference from upstream
6653 Eina_List *list, *l;
6656 ELM_GENLIST_CHECK(obj);
6657 ELM_GENLIST_DATA_GET(obj, sd);
6659 if (sd->reorder_mode == !!reorder_mode) return;
6660 sd->reorder_mode = !!reorder_mode;
6661 #if 1 // FIXME: difference from upstream
6662 list = elm_genlist_realized_items_get(obj);
6663 EINA_LIST_FOREACH(list, l, it)
6665 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6667 if (sd->reorder_mode)
6668 edje_object_signal_emit
6669 (VIEW(it), "elm,state,reorder,mode_set", "elm");
6671 edje_object_signal_emit
6672 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
6674 if (sd->decorate_all_mode)
6676 if (sd->reorder_mode)
6677 edje_object_signal_emit
6678 (it->deco_all_view, "elm,state,reorder,mode_set", "elm");
6680 edje_object_signal_emit
6681 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
6684 eina_list_free(list);
6689 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6691 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6692 ELM_GENLIST_DATA_GET(obj, sd);
6694 return sd->reorder_mode;
6697 EAPI Elm_Genlist_Item_Type
6698 elm_genlist_item_type_get(const Elm_Object_Item *item)
6700 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6702 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_GENLIST_ITEM_MAX);
6704 return it->item->type;
6707 EAPI Elm_Genlist_Item_Class *
6708 elm_genlist_item_class_new(void)
6710 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
6711 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6713 itc->version = CLASS_ALLOCATED;
6715 itc->delete_me = EINA_FALSE;
6721 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6723 if (itc && (itc->version == CLASS_ALLOCATED))
6725 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6726 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6736 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6738 if (itc && (itc->version == CLASS_ALLOCATED))
6741 if (itc->refcount == 0) itc->refcount--;
6746 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6748 if (itc && (itc->version == CLASS_ALLOCATED))
6750 if (itc->refcount > 0) itc->refcount--;
6751 if (itc->delete_me && (!itc->refcount))
6752 elm_genlist_item_class_free(itc);
6757 elm_genlist_item_flip_set(Elm_Object_Item *item,
6760 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6761 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6762 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
6765 if (it->flipped == flip) return;
6767 it->item->unrealize_disabled = EINA_FALSE;
6771 _item_unrealize(it, EINA_FALSE);
6772 it->flipped = EINA_TRUE;
6773 it->item->nocache = EINA_TRUE;
6777 _item_unrealize(it, EINA_FALSE);
6778 it->flipped = EINA_FALSE;
6779 it->item->nocache = EINA_FALSE;
6781 if (sd->calc_job) ecore_job_del(sd->calc_job);
6782 sd->calc_job = ecore_job_add(_calc_job, sd);
6786 elm_genlist_item_flip_get(const Elm_Object_Item *item)
6788 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6790 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
6796 elm_genlist_select_mode_set(Evas_Object *obj,
6797 Elm_Object_Select_Mode mode)
6799 ELM_GENLIST_CHECK(obj);
6800 ELM_GENLIST_DATA_GET(obj, sd);
6802 if (mode >= ELM_OBJECT_SELECT_MODE_MAX || (sd->select_mode == mode))
6805 sd->select_mode = mode;
6806 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
6807 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
6811 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it)
6816 EAPI Elm_Object_Select_Mode
6817 elm_genlist_select_mode_get(const Evas_Object *obj)
6819 ELM_GENLIST_CHECK(obj) ELM_OBJECT_SELECT_MODE_MAX;
6820 ELM_GENLIST_DATA_GET(obj, sd);
6822 return sd->select_mode;
6826 elm_genlist_highlight_mode_set(Evas_Object *obj,
6827 Eina_Bool highlight)
6829 ELM_GENLIST_CHECK(obj);
6830 ELM_GENLIST_DATA_GET(obj, sd);
6832 sd->highlight = !!highlight;
6836 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6838 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6839 ELM_GENLIST_DATA_GET(obj, sd);
6841 return sd->highlight;
6845 elm_genlist_item_select_mode_set(Elm_Object_Item *item,
6846 Elm_Object_Select_Mode mode)
6848 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6850 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6852 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6854 if (it->select_mode != mode)
6855 it->select_mode = mode;
6857 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
6858 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
6861 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6863 it->item->mincalcd = EINA_FALSE;
6864 it->item->updateme = EINA_TRUE;
6865 if (it->item->block) it->item->block->updateme = EINA_TRUE;
6866 if (GL_IT(it)->wsd->update_job)
6867 ecore_job_del(GL_IT(it)->wsd->update_job);
6868 GL_IT(it)->wsd->update_job =
6869 ecore_job_add(_update_job, GL_IT(it)->wsd);
6871 // reset homogeneous item size
6872 if (GL_IT(it)->wsd->homogeneous)
6875 GL_IT(it)->wsd->group_item_width =
6876 GL_IT(it)->wsd->group_item_height = 0;
6878 GL_IT(it)->wsd->item_width = GL_IT(it)->wsd->item_height = 0;
6883 EAPI Elm_Object_Select_Mode
6884 elm_genlist_item_select_mode_get(const Elm_Object_Item *item)
6886 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6888 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_OBJECT_SELECT_MODE_MAX);
6890 if (!it) return ELM_OBJECT_SELECT_MODE_MAX;
6892 return it->select_mode;
6895 // will be deprecated
6897 elm_genlist_tree_effect_enabled_set(Evas_Object *obj __UNUSED__,
6898 Eina_Bool enabled __UNUSED__)
6900 ELM_GENLIST_CHECK(obj);
6903 // will be deprecated
6905 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj __UNUSED__)
6907 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6912 EAPI Elm_Object_Item *
6913 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
6915 Elm_Gen_Item *it = NULL;
6919 ELM_GENLIST_CHECK(obj) NULL;
6920 ELM_GENLIST_DATA_GET(obj, sd);
6922 if (!sd->items) return NULL;
6924 a = eina_inlist_accessor_new(sd->items);
6925 if (!a) return NULL;
6926 if (eina_accessor_data_get(a, nth, &data))
6927 it = ELM_GEN_ITEM_FROM_INLIST(data);
6928 eina_accessor_free(a);
6929 return (Elm_Object_Item *)it;
6932 #if GENLIST_FX_SUPPORT
6934 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
6936 ELM_GENLIST_CHECK(obj);
6937 ELM_GENLIST_DATA_GET(obj, sd);
6943 elm_genlist_fx_mode_get(const Evas_Object *obj)
6945 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6946 ELM_GENLIST_DATA_GET(obj, sd);
6952 _elm_genlist_proxy_item_del(const Elm_Object_Item *item)
6954 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6955 if ((!it) || (!it->item)) return;
6957 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
6961 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
6962 if (pi->it == it) pi->it = NULL;
6964 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
6965 if (pi->it == it) pi->it = NULL;
6969 _elm_genlist_proxy_item_new(const Elm_Object_Item *item)
6971 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6972 if ((!it) || (!it->item)) return EINA_FALSE;
6975 Proxy_Item *pi = NULL;
6976 pi = calloc(1, sizeof(Proxy_Item));
6977 if (!pi) return NULL;
6979 pi->proxy = evas_object_image_filled_add
6980 (evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
6981 if (!pi->proxy) return EINA_FALSE;
6982 evas_object_clip_set(pi->proxy, evas_object_clip_get(GL_IT(it)->wsd->pan_obj));
6983 evas_object_smart_member_add(pi->proxy, GL_IT(it)->wsd->pan_obj);
6984 evas_object_hide(pi->proxy);
6986 if ((GL_IT(it)->wsd->decorate_all_mode) && (it->deco_all_view))
6987 evas_object_image_source_set(pi->proxy, it->deco_all_view);
6989 evas_object_image_source_set(pi->proxy, VIEW(it));
6991 GL_IT(it)->has_proxy_it = EINA_TRUE;
6993 pi->num = it->item->num;
6994 pi->x = it->item->scrl_x;
6995 pi->y = it->item->scrl_y;
6996 pi->w = it->item->w;
6997 pi->h = it->item->h;
6999 evas_object_geometry_get(VIEW(it), NULL, NULL, &w, &h);
7001 if (w <= 0 || h <= 0)
7003 evas_object_size_hint_min_get(VIEW(it), &w, &h);
7004 evas_object_size_hint_min_set(pi->proxy, w, h);
7006 else evas_object_resize(pi->proxy, w, h);
7012 _elm_genlist_fx_capture(Evas_Object *obj, int level)
7014 ELM_GENLIST_DATA_GET(obj, sd);
7018 Eina_Bool done = EINA_FALSE;
7021 Evas_Coord ox, oy, ow, oh;
7025 if ((!sd->rendered) || (sd->fx_playing)) return EINA_FALSE;
7026 if ((!level) && (sd->fx_first_captured)) return EINA_FALSE;
7027 if ((level) && (!sd->fx_first_captured)) return EINA_FALSE;
7029 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7033 sd->fx_first_captured = EINA_TRUE;
7034 EINA_LIST_FREE(sd->capture_before_items, pi)
7036 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
7037 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
7038 if (pi->proxy) evas_object_del(pi->proxy);
7044 EINA_LIST_FREE(sd->capture_after_items, pi)
7046 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
7047 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
7048 if (pi->proxy) evas_object_del(pi->proxy);
7052 EINA_INLIST_FOREACH(sd->blocks, itb)
7056 EINA_LIST_FOREACH(itb->items, l, it)
7058 if (it->realized && it->item->scrl_y >= oy)
7060 sd->realized_top_item = it;
7065 if (sd->realized_top_item) break;
7069 #if GENLIST_PINCH_ZOOM_SUPPORT
7070 if (sd->pinch_zoom_mode)
7072 EINA_INLIST_FOREACH(sd->blocks, itb)
7074 EINA_LIST_FOREACH(itb->items, l, it)
7077 if (IS_ROOT_PARENT_IT(it) && it->realized
7078 && (GL_IT(it)->scrl_y + GL_IT(it)->h >= oy && GL_IT(it)->scrl_y <= oy + oh))
7080 pi = _elm_genlist_proxy_item_new((Elm_Object_Item *)it);
7081 if (!level) sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
7082 else sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
7086 if ((sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT) && (level)) return EINA_TRUE;
7087 if ((sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND) && (!level)) return EINA_TRUE;
7091 EINA_INLIST_FOREACH(sd->blocks, itb)
7096 EINA_LIST_FOREACH(itb->items, l, it)
7098 #if GENLIST_PINCH_ZOOM_SUPPORT
7099 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7103 pi = _elm_genlist_proxy_item_new((Elm_Object_Item *)it);
7106 sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
7108 sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
7112 else if (done) break;
7117 static Elm_Gen_FX_Item *
7118 _elm_genlist_fx_item_find(const Elm_Object_Item *item)
7120 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
7121 if (!it) return EINA_FALSE;
7123 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
7124 if (!sd) return NULL;
7126 Elm_Gen_FX_Item *fi = NULL;
7129 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7131 if (fi->it == it) return fi;
7136 static Elm_Gen_FX_Item *
7137 _elm_genlist_fx_item_new(const Proxy_Item *pi)
7139 if ((!pi) || (!pi->it)) return NULL;
7141 Elm_Gen_FX_Item *fi = NULL;
7142 fi = calloc(1, sizeof(Elm_Gen_FX_Item));
7143 if (!fi) return NULL;
7146 GL_IT(fi->it)->fi = fi;
7147 fi->proxy = pi->proxy;
7149 fi->from.x = fi->to.x = pi->x;
7150 fi->from.y = fi->to.y = pi->y;
7151 fi->from.w = fi->to.w = pi->w;
7152 fi->from.h = fi->to.h = pi->h;
7153 fi->update = EINA_FALSE;
7158 static Elm_Object_Item *
7159 _elm_genlist_fx_item_prev_get(const Elm_Object_Item *item)
7162 it = (Elm_Gen_Item *)item;
7163 if (!it) return NULL;
7164 if (GL_IT(it)->wsd->pinch_zoom_mode) return NULL;
7168 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7172 return (Elm_Object_Item *)it;
7176 _elm_genlist_fx_items_make(Evas_Object *obj)
7178 ELM_GENLIST_CHECK(obj) EINA_FALSE;
7179 ELM_GENLIST_DATA_GET(obj, sd);
7181 Elm_Gen_FX_Item *fi;
7184 Elm_Gen_Item *prev = NULL;
7185 Evas_Coord ox, oy, ow, oh, mv_dist, max_mv_dist = 0;
7187 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7189 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7191 fi = _elm_genlist_fx_item_new(pi);
7192 if (fi) sd->fx_items = eina_list_append(sd->fx_items, fi);
7195 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
7197 fi = _elm_genlist_fx_item_find((Elm_Object_Item *)pi->it);
7199 if (fi) // pi exists in both before and after capture items
7201 fi->type = ELM_GEN_ITEM_FX_TYPE_SAME;
7202 fi->update = EINA_TRUE;
7208 // find the max distance between before and after capture items
7209 mv_dist = abs(fi->to.y - fi->from.y);
7210 if (max_mv_dist < mv_dist) max_mv_dist = mv_dist;
7212 else // pi only exists in after capture items
7214 fi = _elm_genlist_fx_item_new(pi);
7217 fi->type = ELM_GEN_ITEM_FX_TYPE_ADD;
7218 fi->update = EINA_TRUE;
7219 sd->fx_items = eina_list_append(sd->fx_items, fi);
7224 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7226 // find deleted items
7227 if (!fi->update) // pi only exists in before capture items
7229 fi->type = ELM_GEN_ITEM_FX_TYPE_DEL;
7230 fi->update = EINA_TRUE;
7232 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7233 if ((prev) && (GL_IT(prev)->fi))
7235 fi->to.y = GL_IT(prev)->fi->to.y + GL_IT(prev)->fi->to.h;
7238 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7240 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7241 if ((prev) && (prev->realized) && (GL_IT(prev)->fi))
7243 fi->from.y = GL_IT(prev)->fi->from.y + GL_IT(prev)->fi->from.h;
7247 if (sd->realized_top_item)
7250 if (fi->num <= sd->realized_top_item->item->num)
7251 fi->from.y -= max_mv_dist;
7253 fi->from.y += max_mv_dist;
7259 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7261 if ((GL_IT(fi->it)->items) && (GL_IT(fi->it)->expanded_depth == 0))
7263 #if GENLIST_PINCH_ZOOM_SUPPORT
7264 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7266 fi->from.y = oy + GL_IT(fi->it)->pan_scrl_y - sd->pinch_pan_y;
7269 if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7271 if (sd->realized_top_item)
7273 if (fi->num <= sd->realized_top_item->item->num)
7274 fi->to.y = oy - fi->from.h;
7285 static Elm_Gen_FX_Item *
7286 _fx_cover_item_get(const Elm_Gen_FX_Item *fi)
7288 Elm_Gen_FX_Item *cover_fi;
7290 if (!fi) return NULL;
7292 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7293 Evas_Coord ox, oy, ow, oh;
7294 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7296 EINA_LIST_FOREACH(sd->fx_items, l, cover_fi)
7298 if (fi == cover_fi) continue;
7299 if (sd->fx_items_deleted)
7301 if ((cover_fi->from.y >= oy+oh || cover_fi->from.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y > 0))
7306 if ((cover_fi->to.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y < 0))
7314 _item_fx_op(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__, double progress __UNUSED__)
7316 Elm_Gen_FX_Item *fi = data, *cover_it;
7317 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7318 Evas_Coord fi_ox, fi_oy, cover_it_ox, cover_it_oy, ox, oy, ow, oh;
7320 evas_object_show(VIEW(fi->it));
7321 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7322 evas_object_geometry_get(fi->proxy, &fi_ox, &fi_oy, NULL, NULL);
7323 evas_object_move(fi->proxy, ox, fi_oy);
7324 evas_object_show(fi->proxy);
7325 #if GENLIST_PINCH_ZOOM_SUPPORT
7326 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(fi->it))) evas_object_raise(fi->proxy);
7329 if ((!sd->expanded_next_item) || (sd->expanded_next_item == fi->it)) goto raise_event_block;
7330 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME) goto raise_event_block;
7332 // find the closest item that cover current item when deleting
7333 cover_it = _fx_cover_item_get(fi);
7336 evas_object_geometry_get(cover_it->proxy, &cover_it_ox, &cover_it_oy, NULL, NULL);
7338 if (sd->fx_items_deleted)
7341 && (fi_oy + fi->to.h >= cover_it_oy + cover_it->to.h ) && (fi->from.y < cover_it->from.y))
7342 evas_object_hide(fi->proxy);
7344 else if (cover_it_oy && (fi_oy >= cover_it_oy))
7345 evas_object_hide(fi->proxy);
7347 evas_object_show(fi->proxy);
7351 evas_object_raise(sd->alpha_bg);
7358 _item_fx_done(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__)
7360 Elm_Gen_FX_Item *fx_done_it = data;
7361 Elm_Genlist_Smart_Data *sd = GL_IT(fx_done_it->it)->wsd;
7363 if ((!fx_done_it) || (!fx_done_it->it) || (!sd)) return;
7365 evas_object_image_source_visible_set(fx_done_it->proxy, EINA_TRUE);
7366 evas_object_lower(fx_done_it->proxy);
7368 if ((sd->decorate_all_mode) && (fx_done_it->it->deco_all_view))
7369 evas_object_move(fx_done_it->it->deco_all_view, fx_done_it->to.x, fx_done_it->to.y);
7371 evas_object_move(VIEW(fx_done_it->it), fx_done_it->to.x, fx_done_it->to.y);
7372 GL_IT(fx_done_it->it)->has_proxy_it = EINA_FALSE;
7374 evas_object_clip_unset(fx_done_it->proxy);
7378 _item_fx_del_cb(void *data, Elm_Transit *transit __UNUSED__)
7380 Elm_Gen_FX_Item *fx_done_it = data;
7381 Elm_Gen_Item *it = NULL;
7382 Proxy_Item *pi = NULL;
7384 Elm_Genlist_Smart_Data *sd = GL_IT(fx_done_it->it)->wsd;
7386 if ((!fx_done_it) || (!fx_done_it->it) || (!sd)) return;
7388 sd->fx_items = eina_list_remove(sd->fx_items, fx_done_it);
7389 GL_IT(fx_done_it->it)->fi = NULL;
7392 if (!eina_list_count(sd->fx_items))
7394 EINA_LIST_FREE (sd->pending_unrealized_items, it)
7396 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7397 #if GENLIST_PINCH_ZOOM_SUPPORT
7398 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7400 _item_unrealize(it, EINA_FALSE);
7402 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
7404 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7405 #if GENLIST_PINCH_ZOOM_SUPPORT
7406 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7408 _decorate_all_item_unrealize(it);
7411 EINA_LIST_FREE (sd->pending_del_items, it)
7414 _elm_widget_item_free((Elm_Widget_Item *)it);
7417 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7418 evas_object_hide(pi->proxy);
7419 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
7420 evas_object_hide(pi->proxy);
7422 sd->fx_playing = EINA_FALSE;
7423 sd->sorting = EINA_FALSE;
7424 sd->fx_first_captured = EINA_FALSE;
7425 evas_object_hide(sd->alpha_bg);
7427 sd->realized_top_item = NULL;
7428 sd->pan_changed = EINA_TRUE;
7429 evas_object_smart_changed(sd->pan_obj);
7434 _sorting_effect_animator_cb(void *data)
7436 Elm_Genlist_Smart_Data *sd = data;
7437 Elm_Gen_FX_Item *fi;
7440 Evas_Coord ox, oy, ow, oh;
7441 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7443 sd->fx_timer = NULL;
7444 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7448 fi->changed = EINA_TRUE;
7449 evas_object_resize(fi->proxy, ow, fi->to.h);
7451 fi->trans = elm_transit_add();
7452 elm_transit_object_add(fi->trans, fi->proxy);
7453 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7454 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7456 elm_transit_effect_translation_add(fi->trans, fi->to.x, fi->to.y - 30 * elm_config_scale_get(), fi->to.x, fi->to.y);
7457 elm_transit_effect_color_add(fi->trans,0, 0, 0, 0, 255,255,255,255);
7459 elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
7460 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7461 elm_transit_duration_set(fi->trans,0.3);
7462 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7463 elm_transit_go(fi->trans);
7465 return ECORE_CALLBACK_RENEW;
7468 return ECORE_CALLBACK_CANCEL;
7472 _elm_genlist_fx_play(Evas_Object *obj)
7474 ELM_GENLIST_CHECK(obj);
7475 ELM_GENLIST_DATA_GET(obj, sd);
7477 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
7478 Elm_Gen_FX_Item *fi;
7481 if (!sd->fx_mode) return;
7483 EINA_LIST_FREE(sd->fx_items, fi)
7485 if (fi->trans) elm_transit_del(fi->trans);
7488 _item_cache_all_free(sd);
7490 _elm_genlist_fx_items_make(obj);
7491 if (!eina_list_count(sd->fx_items) || (sd->queue))
7493 _elm_genlist_fx_clear(obj);
7497 sd->fx_playing = EINA_TRUE;
7499 if (!sd->alpha_bg) sd->alpha_bg = _tray_alpha_bg_create(obj);
7500 evas_object_show(sd->alpha_bg);
7502 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7503 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
7507 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7508 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7509 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
7510 sd->fx_timer = ecore_timer_add(0.05, _sorting_effect_animator_cb, sd);
7514 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7516 if (!fi->proxy) continue;
7518 if ((fi->from.y <= oy) || (fi->from.y + fi->from.h >= oy + oh))
7520 if ((sd->decorate_all_mode) && (fi->it->deco_all_view))
7521 evas_object_move(fi->it->deco_all_view, cvx, fi->to.y);
7523 evas_object_move(VIEW(fi->it), cvx, fi->to.y);
7525 else if ((fi->to.y <= oy) || (fi->to.y + fi->to.h >= oy + oh))
7527 if ((sd->decorate_all_mode) && (fi->it->deco_all_view))
7528 evas_object_move(fi->it->deco_all_view, cvx, fi->from.y);
7530 evas_object_move(VIEW(fi->it), cvx, fi->from.y);
7533 evas_object_resize(fi->proxy, ow, fi->to.h);
7534 evas_object_show(fi->proxy);
7536 fi->trans = elm_transit_add();
7537 elm_transit_object_add(fi->trans, fi->proxy);
7539 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7540 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7542 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME)
7544 evas_object_raise(fi->proxy);
7545 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7548 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7550 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7551 elm_transit_effect_color_add(fi->trans, 0, 0, 0, 0, 255, 255, 255, 255);
7553 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7555 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7556 elm_transit_effect_color_add(fi->trans, 255, 255, 255, 255, 0, 0, 0, 0);
7558 elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
7559 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7561 elm_transit_duration_set(fi->trans, FX_MOVE_TIME);
7562 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7563 elm_transit_go(fi->trans);
7568 #if GENLIST_PINCH_ZOOM_SUPPORT
7570 elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Elm_Gen_Pinch_Zoom_Mode mode)
7572 ELM_GENLIST_DATA_GET(obj, sd);
7577 Eina_Bool done = EINA_FALSE;
7579 if ((sd->queue) || (!sd->rendered) || (sd->queue_idle_enterer)) return EINA_FALSE;
7581 EINA_INLIST_FOREACH(sd->blocks, itb)
7583 EINA_LIST_FOREACH(itb->items, l, it)
7586 if (IS_ROOT_PARENT_IT(it))
7594 if (!done) return EINA_FALSE;
7596 sd->pinch_zoom_mode = mode;
7598 _item_cache_all_free(sd);
7599 _elm_genlist_fx_capture(obj, 0);
7601 sd->pinch_pan_y = sd->pan_y;
7603 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7604 sd->s_iface->content_region_show(obj, 0,0,0,0);
7606 sd->pan_changed = EINA_TRUE;
7607 evas_object_smart_changed(sd->pan_obj);
7614 eina_list_sort_merge(Eina_List *a, Eina_List *b, Eina_Compare_Cb func)
7616 Eina_List *first, *last;
7618 if (func(a->data, b->data) > 0)
7620 _item_move_after(a->data, b->data);
7621 a = (last = first = a)->next;
7625 b = (last = first = b)->next;
7628 if (func(a->data, b->data) > 0)
7630 _item_move_after(a->data, b->data);
7631 a = (last = last->next = a)->next;
7634 b = (last = last->next = b)->next;
7636 last->next = a ? a : b;
7642 elm_genlist_sort(Evas_Object *obj, Eina_Compare_Cb func)
7644 ELM_GENLIST_CHECK(obj) NULL;
7645 ELM_GENLIST_DATA_GET(obj, sd);
7646 Eina_List *list = NULL;
7647 Elm_Gen_Item *it, *next;
7648 unsigned int limit = 0, i = 0, n = 0;
7649 Eina_List *tail = NULL, *unsort = NULL, *stack[32], *prev = NULL;
7651 sd->sorting = EINA_TRUE;
7653 it = (Elm_Gen_Item*)elm_genlist_first_item_get(obj);
7656 list = eina_list_append(list, it);
7657 next = (Elm_Gen_Item*)elm_genlist_item_next_get((Elm_Object_Item *)it);
7665 limit = eina_list_count(list);
7669 (limit > list->accounting->count))
7670 limit = list->accounting->count;
7672 if (limit != list->accounting->count)
7674 unsort = eina_list_nth_list(list, limit);
7676 unsort->prev->next = NULL;
7681 unsigned int idx, tmp;
7683 Eina_List *a = tail;
7684 Eina_List *b = tail->next;
7694 if (func(a->data, b->data) > 0)
7695 ((stack[i++] = a)->next = b)->next = 0;
7697 ((stack[i++] = b)->next = a)->next = 0;
7700 for (idx = n ^ tmp; idx &= idx - 1; i--)
7701 stack[i - 2] = eina_list_sort_merge(stack[i - 2], stack[i - 1], func);
7705 stack[i - 1] = eina_list_sort_merge(stack[i - 1], stack[i], func);
7709 for (; stack[0]; stack[0] = stack[0]->next)
7711 stack[0]->prev = prev;
7718 tail->next = unsort;
7719 unsort->prev = tail;
7722 list->accounting->last = tail;
7724 if (!sd->fx_mode) sd->sorting = EINA_FALSE;
7725 if (sd->decorate_all_mode) sd->sorting = EINA_FALSE;
7726 sd->s_iface->content_region_show(obj, 0,0,0,0);
7727 sd->pan_changed = EINA_TRUE;
7728 evas_object_smart_changed(sd->pan_obj);