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) \
26 &&(!(GL_IT(_it)->type & ELM_GENLIST_ITEM_TREE)))) \
28 static const Evas_Smart_Interface *_smart_interfaces[] =
30 (Evas_Smart_Interface *)&ELM_SCROLLABLE_IFACE, NULL
33 static const char SIG_ACTIVATED[] = "activated";
34 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
35 static const char SIG_SELECTED[] = "selected";
36 static const char SIG_UNSELECTED[] = "unselected";
37 static const char SIG_EXPANDED[] = "expanded";
38 static const char SIG_CONTRACTED[] = "contracted";
39 static const char SIG_EXPAND_REQUEST[] = "expand,request";
40 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
41 static const char SIG_REALIZED[] = "realized";
42 static const char SIG_UNREALIZED[] = "unrealized";
43 static const char SIG_DRAG_START_UP[] = "drag,start,up";
44 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
45 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
46 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
47 static const char SIG_DRAG_STOP[] = "drag,stop";
48 static const char SIG_DRAG[] = "drag";
49 static const char SIG_LONGPRESSED[] = "longpressed";
50 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
51 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
52 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
53 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
54 static const char SIG_EDGE_TOP[] = "edge,top";
55 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
56 static const char SIG_EDGE_LEFT[] = "edge,left";
57 static const char SIG_EDGE_RIGHT[] = "edge,right";
58 static const char SIG_VBAR_DRAG[] = "vbar,drag";
59 static const char SIG_VBAR_PRESS[] = "vbar,press";
60 static const char SIG_VBAR_UNPRESS[] = "vbar,unpress";
61 static const char SIG_HBAR_DRAG[] = "hbar,drag";
62 static const char SIG_HBAR_PRESS[] = "hbar,press";
63 static const char SIG_HBAR_UNPRESS[] = "hbar,unpress";
64 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
65 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
66 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
67 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
68 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
69 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
70 static const char SIG_SWIPE[] = "swipe";
71 static const char SIG_MOVED[] = "moved";
72 static const char SIG_MOVED_AFTER[] = "moved,after";
73 static const char SIG_MOVED_BEFORE[] = "moved,before";
74 static const char SIG_INDEX_UPDATE[] = "index,update";
75 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
76 static const char SIG_HIGHLIGHTED[] = "highlighted";
77 static const char SIG_UNHIGHLIGHTED[] = "unhighlighted";
79 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
80 {SIG_CLICKED_DOUBLE, ""},
86 {SIG_EXPAND_REQUEST, ""},
87 {SIG_CONTRACT_REQUEST, ""},
90 {SIG_DRAG_START_UP, ""},
91 {SIG_DRAG_START_DOWN, ""},
92 {SIG_DRAG_START_LEFT, ""},
93 {SIG_DRAG_START_RIGHT, ""},
96 {SIG_LONGPRESSED, ""},
97 {SIG_SCROLL_ANIM_START, ""},
98 {SIG_SCROLL_ANIM_STOP, ""},
99 {SIG_SCROLL_DRAG_START, ""},
100 {SIG_SCROLL_DRAG_STOP, ""},
102 {SIG_EDGE_BOTTOM, ""},
104 {SIG_EDGE_RIGHT, ""},
106 {SIG_VBAR_PRESS, ""},
107 {SIG_VBAR_UNPRESS, ""},
109 {SIG_HBAR_PRESS, ""},
110 {SIG_HBAR_UNPRESS, ""},
111 {SIG_MULTI_SWIPE_LEFT, ""},
112 {SIG_MULTI_SWIPE_RIGHT, ""},
113 {SIG_MULTI_SWIPE_UP, ""},
114 {SIG_MULTI_SWIPE_DOWN, ""},
115 {SIG_MULTI_PINCH_OUT, ""},
116 {SIG_MULTI_PINCH_IN, ""},
119 {SIG_MOVED_AFTER, ""},
120 {SIG_MOVED_BEFORE, ""},
121 {SIG_TREE_EFFECT_FINISHED, ""},
122 {SIG_HIGHLIGHTED, ""},
123 {SIG_UNHIGHLIGHTED, ""},
127 EVAS_SMART_SUBCLASS_IFACE_NEW
128 (ELM_GENLIST_SMART_NAME, _elm_genlist, Elm_Genlist_Smart_Class,
129 Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks,
132 ELM_INTERNAL_SMART_SUBCLASS_NEW
133 (ELM_GENLIST_PAN_SMART_NAME, _elm_genlist_pan, Elm_Genlist_Pan_Smart_Class,
134 Elm_Pan_Smart_Class, elm_pan_smart_class_get, NULL);
136 static void _calc_job(void *);
137 static Eina_Bool _item_block_recalc(Item_Block *, int, Eina_Bool);
138 static void _item_mouse_callbacks_add(Elm_Gen_Item *, Evas_Object *);
139 static void _item_mouse_callbacks_del(Elm_Gen_Item *, Evas_Object *);
140 static void _access_activate_cb(void *data __UNUSED__,
141 Evas_Object *part_obj __UNUSED__,
142 Elm_Object_Item *item);
143 static void _item_select(Elm_Gen_Item *it);
145 static void _expand_toggle_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
146 static void _expand_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
147 static void _contract_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
148 static void _elm_genlist_item_state_update(Elm_Gen_Item *it);
149 static void _decorate_item_unrealize(Elm_Gen_Item *it);
150 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
151 static void _decorate_item_set(Elm_Gen_Item *it);
152 static void _changed_job(Elm_Genlist_Smart_Data *sd);
154 #if GENLIST_FX_SUPPORT
155 static Eina_Bool _elm_genlist_fx_capture(Evas_Object *obj, int level);
156 static void _elm_genlist_fx_play(Evas_Object *obj);
157 static void _elm_genlist_fx_clear(Evas_Object *obj, Eina_Bool force);
158 static void _elm_genlist_proxy_item_del(const Elm_Object_Item *item);
161 #if GENLIST_PINCH_ZOOM_SUPPORT
162 EAPI Eina_Bool elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Elm_Gen_Pinch_Zoom_Mode mode);
166 _item_cache_all_free(Elm_Genlist_Smart_Data *sd)
168 // It would be better not to use
169 // EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
170 while (sd->item_cache)
172 Item_Cache *ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
173 if (ic->spacer) evas_object_del(ic->spacer);
174 if (ic->base_view) evas_object_del(ic->base_view);
175 if (ic->item_style) eina_stringshare_del(ic->item_style);
176 sd->item_cache = eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
177 // Free should be performed after inlist is poped
180 sd->item_cache = NULL;
181 sd->item_cache_count = 0;
185 _item_cache_push(Elm_Gen_Item *it)
187 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
188 Item_Cache *ic = NULL;
190 if (sd->item_cache_count >= sd->item_cache_max)
192 ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
193 if (ic->spacer) evas_object_del(ic->spacer);
194 if (ic->base_view) evas_object_del(ic->base_view);
195 eina_stringshare_del(ic->item_style);
196 sd->item_cache = eina_inlist_remove(sd->item_cache,
197 sd->item_cache->last);
198 sd->item_cache_count--;
199 // Free should be performed after inlist is poped
202 //evas_event_freeze(evas_object_evas_get(obj));
204 edje_object_mirrored_set(VIEW(it),
205 elm_widget_mirrored_get(WIDGET(it)));
206 edje_object_scale_set(VIEW(it),
207 elm_widget_scale_get(WIDGET(it))
208 * elm_config_scale_get());
210 // FIXME: other callbacks?
211 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand,toggle",
212 "elm", _expand_toggle_signal_cb, it);
213 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand", "elm",
214 _expand_signal_cb, it);
215 edje_object_signal_callback_del_full(VIEW(it), "elm,action,contract", "elm",
216 _contract_signal_cb, it);
217 _item_mouse_callbacks_del(it, VIEW(it));
219 #if GENLIST_FX_SUPPORT
220 if ((it->item->nocache_once) || (it->item->nocache) || (sd->pending_del_items))
222 if ((it->item->nocache_once) || (it->item->nocache))
225 if (VIEW(it)) evas_object_del(VIEW(it));
226 if (it->spacer) evas_object_del(it->spacer);
229 ic = ELM_NEW(Item_Cache);
232 if (VIEW(it)) evas_object_del(VIEW(it));
233 if (it->spacer) evas_object_del(it->spacer);
238 ecore_timer_del(it->long_timer);
239 it->long_timer = NULL;
241 if (it->item->swipe_timer)
243 ecore_timer_del(it->item->swipe_timer);
244 it->item->swipe_timer = NULL;
247 ic->base_view = VIEW(it);
248 ic->spacer = it->spacer;
249 ic->item_style = eina_stringshare_add(it->itc->item_style);
250 if (it->item->type & ELM_GENLIST_ITEM_TREE) ic->tree = 1;
252 ic->selected = it->selected;
253 ic->disabled = elm_widget_item_disabled_get(it);
254 ic->expanded = it->item->expanded;
255 if (it->item->type & ELM_GENLIST_ITEM_TREE) ic->tree = 1;
257 edje_object_signal_emit(ic->base_view, "elm,state,unselected", "elm");
258 evas_object_hide(ic->base_view);
260 sd->item_cache = eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(ic));
261 sd->item_cache_count++;
267 it->realized = EINA_FALSE;
268 it->want_unrealize = EINA_FALSE;
270 //evas_event_thaw(evas_object_evas_get(obj));
271 //evas_event_thaw_eval(evas_object_evas_get(obj));
275 _item_cache_pop(Elm_Gen_Item *it)
277 Item_Cache *ic = NULL;
280 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
282 if (it->item->nocache_once) {
283 it->item->nocache_once = EINA_FALSE;
286 if (it->item->nocache) return EINA_FALSE;
288 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
289 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, ic)
291 if ((ic->selected) || (ic->disabled) || (ic->expanded))
294 if ((ic->tree == tree) &&
295 (((!it->itc->item_style) && (!ic->item_style)) ||
296 (it->itc->item_style && ic->item_style &&
297 (!strcmp(it->itc->item_style, ic->item_style)))))
300 eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
301 sd->item_cache_count--;
303 VIEW(it) = ic->base_view;
304 it->spacer = ic->spacer;
306 #if 1 // FIXME: different from upstream
307 // Because of item cache, set state as default after cache item
309 edje_object_signal_emit(VIEW(it),"elm,state,default", "elm");
311 edje_object_signal_callback_add
312 (VIEW(it), "elm,action,expand,toggle", "elm",
313 _expand_toggle_signal_cb, it);
314 edje_object_signal_callback_add
315 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
316 edje_object_signal_callback_add
317 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
318 _item_mouse_callbacks_add(it, VIEW(it));
320 eina_stringshare_del(ic->item_style);
330 _elm_genlist_pan_smart_pos_set(Evas_Object *obj,
336 ELM_GENLIST_PAN_DATA_GET(obj, psd);
338 if ((x == psd->wsd->pan_x) && (y == psd->wsd->pan_y)) return;
342 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
344 if ((itb->y + itb->h) > y)
349 EINA_LIST_FOREACH(itb->items, l2, it)
351 if ((itb->y + it->y) >= y)
353 psd->wsd->anchor_item = it;
354 psd->wsd->anchor_y = -(itb->y + it->y - y);
361 if (!psd->wsd->reorder_move_animator) evas_object_smart_changed(obj);
365 _elm_genlist_pan_smart_pos_get(const Evas_Object *obj,
369 ELM_GENLIST_PAN_DATA_GET(obj, psd);
371 if (x) *x = psd->wsd->pan_x;
372 if (y) *y = psd->wsd->pan_y;
376 _elm_genlist_pan_smart_pos_max_get(const Evas_Object *obj,
382 ELM_GENLIST_PAN_DATA_GET(obj, psd);
384 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
385 ow = psd->wsd->minw - ow;
387 oh = psd->wsd->minh - oh;
392 #if GENLIST_PINCH_ZOOM_SUPPORT
393 if (psd->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
395 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
396 if (psd->wsd->pinch_zoom_h > oh)
397 *y = psd->wsd->pinch_zoom_h - oh;
404 _elm_genlist_pan_smart_pos_min_get(const Evas_Object *obj __UNUSED__,
413 _elm_genlist_pan_smart_content_size_get(const Evas_Object *obj,
417 ELM_GENLIST_PAN_DATA_GET(obj, psd);
419 if (w) *w = psd->wsd->minw;
420 if (h) *h = psd->wsd->minh;
424 _elm_genlist_pan_smart_add(Evas_Object *obj)
426 /* here just to allocate our extended data */
427 EVAS_SMART_DATA_ALLOC(obj, Elm_Genlist_Pan_Smart_Data);
429 ELM_PAN_CLASS(_elm_genlist_pan_parent_sc)->base.add(obj);
433 _elm_genlist_pan_smart_del(Evas_Object *obj)
435 ELM_GENLIST_PAN_DATA_GET(obj, psd);
439 ecore_job_del(psd->resize_job);
440 psd->resize_job = NULL;
443 _elm_genlist_pan_parent_sc->base.del(obj);
447 _elm_genlist_pan_smart_move(Evas_Object *obj,
448 Evas_Coord x __UNUSED__,
449 Evas_Coord y __UNUSED__)
451 ELM_GENLIST_PAN_DATA_GET(obj, psd);
453 psd->wsd->pan_changed = EINA_TRUE;
454 evas_object_smart_changed(obj);
455 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
456 psd->wsd->calc_job = NULL;
460 _elm_genlist_pan_smart_resize(Evas_Object *obj,
464 Evas_Coord ow = 0, oh = 0, vw = 0;
466 ELM_GENLIST_PAN_DATA_GET(obj, psd);
468 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
469 if ((ow == w) && (oh == h)) return;
471 psd->wsd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(psd->wsd)->obj,
473 if (psd->wsd->mode == ELM_LIST_COMPRESS &&
474 vw != psd->wsd->prev_viewport_w)
475 psd->wsd->size_changed = EINA_TRUE;
476 if (vw != 0) psd->wsd->prev_viewport_w = vw;
478 psd->wsd->pan_changed = EINA_TRUE;
479 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
480 psd->wsd->calc_job = ecore_job_add(_calc_job, psd->wsd);
484 _item_scroll(Elm_Genlist_Smart_Data *sd)
487 Elm_Gen_Item *it = NULL;
488 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
490 if (!sd->show_item) return;
492 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &oh);
494 dx = it->x + it->item->block->x;
495 dy = it->y + it->item->block->y;
496 dw = it->item->block->w;
499 switch (sd->scroll_to_type)
501 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
502 if (it->item->group_item) gith = it->item->group_item->item->h;
506 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
507 dy += ((it->item->h / 2) - (oh / 2));
510 case ELM_GENLIST_ITEM_SCROLLTO_IN:
512 if ((sd->expanded_item) &&
513 ((sd->show_item->y + sd->show_item->item->block->y
514 + sd->show_item->item->h) -
515 (sd->expanded_item->y + sd->expanded_item->item->block->y) > oh))
517 it = sd->expanded_item;
518 if (it->item->group_item) gith = it->item->group_item->item->h;
519 dx = it->x + it->item->block->x;
520 dy = it->y + it->item->block->y - gith;
521 dw = it->item->block->w;
525 if ((it->item->group_item) &&
526 (sd->pan_y > (it->y + it->item->block->y)))
527 gith = it->item->group_item->item->h;
534 sd->s_iface->region_bring_in(ELM_WIDGET_DATA(sd)->obj, dx, dy, dw, dh);
536 sd->s_iface->content_region_show
537 (ELM_WIDGET_DATA(sd)->obj, dx, dy, dw, dh);
539 it->item->show_me = EINA_FALSE;
540 sd->show_item = NULL;
541 sd->auto_scroll_enabled = EINA_FALSE;
542 sd->check_scroll = EINA_FALSE;
546 _item_unrealize(Elm_Gen_Item *it,
549 Evas_Object *content;
553 if (!it->realized) return;
554 if (GL_IT(it)->wsd->reorder_it == it) return;
556 #if GENLIST_FX_SUPPORT
557 if ((GL_IT(it)->has_proxy_it) && (!GL_IT(it)->wsd->genlist_clearing))
559 if (!eina_list_data_find(GL_IT(it)->wsd->pending_unrealized_items, it))
560 GL_IT(it)->wsd->pending_unrealized_items =
561 eina_list_append(GL_IT(it)->wsd->pending_unrealized_items, it);
565 #if GENLIST_ENTRY_SUPPORT
566 if (it->item->unrealize_disabled)
568 evas_object_hide(VIEW(it));
573 //evas_event_freeze(evas_object_evas_get(WIDGET(it)));
575 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
578 ecore_timer_del(it->long_timer);
579 it->long_timer = NULL;
581 if (it->item->swipe_timer)
583 ecore_timer_del(it->item->swipe_timer);
584 it->item->swipe_timer = NULL;
588 EINA_LIST_FOREACH(it->texts, l, part)
589 edje_object_part_text_set(VIEW(it), part, NULL);
591 elm_widget_stringlist_free(it->texts);
593 elm_widget_stringlist_free(it->contents);
595 elm_widget_stringlist_free(it->states);
597 EINA_LIST_FREE(it->content_objs, content)
599 // FIXME: If parent-child relationship was broken before 'ic'
600 // is deleted, freeze_pop will not be called. ex) elm_slider
601 // If layout is used instead of edje, this problme can be
603 if (0 != elm_widget_scroll_freeze_get(content))
604 elm_widget_scroll_freeze_pop(content);
605 evas_object_del(content);
609 elm_widget_stringlist_free(it->item->flip_contents);
610 it->item->flip_contents = NULL;
611 EINA_LIST_FREE(it->item->flip_content_objs, content)
612 evas_object_del(content);
615 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
616 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
618 // unswallow VIEW(it) first then manipulate VIEW(it)
619 _decorate_item_unrealize(it);
620 _decorate_all_item_unrealize(it);
622 edje_object_signal_emit
623 (VIEW(it), "elm,state,decorate,disabled", "elm");
624 edje_object_signal_emit
625 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
626 edje_object_message_signal_process(VIEW(it));
628 it->realized = EINA_FALSE;
629 _item_cache_push(it);
631 #if GENLIST_ENTRY_SUPPORT
632 it->item->unrealize_disabled = EINA_FALSE;
634 it->want_unrealize = EINA_FALSE;
636 //evas_event_thaw(evas_object_evas_get(WIDGET(it)));
637 //evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
641 _item_block_unrealize(Item_Block *itb)
645 Eina_Bool dragging = EINA_FALSE;
647 if (!itb->realized) return;
648 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
650 EINA_LIST_FOREACH(itb->items, l, it)
652 if (itb->must_recalc || !it->group)
656 dragging = EINA_TRUE;
657 it->want_unrealize = EINA_TRUE;
660 _item_unrealize(it, EINA_FALSE);
665 itb->realized = EINA_FALSE;
666 itb->want_unrealize = EINA_TRUE;
669 itb->want_unrealize = EINA_FALSE;
670 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
671 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
675 _must_recalc_idler(void *data)
677 Elm_Genlist_Smart_Data *sd = data;
679 if (sd->calc_job) ecore_job_del(sd->calc_job);
680 sd->calc_job = ecore_job_add(_calc_job, sd);
681 sd->must_recalc_idler = NULL;
682 return ECORE_CALLBACK_CANCEL;
686 _calc_job(void *data)
689 Item_Block *itb, *chb = NULL;
690 Evas_Coord pan_w = 0, pan_h = 0;
691 Elm_Genlist_Smart_Data *sd = data;
692 Eina_Bool minw_change = EINA_FALSE;
693 Eina_Bool did_must_recalc = EINA_FALSE;
694 Evas_Coord minw = -1, minh = 0, y = 0, dy = 0, vw = 0;
696 sd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(sd)->obj, &sd->w, &sd->h);
698 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
699 EINA_INLIST_FOREACH(sd->blocks, itb)
701 Eina_Bool show_me = EINA_FALSE;
704 show_me = itb->show_me;
705 itb->show_me = EINA_FALSE;
708 if (itb->realized) _item_block_unrealize(itb);
710 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
712 if (itb->must_recalc)
717 EINA_LIST_FOREACH(itb->items, l, it)
718 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
719 itb->changed = EINA_TRUE;
720 did_must_recalc = EINA_TRUE;
721 if (itb->realized) _item_block_unrealize(itb);
722 itb->must_recalc = EINA_FALSE;
724 show_me = _item_block_recalc(itb, in, EINA_FALSE);
730 if (minw == -1) minw = itb->minw;
731 else if ((!itb->must_recalc) && (minw < itb->minw))
734 minw_change = EINA_TRUE;
736 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
739 minw_change = EINA_TRUE;
745 if ((show_me) && (sd->show_item) && (!sd->show_item->item->queued))
746 sd->check_scroll = EINA_TRUE;
750 EINA_INLIST_FOREACH(sd->blocks, itb)
756 if ((chb) && (EINA_INLIST_GET(chb)->next))
758 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
760 if (itb->realized) _item_block_unrealize(itb);
764 if (minw < sd->w) minw = sd->w;
765 if ((minw != sd->minw) || (minh != sd->minh))
769 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
770 elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
777 if ((sd->anchor_item) && (sd->anchor_item->item->block)
778 && (!sd->auto_scroll_enabled))
783 it = sd->anchor_item;
785 sd->s_iface->content_pos_set
786 (ELM_WIDGET_DATA(sd)->obj, sd->pan_x, it->item->block->y
787 + it->y + it_y, EINA_TRUE);
788 sd->anchor_item = it;
794 if (!sd->must_recalc_idler)
795 sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, sd);
797 if (sd->check_scroll)
799 _elm_genlist_pan_smart_content_size_get(sd->pan_obj, &pan_w, &pan_h);
800 if (EINA_INLIST_GET(sd->show_item) == sd->items->last)
801 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
803 switch (sd->scroll_to_type)
805 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
809 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
813 case ELM_GENLIST_ITEM_SCROLLTO_IN:
818 if ((sd->show_item) && (sd->show_item->item->block))
820 if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
821 && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
830 evas_object_smart_changed(sd->pan_obj);
831 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
832 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
836 _elm_genlist_smart_sizing_eval(Evas_Object *obj)
838 Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1, vw = 0;
840 ELM_GENLIST_DATA_GET(obj, sd);
842 /* parent class' early call */
843 if (!sd->s_iface) return;
844 if (sd->on_sub_del) return;;
846 evas_object_size_hint_min_get(obj, &minw, NULL);
847 evas_object_size_hint_max_get(obj, &maxw, &maxh);
848 edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
850 sd->s_iface->content_viewport_size_get(obj, &vw, NULL);
851 if (vw != 0) sd->prev_viewport_w = vw;
853 if (sd->mode == ELM_LIST_LIMIT)
856 minw = minw + sd->realminw;
859 evas_object_size_hint_min_set(obj, minw, minh);
860 evas_object_size_hint_max_set(obj, maxw, maxh);
864 _item_position(Elm_Gen_Item *it,
872 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
873 evas_object_resize(view, it->item->w, it->item->h);
874 evas_object_move(view, it_x, it_y);
875 evas_object_show(view);
876 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
877 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
881 _item_sub_items_clear(Elm_Gen_Item *it)
884 Elm_Object_Item *it2;
886 EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, it2)
887 elm_widget_item_del(it2);
891 _item_auto_scroll(Elm_Genlist_Smart_Data *sd)
893 Elm_Gen_Item *tmp_item = NULL;
895 #if GENLIST_FX_SUPPORT
896 if (sd->fx_first_captured) return;
898 if ((sd->expanded_item) && (sd->auto_scroll_enabled))
900 tmp_item = eina_list_data_get
901 (eina_list_last(sd->expanded_item->item->items));
902 if (!tmp_item) return;
903 sd->show_item = tmp_item;
904 sd->bring_in = EINA_TRUE;
905 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
906 if ((sd->show_item->item->queued) || (!sd->show_item->item->mincalcd))
908 sd->show_item->item->show_me = EINA_TRUE;
909 sd->auto_scroll_enabled = EINA_FALSE;
917 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
919 if (!it->item->nostacking)
921 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
923 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
924 else evas_object_lower(VIEW(it));
928 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
929 else evas_object_raise(VIEW(it));
933 if (it->item->order_num_in & 0x1)
935 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
936 if (it->deco_all_view)
937 edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
941 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
942 if (it->deco_all_view)
943 edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
948 _item_order_update(const Eina_Inlist *l,
951 Elm_Gen_Item *it, *it2;
953 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next,
954 it = ELM_GEN_ITEM_FROM_INLIST(l))
956 it->item->order_num_in = start++;
957 _elm_genlist_item_odd_even_update(it);
958 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
959 if (it2 && (it->item->order_num_in != it2->item->order_num_in))
965 _elm_genlist_item_state_update(Elm_Gen_Item *it)
969 if (it->deco_all_view)
970 edje_object_signal_emit
971 (it->deco_all_view, "elm,state,selected", "elm");
972 edje_object_signal_emit
973 (VIEW(it), "elm,state,selected", "elm");
974 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
976 if (elm_widget_item_disabled_get(it))
978 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
979 if (it->deco_all_view)
980 edje_object_signal_emit
981 (it->deco_all_view, "elm,state,disabled", "elm");
983 if (it->item->expanded)
985 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
986 if (it->deco_all_view)
987 edje_object_signal_emit
988 (it->deco_all_view, "elm,state,expanded", "elm");
993 _elm_genlist_item_index_update(Elm_Gen_Item *it)
995 if (it->position_update || it->item->block->position_update)
997 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
998 it->position_update = EINA_FALSE;
1003 _item_text_realize(Elm_Gen_Item *it,
1004 Evas_Object *target,
1008 if (it->itc->func.text_get)
1014 *source = elm_widget_stringlist_get
1015 (edje_object_data_get(target, "texts"));
1016 EINA_LIST_FOREACH(*source, l, key)
1018 if (parts && fnmatch(parts, key, FNM_PERIOD))
1021 char *s = it->itc->func.text_get
1022 ((void *)it->base.data, WIDGET(it), key);
1026 edje_object_part_text_escaped_set(target, key, s);
1031 edje_object_part_text_set(target, key, "");
1038 // FIXME: difference from upstream
1040 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1042 Elm_Gen_Item *it = data;
1043 if (it) it->defer_unrealize = EINA_TRUE;
1047 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1049 Elm_Gen_Item *it = data;
1050 if (it) it->defer_unrealize = EINA_FALSE;
1055 _item_mode_content_realize(Elm_Gen_Item *it,
1056 Evas_Object *target,
1059 Eina_List **contents_list)
1061 Eina_List *res = *contents_list;
1063 if (it->itc->func.content_get)
1069 EINA_LIST_FOREACH(*source, l, key)
1071 if (parts && fnmatch(parts, key, FNM_PERIOD))
1074 ic = it->itc->func.content_get
1075 ((void *)it->base.data, WIDGET(it), key);
1079 res = eina_list_append(res, ic);
1080 edje_object_part_swallow(target, key, ic);
1081 evas_object_show(ic);
1082 #if GENLIST_ENTRY_SUPPORT
1085 // For entry or editfield
1086 // 1. Add resize callback for multiline entry.
1087 // 2. Do not unrealize it for focus issue
1088 // ps. Only for entry because of performnace
1089 if (!strcmp("elm_entry", evas_object_type_get(ic)))
1090 it->item->unrealize_disabled = EINA_TRUE;
1094 // FIXME: difference from upstream
1097 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1098 // genlist does not need to handle this focus thing.
1099 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1100 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1103 if (elm_widget_item_disabled_get(it))
1104 elm_widget_disabled_set(ic, EINA_TRUE);
1113 _item_state_realize(Elm_Gen_Item *it,
1114 Evas_Object *target,
1118 if (it->itc->func.state_get)
1125 *source = elm_widget_stringlist_get
1126 (edje_object_data_get(target, "states"));
1127 EINA_LIST_FOREACH(*source, l, key)
1129 if (parts && fnmatch(parts, key, FNM_PERIOD))
1132 Eina_Bool on = it->itc->func.state_get
1133 ((void *)it->base.data, WIDGET(it), key);
1137 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1138 edje_object_signal_emit(target, buf, "elm");
1142 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1143 edje_object_signal_emit(target, buf, "elm");
1150 _decorate_item_unrealize(Elm_Gen_Item *it)
1152 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
1153 Evas_Object *content;
1155 if (!it->item->deco_it_view) return;
1157 //evas_event_freeze(evas_object_evas_get(obj));
1158 elm_widget_stringlist_free(it->item->deco_it_texts);
1159 it->item->deco_it_texts = NULL;
1160 elm_widget_stringlist_free(it->item->deco_it_contents);
1161 it->item->deco_it_contents = NULL;
1162 elm_widget_stringlist_free(it->item->deco_it_states);
1164 EINA_LIST_FREE (it->item->deco_it_content_objs, content)
1165 evas_object_del(content);
1167 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
1168 evas_object_smart_member_add(VIEW(it), sd->pan_obj);
1169 evas_object_del(it->item->deco_it_view);
1170 it->item->deco_it_view = NULL;
1172 if (sd->mode_item == it) sd->mode_item = NULL;
1173 //evas_event_thaw(evas_object_evas_get(obj));
1174 //evas_event_thaw_eval(evas_object_evas_get(obj));
1179 _decorate_all_item_position(Elm_Gen_Item *it,
1183 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
1184 evas_object_move(it->deco_all_view, itx, ity);
1188 _decorate_all_item_realize(Elm_Gen_Item *it,
1189 Eina_Bool effect_on)
1192 const char *stacking;
1193 const char *stacking_even;
1195 if ((!it) || (it->item->decorate_all_item_realized)) return;
1197 if (it->item->deco_it_view) _decorate_item_unrealize(it);
1199 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1200 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
1201 elm_config_scale_get());
1202 evas_object_smart_member_add(it->deco_all_view, GL_IT(it)->wsd->pan_obj);
1203 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
1205 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1206 strncpy(buf, "tree", sizeof(buf));
1207 else strncpy(buf, "item", sizeof(buf));
1208 if (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)
1209 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1211 strncat(buf, "/", sizeof(buf) - strlen(buf));
1212 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
1214 elm_widget_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
1215 elm_widget_style_get(WIDGET(it)));
1217 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1218 if (!stacking_even) stacking_even = "above";
1219 it->item->stacking_even = !!strcmp("above", stacking_even);
1221 stacking = edje_object_data_get(VIEW(it), "stacking");
1222 if (!stacking) stacking = "yes";
1223 it->item->nostacking = !!strcmp("yes", stacking);
1225 edje_object_mirrored_set
1226 (it->deco_all_view, elm_widget_mirrored_get(WIDGET(it)));
1228 _elm_genlist_item_odd_even_update(it);
1229 _elm_genlist_item_state_update(it);
1231 #if 1 // FIXME: difference from upstream
1232 if (GL_IT(it)->wsd->reorder_mode)
1233 edje_object_signal_emit
1234 (it->deco_all_view, "elm,state,reorder,mode_set", "elm");
1236 edje_object_signal_emit
1237 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
1241 edje_object_signal_emit
1242 (it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
1243 edje_object_signal_emit
1244 (VIEW(it), "elm,state,decorate,enabled,effect", "elm");
1248 edje_object_signal_emit
1249 (it->deco_all_view, "elm,state,decorate,enabled", "elm");
1250 edje_object_signal_emit
1251 (VIEW(it), "elm,state,decorate,enabled", "elm");
1253 _item_mouse_callbacks_del(it, VIEW(it));
1254 _item_mouse_callbacks_add(it, it->deco_all_view);
1256 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
1258 edje_object_signal_emit
1259 (it->deco_all_view, "elm,state,flip,enabled", "elm");
1260 if (!it->item->deco_all_contents)
1261 it->item->deco_all_contents = elm_widget_stringlist_get
1262 (edje_object_data_get(it->deco_all_view, "contents"));
1263 it->item->deco_all_content_objs =
1264 _item_mode_content_realize(it, it->deco_all_view,
1265 &it->item->deco_all_contents, NULL,
1266 &it->item->deco_all_content_objs);
1268 (it, it->deco_all_view, &it->item->deco_all_states, NULL);
1269 edje_object_part_swallow
1270 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1272 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
1273 evas_object_show(it->deco_all_view);
1277 edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
1278 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
1281 it->item->decorate_all_item_realized = EINA_TRUE;
1282 it->want_unrealize = EINA_FALSE;
1286 _expand_toggle_signal_cb(void *data,
1287 Evas_Object *obj __UNUSED__,
1288 const char *emission __UNUSED__,
1289 const char *source __UNUSED__)
1291 Elm_Gen_Item *it = data;
1293 if (it->item->expanded)
1294 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1296 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1300 _expand_signal_cb(void *data,
1301 Evas_Object *obj __UNUSED__,
1302 const char *emission __UNUSED__,
1303 const char *source __UNUSED__)
1305 Elm_Gen_Item *it = data;
1307 if (!it->item->expanded)
1308 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1312 _contract_signal_cb(void *data,
1313 Evas_Object *obj __UNUSED__,
1314 const char *emission __UNUSED__,
1315 const char *source __UNUSED__)
1317 Elm_Gen_Item *it = data;
1319 if (it->item->expanded)
1320 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1323 #if GENLIST_ENTRY_SUPPORT
1325 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1327 Elm_Gen_Item *it = data;
1329 if (it->want_unrealize) return;
1330 GL_IT(it)->wsd->size_changed = EINA_TRUE;
1331 evas_object_smart_changed(GL_IT(it)->wsd->pan_obj);
1336 _item_content_realize(Elm_Gen_Item *it,
1337 Evas_Object *target,
1341 Eina_List *res = it->content_objs;
1343 if (it->itc->func.content_get)
1347 Evas_Object *ic = NULL;
1350 *source = elm_widget_stringlist_get
1351 (edje_object_data_get(target, "contents"));
1353 EINA_LIST_FOREACH(*source, l, key)
1355 if (parts && fnmatch(parts, key, FNM_PERIOD))
1358 if (it->itc->func.content_get)
1359 ic = it->itc->func.content_get
1360 ((void *)it->base.data, WIDGET(it), key);
1363 res = eina_list_append(res, ic);
1364 edje_object_part_swallow(target, key, ic);
1365 evas_object_show(ic);
1367 #if GENLIST_ENTRY_SUPPORT
1368 // For entry or editfield
1369 // 1. Add resize callback for multiline entry.
1370 // 2. Do not unrealize it for focus issue
1371 // ps. Only for entry because of performnace
1372 if (!strcmp("elm_entry", evas_object_type_get(ic)))
1374 if (!elm_entry_single_line_get(ic))
1375 evas_object_event_callback_add
1376 (ic, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1377 _changed_size_hints, it);
1378 it->item->unrealize_disabled = EINA_TRUE;
1381 #if 0 // FIXME: difference from upstream
1384 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1385 // genlist does not need to handle this focus thing.
1386 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1387 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1390 if (elm_widget_item_disabled_get(it))
1391 elm_widget_disabled_set(ic, EINA_TRUE);
1400 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
1405 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1406 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1408 buf = eina_strbuf_new();
1410 if (it->itc->func.text_get)
1415 if (!(it->texts)) it->texts =
1416 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1418 EINA_LIST_FOREACH(it->texts, l, key)
1420 char *s = it->itc->func.text_get
1421 ((void *)it->base.data, WIDGET(it), key);
1423 s = _elm_util_mkup_to_text(s);
1427 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1428 eina_strbuf_append(buf, s);
1434 ret = eina_strbuf_string_steal(buf);
1435 eina_strbuf_free(buf);
1440 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
1442 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1443 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1445 if (it->base.disabled)
1446 return strdup(E_("State: Disabled"));
1452 _access_on_highlight_cb(void *data)
1454 Evas_Coord x, y, w, h;
1455 Evas_Coord sx, sy, sw, sh;
1456 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1457 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1459 ELM_GENLIST_DATA_GET(it->base.widget, sd);
1461 evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
1462 // XXX There would be a reason.
1463 if ((w == 0) && (h == 0)) return;
1465 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
1466 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
1467 elm_genlist_item_bring_in((Elm_Object_Item *)it,
1468 ELM_GENLIST_ITEM_SCROLLTO_IN);
1472 _access_widget_item_register(Elm_Gen_Item *it)
1474 Elm_Access_Info *ai;
1476 _elm_access_widget_item_register((Elm_Widget_Item *)it);
1478 ai = _elm_access_object_get(it->base.access_obj);
1480 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1481 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1482 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
1483 _elm_access_activate_callback_set(ai, _access_activate_cb, it);
1487 _item_realize(Elm_Gen_Item *it,
1491 const char *treesize;
1497 if (it->item->order_num_in != in)
1499 _item_order_update(EINA_INLIST_GET(it), in);
1500 _elm_genlist_item_state_update(it);
1501 _elm_genlist_item_index_update(it);
1505 it->item->order_num_in = in;
1507 if (it->item->nocache_once | it->item->nocache ||
1508 it->item->type == ELM_GENLIST_ITEM_TREE || it->parent ||
1509 !_item_cache_pop(it))
1511 const char *stacking_even;
1512 const char *stacking;
1514 it->item->nocache_once = EINA_FALSE;
1516 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1517 edje_object_scale_set(VIEW(it),
1518 elm_widget_scale_get(WIDGET(it)) *
1519 elm_config_scale_get());
1520 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
1521 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1523 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1524 snprintf(buf, sizeof(buf), "tree%s/%s",
1525 GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS ? "_compress" :
1526 "", it->itc->item_style ? : "default");
1528 snprintf(buf, sizeof(buf), "item%s/%s",
1529 GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS ? "_compress" :
1530 "", it->itc->item_style ? : "default");
1532 elm_widget_theme_object_set
1533 (WIDGET(it), VIEW(it), "genlist", buf,
1534 elm_widget_style_get(WIDGET(it)));
1536 #if 1 // FIXME: difference from upstream
1537 if (it->item->expanded_depth > 0)
1538 edje_object_signal_emit(VIEW(it), "bg_color_change", "elm");
1541 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1542 if (!stacking_even) stacking_even = "above";
1543 it->item->stacking_even = !!strcmp("above", stacking_even);
1545 stacking = edje_object_data_get(VIEW(it), "stacking");
1546 if (!stacking) stacking = "yes";
1547 it->item->nostacking = !!strcmp("yes", stacking);
1549 edje_object_mirrored_set
1550 (VIEW(it), elm_widget_mirrored_get(WIDGET(it)));
1552 edje_object_signal_callback_add
1553 (VIEW(it), "elm,action,expand,toggle", "elm",
1554 _expand_toggle_signal_cb, it);
1555 edje_object_signal_callback_add
1556 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1557 edje_object_signal_callback_add
1558 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1559 _item_mouse_callbacks_add(it, VIEW(it));
1563 if (_elm_config->access_mode) _access_widget_item_register(it);
1565 _item_order_update(EINA_INLIST_GET(it), in);
1566 #if 1 // FIXME: difference from upstream
1567 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
1569 if (GL_IT(it)->wsd->reorder_mode)
1570 edje_object_signal_emit
1571 (VIEW(it), "elm,state,reorder,mode_set", "elm");
1573 edje_object_signal_emit
1574 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
1577 treesize = edje_object_data_get(VIEW(it), "treesize");
1578 if (treesize) tsize = atoi(treesize);
1579 if (it->parent && GL_IT(it->parent)->type == ELM_GENLIST_ITEM_TREE &&
1580 !it->spacer && treesize)
1583 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1584 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1588 evas_object_size_hint_min_set
1589 (it->spacer, (it->item->expanded_depth * tsize) *
1590 elm_config_scale_get(), 1);
1591 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1595 if ((GL_IT(it)->wsd->decorate_all_mode) && (!it->deco_all_view) &&
1596 (it->item->type != ELM_GENLIST_ITEM_GROUP) &&
1597 (it->itc->decorate_all_item_style))
1598 _decorate_all_item_realize(it, EINA_FALSE);
1600 _elm_genlist_item_state_update(it);
1601 _elm_genlist_item_index_update(it);
1604 /* homogenous genlist shortcut */
1605 if ((calc) && (GL_IT(it)->wsd->homogeneous) && (!it->item->mincalcd) &&
1606 ((it->group && GL_IT(it)->wsd->group_item_width) ||
1607 (!it->group && GL_IT(it)->wsd->item_width)))
1611 it->item->w = it->item->minw = GL_IT(it)->wsd->group_item_width;
1612 it->item->h = it->item->minh = GL_IT(it)->wsd->group_item_height;
1616 it->item->w = it->item->minw = GL_IT(it)->wsd->item_width;
1617 it->item->h = it->item->minh = GL_IT(it)->wsd->item_height;
1619 it->item->mincalcd = EINA_TRUE;
1623 if (eina_list_count(it->content_objs) != 0)
1624 ERR_ABORT("If you see this error, please notify us and we"
1627 _item_text_realize(it, VIEW(it), &it->texts, NULL);
1629 _item_content_realize(it, VIEW(it), &it->contents, NULL);
1630 _item_state_realize(it, VIEW(it), &it->states, NULL);
1633 edje_object_signal_emit
1634 (VIEW(it), "elm,state,flip,enabled", "elm");
1635 // This is needed before contents are swallowed
1636 edje_object_message_signal_process(VIEW(it));
1638 if (!(it->item->flip_contents))
1639 it->item->flip_contents = elm_widget_stringlist_get
1640 (edje_object_data_get(VIEW(it), "flips"));
1641 it->item->flip_content_objs = _item_mode_content_realize
1642 (it, VIEW(it), &it->item->flip_contents, NULL,
1643 &it->item->flip_content_objs);
1646 /* access: unregister item which have no text and content */
1647 if (_elm_config->access_mode && !it->texts && !it->contents)
1648 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1651 // FIXME: difference from upstream
1652 if (!it->item->mincalcd || ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
1654 if (!it->item->mincalcd)
1657 Evas_Coord mw = 0, mh = 0;
1659 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1660 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1661 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
1662 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
1663 (mw < GL_IT(it)->wsd->prev_viewport_w))
1664 mw = GL_IT(it)->wsd->prev_viewport_w;
1665 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
1666 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
1667 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
1668 (mw > GL_IT(it)->wsd->prev_viewport_w))
1669 mw = GL_IT(it)->wsd->prev_viewport_w;
1672 it->item->w = it->item->minw = mw;
1673 it->item->h = it->item->minh = mh;
1674 it->item->mincalcd = EINA_TRUE;
1676 if ((!GL_IT(it)->wsd->group_item_width) && (it->group))
1678 GL_IT(it)->wsd->group_item_width = mw;
1679 GL_IT(it)->wsd->group_item_height = mh;
1681 else if ((!GL_IT(it)->wsd->item_width) &&
1682 (it->item->type == ELM_GENLIST_ITEM_NONE))
1684 GL_IT(it)->wsd->item_width = mw;
1685 GL_IT(it)->wsd->item_height = mh;
1688 if (!calc) evas_object_show(VIEW(it));
1691 if (it->tooltip.content_cb)
1693 elm_widget_item_tooltip_content_cb_set
1694 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
1695 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1696 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1699 if (it->mouse_cursor)
1700 elm_widget_item_cursor_set(it, it->mouse_cursor);
1702 it->realized = EINA_TRUE;
1703 it->want_unrealize = EINA_FALSE;
1705 if (!calc || it->item->unrealize_disabled)
1706 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1708 if ((!calc) && (GL_IT(it)->wsd->decorate_all_mode) &&
1709 (it->item->type != ELM_GENLIST_ITEM_GROUP))
1711 if (it->itc->decorate_all_item_style)
1713 if (!it->deco_all_view)
1714 _decorate_all_item_realize(it, EINA_FALSE);
1715 edje_object_message_signal_process(it->deco_all_view);
1718 if ((!calc) && (it->decorate_it_set) &&
1719 (it->item->type != ELM_GENLIST_ITEM_GROUP))
1721 if (it->itc->decorate_item_style)
1723 if (!it->item->deco_it_view)
1724 _decorate_item_set(it);
1725 edje_object_message_signal_process(it->item->deco_it_view);
1728 edje_object_message_signal_process(VIEW(it));
1731 #if GENLIST_PINCH_ZOOM_SUPPORT
1733 _pinch_items_recalc(void *data)
1735 Elm_Genlist_Smart_Data *sd = data;
1740 Evas_Coord tot_y = 0, ox, oy;
1741 evas_object_geometry_get(sd->pan_obj, &ox, &oy, NULL, NULL);
1743 EINA_INLIST_FOREACH(sd->blocks, itb)
1745 EINA_LIST_FOREACH(itb->items, l, it)
1748 if (IS_ROOT_PARENT_IT(it))
1750 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
1752 if (!it->realized) _item_realize(it, 0, EINA_FALSE);
1753 it->item->scrl_y = oy + tot_y - sd->pan_y;
1754 evas_object_resize(VIEW(it), sd->minw, it->item->h);
1755 evas_object_move(VIEW(it), it->item->scrl_x, it->item->scrl_y);
1756 evas_object_show(VIEW(it));
1757 evas_object_raise(VIEW(it));
1758 tot_y += it->item->h;
1759 sd->pinch_zoom_h = tot_y;
1762 else if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND)
1764 evas_object_resize(VIEW(it), sd->minw, it->item->h);
1765 it->item->scrl_y = oy + it->item->pan_scrl_y - sd->pan_y;
1766 evas_object_move(VIEW(it), it->item->scrl_x, it->item->scrl_y);
1775 #if GROUP_ITEMS_FEATURE
1777 _group_items_recalc(void *data)
1781 Elm_Genlist_Smart_Data *sd = data;
1783 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1784 EINA_LIST_FOREACH(sd->group_items, l, git)
1786 if (git->item->want_realize)
1788 if (!git->realized) _item_realize(git, 0, EINA_FALSE);
1789 evas_object_resize(VIEW(git), sd->minw, git->item->h);
1790 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
1791 evas_object_show(VIEW(git));
1792 evas_object_raise(VIEW(git));
1794 else if (!git->item->want_realize)
1797 _item_unrealize(git, EINA_FALSE);
1800 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1801 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
1806 _reorder_move_animator_cb(void *data)
1809 Elm_Gen_Item *it = data;
1810 Eina_Bool down = EINA_FALSE;
1813 dy = 20 * elm_config_scale_get();
1814 t = ((0.0 > (t = ecore_loop_time_get()
1815 - GL_IT(it)->wsd->start_time)) ? 0.0 : t);
1817 if (t <= REORDER_EFFECT_TIME)
1818 y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
1821 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
1822 if (diff < dy) y = diff;
1824 if (it->item->old_scrl_y < it->item->scrl_y)
1826 it->item->old_scrl_y += y;
1829 else if (it->item->old_scrl_y > it->item->scrl_y)
1831 it->item->old_scrl_y -= y;
1835 if (it->deco_all_view)
1837 (it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
1838 else if (it->item->deco_it_view)
1840 (it, it->item->deco_it_view, it->item->scrl_x, it->item->old_scrl_y);
1842 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
1844 if ((GL_IT(it)->wsd->reorder_pan_move) ||
1845 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
1846 (!down && it->item->old_scrl_y <= it->item->scrl_y))
1848 it->item->old_scrl_y = it->item->scrl_y;
1849 it->item->move_effect_enabled = EINA_FALSE;
1850 GL_IT(it)->wsd->reorder_move_animator = NULL;
1851 return ECORE_CALLBACK_CANCEL;
1854 return ECORE_CALLBACK_RENEW;
1858 _reorder_item_space_get(Elm_Gen_Item *it)
1860 Elm_Gen_Item *reorder_it = GL_IT(it)->wsd->reorder_it;
1861 Evas_Coord rox, roy, row, roh, oy, oh;
1862 Eina_Bool top = EINA_FALSE;
1864 if (!reorder_it) return 0;
1865 if(it->deco_all_view) evas_object_lower(it->deco_all_view);
1867 evas_object_geometry_get(GL_IT(it)->wsd->pan_obj, NULL, &oy, NULL, &oh);
1868 evas_object_geometry_get
1869 (GL_IT(it)->wsd->VIEW(reorder_it), &rox, &roy, &row, &roh);
1871 if ((GL_IT(it)->wsd->reorder_start_y < it->item->block->y) &&
1872 (roy - oy + (roh / 2) >= it->item->block->y - GL_IT(it)->wsd->pan_y))
1874 it->item->block->reorder_offset =
1875 GL_IT(it)->wsd->reorder_it->item->h * -1;
1876 if (it->item->block->count == 1)
1877 GL_IT(it)->wsd->reorder_rel = it;
1879 else if ((GL_IT(it)->wsd->reorder_start_y >= it->item->block->y) &&
1880 (roy - oy + (roh / 2) <= it->item->block->y -
1881 GL_IT(it)->wsd->pan_y))
1883 it->item->block->reorder_offset = GL_IT(it)->wsd->reorder_it->item->h;
1886 it->item->block->reorder_offset = 0;
1888 it->item->scrl_y += it->item->block->reorder_offset;
1890 top = (ELM_RECTS_INTERSECT
1891 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
1892 rox, roy + (roh / 2), row, 1));
1895 GL_IT(it)->wsd->reorder_rel = it;
1896 it->item->scrl_y += GL_IT(it)->wsd->reorder_it->item->h;
1897 return GL_IT(it)->wsd->reorder_it->item->h;
1904 _item_block_position(Item_Block *itb,
1910 Eina_Bool vis = EINA_FALSE;
1911 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
1913 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
1914 evas_object_geometry_get(itb->sd->pan_obj, &ox, &oy, &ow, &oh);
1915 evas_output_viewport_get
1916 (evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj),
1917 &cvx, &cvy, &cvw, &cvh);
1919 EINA_LIST_FOREACH(itb->items, l, it)
1921 if ((GL_IT(it)->wsd->reorder_it == it) && it->highlighted) continue;
1925 it->item->w = itb->w;
1926 it->item->scrl_x = itb->x + it->x - GL_IT(it)->wsd->pan_x + ox;
1927 it->item->scrl_y = itb->y + it->y - GL_IT(it)->wsd->pan_y + oy;
1929 vis = (ELM_RECTS_INTERSECT
1930 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
1931 cvx, cvy, cvw, cvh));
1934 if ((itb->realized) && (!it->realized))
1936 if (vis) _item_realize(it, in, EINA_FALSE);
1940 if (vis || it->dragging)
1942 #if GENLIST_ENTRY_SUPPORT
1943 evas_object_show(VIEW(it));
1945 if (GL_IT(it)->wsd->reorder_mode &&
1946 GL_IT(it)->wsd->reorder_it &&
1947 GL_IT(it)->wsd->reorder_it->highlighted)
1948 y += _reorder_item_space_get(it);
1949 git = it->item->group_item;
1952 if (git->item->scrl_y < oy)
1953 git->item->scrl_y = oy;
1954 if ((git->item->scrl_y + git->item->h) >
1955 (it->item->scrl_y + it->item->h))
1956 git->item->scrl_y = (it->item->scrl_y +
1957 it->item->h) - git->item->h;
1958 git->item->scrl_x = it->item->scrl_x;
1959 git->item->want_realize = EINA_TRUE;
1961 if ((GL_IT(it)->wsd->reorder_it) &&
1962 GL_IT(it)->wsd->reorder_it->highlighted &&
1963 (it->item->old_scrl_y != it->item->scrl_y))
1965 if (!it->item->move_effect_enabled)
1967 it->item->move_effect_enabled = EINA_TRUE;
1968 GL_IT(it)->wsd->reorder_move_animator =
1970 _reorder_move_animator_cb, it);
1973 if (!it->item->move_effect_enabled)
1975 if ((GL_IT(it)->wsd->decorate_all_mode) &&
1976 (it->itc->decorate_all_item_style))
1977 _decorate_all_item_position
1978 (it, it->item->scrl_x, it->item->scrl_y);
1981 if (it->item->deco_it_view)
1983 (it, it->item->deco_it_view,
1988 (it, VIEW(it), it->item->scrl_x,
1991 it->item->old_scrl_y = it->item->scrl_y;
1992 #if GENLIST_PINCH_ZOOM_SUPPORT
1993 if (((GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
1994 && (!IS_ROOT_PARENT_IT(it))) || (GL_IT(it)->wsd->sorting))
1996 if (it->deco_all_view) evas_object_hide(it->deco_all_view);
1997 else evas_object_hide(VIEW(it));
2005 if ((GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
2006 && (!IS_ROOT_PARENT_IT(it)))
2008 if (it->deco_all_view) evas_object_hide(it->deco_all_view);
2009 else evas_object_hide(VIEW(it));
2012 _item_unrealize(it, EINA_FALSE);
2019 if (vis) it->item->want_realize = EINA_TRUE;
2023 // FIXME: diffrence from upstream
2024 minh += it->item->minh;
2028 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
2029 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(itb->sd)->obj));
2033 _item_block_realize(Item_Block *itb)
2035 if (itb->realized) return;
2037 itb->realized = EINA_TRUE;
2038 itb->want_unrealize = EINA_FALSE;
2042 _changed_job(Elm_Genlist_Smart_Data *sd)
2048 Eina_Bool anything_changed = EINA_FALSE;
2049 Eina_Bool width_changed = EINA_FALSE;
2050 Eina_Bool height_changed = EINA_FALSE;
2052 EINA_INLIST_FOREACH(sd->blocks, itb)
2057 width_changed = height_changed = EINA_FALSE;
2058 EINA_LIST_FOREACH(itb->items, l2, it)
2062 Evas_Coord mw = 0, mh = 0;
2064 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2065 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2066 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
2067 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
2068 (mw < GL_IT(it)->wsd->prev_viewport_w))
2069 mw = GL_IT(it)->wsd->prev_viewport_w;
2070 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
2071 if ((GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS) &&
2072 (GL_IT(it)->wsd->prev_viewport_w != 0) &&
2073 (mw > GL_IT(it)->wsd->prev_viewport_w))
2074 mw = GL_IT(it)->wsd->prev_viewport_w;
2076 if (it->item->minw != mw)
2078 it->item->w = it->item->minw = mw;
2079 width_changed = EINA_TRUE;
2081 if (it->item->minh != mh)
2083 it->item->h = it->item->minh = mh;
2084 height_changed = EINA_TRUE;
2091 if ((!sd->group_item_width) && (it->group))
2093 sd->group_item_width = mw;
2094 sd->group_item_height = mh;
2096 else if ((!sd->item_width) &&
2097 (it->item->type == ELM_GENLIST_ITEM_NONE))
2099 sd->item_width = mw;
2100 sd->item_height = mh;
2107 anything_changed = EINA_TRUE;
2108 itb->changed = EINA_TRUE;
2109 _item_block_recalc(itb, num0, 0);
2110 _item_block_position(itb, num0);
2112 else if (width_changed)
2114 _item_block_position(itb, num0);
2117 if (anything_changed)
2119 if (sd->calc_job) ecore_job_del(sd->calc_job);
2120 sd->calc_job = ecore_job_add(_calc_job, sd);
2125 _elm_genlist_pan_smart_calculate(Evas_Object *obj)
2127 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2128 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
2134 ELM_GENLIST_PAN_DATA_GET(obj, psd);
2136 //evas_event_freeze(evas_object_evas_get(obj));
2138 #if GENLIST_FX_SUPPORT
2139 if (psd->wsd->fx_playing) return;
2141 if (psd->wsd->pan_changed)
2143 _calc_job(psd->wsd);
2144 psd->wsd->pan_changed = EINA_FALSE;
2147 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2148 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2149 EINA_LIST_FOREACH(psd->wsd->group_items, l, git)
2151 #if GROUP_ITEMS_FEATURE
2152 git->item->want_realize = EINA_FALSE;
2154 evas_object_hide(VIEW(git));
2158 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
2160 itb->w = psd->wsd->minw;
2161 if (ELM_RECTS_INTERSECT(itb->x - psd->wsd->pan_x + ox,
2162 itb->y - psd->wsd->pan_y + oy,
2164 cvx, cvy, cvw, cvh))
2166 if ((!itb->realized) || (itb->changed))
2168 _item_block_realize(itb);
2170 // FIXME: difference from opensource
2171 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2172 sd->wd->calc_job = NULL;
2176 _item_block_position(itb, in);
2180 if (itb->realized) _item_block_unrealize(itb);
2184 #if GENLIST_PINCH_ZOOM_SUPPORT
2185 if (psd->wsd->pinch_zoom_mode) _pinch_items_recalc(psd->wsd);
2188 #if GROUP_ITEMS_FEATURE
2189 if ((!psd->wsd->reorder_it) || (psd->wsd->reorder_pan_move))
2190 _group_items_recalc(psd->wsd);
2192 if ((psd->wsd->reorder_mode) && (psd->wsd->reorder_it))
2194 if (psd->wsd->pan_y != psd->wsd->reorder_old_pan_y)
2195 psd->wsd->reorder_pan_move = EINA_TRUE;
2196 else psd->wsd->reorder_pan_move = EINA_FALSE;
2198 evas_object_raise(psd->wsd->VIEW(reorder_it));
2199 psd->wsd->reorder_old_pan_y = psd->wsd->pan_y;
2200 psd->wsd->start_time = ecore_loop_time_get();
2202 _item_auto_scroll(psd->wsd);
2204 psd->wsd->s_iface->content_pos_get(ELM_WIDGET_DATA(psd->wsd)->obj, &vx, &vy);
2205 psd->wsd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(psd->wsd)->obj,
2208 if (psd->wsd->reorder_fast == 1)
2209 psd->wsd->s_iface->content_region_show(ELM_WIDGET_DATA(psd->wsd)->obj,
2210 vx,vy - 10, vw, vh);
2211 else if (psd->wsd->reorder_fast == -1)
2212 psd->wsd->s_iface->content_region_show(ELM_WIDGET_DATA(psd->wsd)->obj,
2213 vx, vy + 10, vw, vh);
2215 if (psd->wsd->size_changed)
2217 _changed_job(psd->wsd);
2218 psd->wsd->size_changed = EINA_FALSE;
2221 #if GENLIST_FX_SUPPORT
2222 psd->wsd->rendered = EINA_TRUE;
2223 if ((psd->wsd->fx_mode) && (!psd->wsd->queue))
2225 if (_elm_genlist_fx_capture(ELM_WIDGET_DATA(psd->wsd)->obj, 1))
2226 _elm_genlist_fx_play(ELM_WIDGET_DATA(psd->wsd)->obj);
2229 #if GENLIST_PINCH_ZOOM_SUPPORT
2230 if (psd->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND)
2231 psd->wsd->pinch_zoom_mode = ELM_GEN_PINCH_ZOOM_NONE;
2233 //evas_event_thaw(evas_object_evas_get(obj));
2234 //evas_event_thaw_eval(evas_object_evas_get(obj));
2238 _elm_genlist_pan_smart_set_user(Elm_Genlist_Pan_Smart_Class *sc)
2240 ELM_PAN_CLASS(sc)->base.add = _elm_genlist_pan_smart_add;
2241 ELM_PAN_CLASS(sc)->base.del = _elm_genlist_pan_smart_del;
2242 ELM_PAN_CLASS(sc)->base.move = _elm_genlist_pan_smart_move;
2243 ELM_PAN_CLASS(sc)->base.resize = _elm_genlist_pan_smart_resize;
2244 ELM_PAN_CLASS(sc)->base.calculate = _elm_genlist_pan_smart_calculate;
2246 ELM_PAN_CLASS(sc)->pos_set = _elm_genlist_pan_smart_pos_set;
2247 ELM_PAN_CLASS(sc)->pos_get = _elm_genlist_pan_smart_pos_get;
2248 ELM_PAN_CLASS(sc)->pos_max_get = _elm_genlist_pan_smart_pos_max_get;
2249 ELM_PAN_CLASS(sc)->pos_min_get = _elm_genlist_pan_smart_pos_min_get;
2250 ELM_PAN_CLASS(sc)->content_size_get =
2251 _elm_genlist_pan_smart_content_size_get;
2255 _item_multi_select_up(Elm_Genlist_Smart_Data *sd)
2257 Elm_Object_Item *prev;
2259 if (!sd->selected) return EINA_FALSE;
2260 if (!sd->multi) return EINA_FALSE;
2262 prev = elm_genlist_item_prev_get(sd->last_selected_item);
2263 if (!prev) return EINA_TRUE;
2265 if (elm_genlist_item_selected_get(prev))
2267 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2268 sd->last_selected_item = prev;
2269 elm_genlist_item_show
2270 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2274 elm_genlist_item_selected_set(prev, EINA_TRUE);
2275 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2281 _item_multi_select_down(Elm_Genlist_Smart_Data *sd)
2283 Elm_Object_Item *next;
2285 if (!sd->selected) return EINA_FALSE;
2286 if (!sd->multi) return EINA_FALSE;
2288 next = elm_genlist_item_next_get(sd->last_selected_item);
2289 if (!next) return EINA_TRUE;
2291 if (elm_genlist_item_selected_get(next))
2293 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2294 sd->last_selected_item = next;
2295 elm_genlist_item_show
2296 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2300 elm_genlist_item_selected_set(next, EINA_TRUE);
2301 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2308 _all_items_deselect(Elm_Genlist_Smart_Data *sd)
2310 if (!sd->selected) return EINA_FALSE;
2312 while (sd->selected)
2313 elm_genlist_item_selected_set(sd->selected->data, EINA_FALSE);
2319 _item_single_select_up(Elm_Genlist_Smart_Data *sd)
2325 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2327 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2330 prev = (Elm_Gen_Item *)elm_genlist_item_prev_get
2331 (sd->last_selected_item);
2333 if (!prev) return EINA_FALSE;
2335 _all_items_deselect(sd);
2337 elm_genlist_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
2338 elm_genlist_item_show((Elm_Object_Item *)prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2343 _item_single_select_down(Elm_Genlist_Smart_Data *sd)
2349 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2351 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2354 next = (Elm_Gen_Item *)elm_genlist_item_next_get
2355 (sd->last_selected_item);
2357 if (!next) return EINA_FALSE;
2359 _all_items_deselect(sd);
2361 elm_genlist_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
2362 elm_genlist_item_show
2363 ((Elm_Object_Item *)next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2369 _elm_genlist_smart_event(Evas_Object *obj,
2370 Evas_Object *src __UNUSED__,
2371 Evas_Callback_Type type,
2378 Evas_Coord step_x = 0;
2379 Evas_Coord step_y = 0;
2380 Evas_Coord page_x = 0;
2381 Evas_Coord page_y = 0;
2382 Elm_Object_Item *it;
2383 Evas_Event_Key_Down *ev = event_info;
2384 Evas_Coord pan_max_x = 0, pan_max_y = 0;
2386 ELM_GENLIST_DATA_GET(obj, sd);
2388 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2389 if (!sd->items) return EINA_FALSE;
2390 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
2391 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
2393 sd->s_iface->content_pos_get(obj, &x, &y);
2394 sd->s_iface->step_size_get(obj, &step_x, &step_y);
2395 sd->s_iface->page_size_get(obj, &page_x, &page_y);
2396 sd->s_iface->content_viewport_size_get(obj, &v_w, &v_h);
2398 if ((!strcmp(ev->keyname, "Left")) ||
2399 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
2403 else if ((!strcmp(ev->keyname, "Right")) ||
2404 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
2408 else if ((!strcmp(ev->keyname, "Up")) ||
2409 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
2411 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
2412 (_item_multi_select_up(sd)))
2413 || (_item_single_select_up(sd)))
2415 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2421 else if ((!strcmp(ev->keyname, "Down")) ||
2422 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
2424 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
2425 (_item_multi_select_down(sd)))
2426 || (_item_single_select_down(sd)))
2428 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2434 else if ((!strcmp(ev->keyname, "Home")) ||
2435 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
2437 it = elm_genlist_first_item_get(obj);
2438 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
2439 elm_genlist_item_selected_set(it, EINA_TRUE);
2440 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2443 else if ((!strcmp(ev->keyname, "End")) ||
2444 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
2446 it = elm_genlist_last_item_get(obj);
2447 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
2448 elm_genlist_item_selected_set(it, EINA_TRUE);
2449 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2452 else if ((!strcmp(ev->keyname, "Prior")) ||
2453 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
2456 y -= -(page_y * v_h) / 100;
2460 else if ((!strcmp(ev->keyname, "Next")) ||
2461 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
2464 y += -(page_y * v_h) / 100;
2468 else if (!strcmp(ev->keyname, "Escape"))
2470 if (!_all_items_deselect(sd)) return EINA_FALSE;
2471 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2474 else if (((!strcmp(ev->keyname, "Return")) ||
2475 (!strcmp(ev->keyname, "KP_Enter")) ||
2476 (!strcmp(ev->keyname, "space")))
2477 && (!sd->multi) && (sd->selected))
2479 it = elm_genlist_selected_item_get(obj);
2480 elm_genlist_item_expanded_set(it, !elm_genlist_item_expanded_get(it));
2481 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
2483 else return EINA_FALSE;
2485 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2486 _elm_genlist_pan_smart_pos_max_get(sd->pan_obj, &pan_max_x, &pan_max_y);
2488 if (x > pan_max_x) x = pan_max_x;
2490 if (y > pan_max_y) y = pan_max_y;
2492 sd->s_iface->content_pos_set(obj, x, y, EINA_TRUE);
2498 _elm_genlist_smart_sub_object_add(Evas_Object *obj,
2501 Elm_Widget_Smart_Class *parent_parent;
2503 parent_parent = (Elm_Widget_Smart_Class *)((Evas_Smart_Class *)
2504 _elm_genlist_parent_sc)->parent;
2506 /* skipping layout's code, which registers size hint changing
2507 * callback on sub objects. this is here because items'
2508 * content_get() routines may change hints on the objects after
2509 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
2510 * not needed at here anyway, so let's skip listening to those
2512 if (!parent_parent->sub_object_add(obj, sobj))
2519 _elm_genlist_smart_sub_object_del(Evas_Object *obj,
2522 ELM_GENLIST_DATA_GET(obj, sd);
2524 /* XXX: hack -- also skipping sizing recalculation on
2525 * sub-object-del. genlist's crazy code paths (like groups and
2526 * such) seem to issue a whole lot of deletions and Evas bitches
2527 * about too many recalculations */
2528 sd->on_sub_del = EINA_TRUE;
2530 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->sub_object_del(obj, sobj))
2533 sd->on_sub_del = EINA_FALSE;
2539 _elm_genlist_smart_on_focus(Evas_Object *obj)
2541 ELM_GENLIST_DATA_GET(obj, sd);
2543 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->on_focus(obj))
2546 if (elm_widget_focus_get(obj) && (sd->items) && (sd->selected) &&
2547 (!sd->last_selected_item))
2548 sd->last_selected_item = eina_list_data_get(sd->selected);
2554 _elm_genlist_smart_focus_next(const Evas_Object *obj,
2555 Elm_Focus_Direction dir,
2558 Evas_Coord x, y, w, h;
2559 Evas_Coord sx, sy, sw, sh;
2561 Eina_List *items = NULL;
2562 Eina_Bool done = EINA_FALSE;
2564 ELM_GENLIST_CHECK(obj) EINA_FALSE;
2565 ELM_GENLIST_DATA_GET(obj, sd);
2567 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
2569 EINA_INLIST_FOREACH(sd->blocks, itb)
2577 EINA_LIST_FOREACH(itb->items, l, it)
2581 evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
2582 items = eina_list_append(items, it->base.access_obj);
2584 if (!it->base.access_order) continue;
2588 EINA_LIST_FOREACH(it->base.access_order, subl, subo)
2589 items = eina_list_append(items, subo);
2593 else if (done) break;
2596 return elm_widget_focus_list_next_get
2597 (obj, items, eina_list_data_get, dir, next);
2601 _mirrored_set(Evas_Object *obj,
2604 ELM_GENLIST_DATA_GET(obj, sd);
2606 sd->s_iface->mirrored_set(obj, rtl);
2610 _elm_genlist_smart_theme(Evas_Object *obj)
2614 ELM_GENLIST_DATA_GET(obj, sd);
2616 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->theme(obj))
2619 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2620 _item_cache_all_free(sd);
2621 _mirrored_set(obj, elm_widget_mirrored_get(obj));
2624 // FIXME: difference from opensource
2625 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
2628 sd->item_width = sd->item_height = 0;
2629 sd->group_item_width = sd->group_item_height = 0;
2630 sd->minw = sd->minh = sd->realminw = 0;
2631 EINA_INLIST_FOREACH(sd->blocks, itb)
2636 if (itb->realized) _item_block_unrealize(itb);
2637 EINA_LIST_FOREACH(itb->items, l, it)
2638 it->item->mincalcd = EINA_FALSE;
2640 itb->changed = EINA_TRUE;
2642 if (sd->calc_job) ecore_job_del(sd->calc_job);
2643 sd->calc_job = NULL;
2644 elm_layout_sizing_eval(obj);
2645 sd->pan_changed = EINA_TRUE;
2646 evas_object_smart_changed(sd->pan_obj);
2647 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2648 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2653 /* FIXME: take off later. maybe this show region coords belong in the
2654 * interface (new api functions, set/get)? */
2656 _show_region_hook(void *data,
2659 Evas_Coord x, y, w, h;
2661 ELM_GENLIST_DATA_GET(data, sd);
2663 elm_widget_show_region_get(obj, &x, &y, &w, &h);
2664 //x & y are screen coordinates, Add with pan coordinates
2667 sd->s_iface->content_region_show(obj, x, y, w, h);
2671 _elm_genlist_smart_translate(Evas_Object *obj)
2673 evas_object_smart_callback_call(obj, "language,changed", NULL);
2679 _item_highlight(Elm_Gen_Item *it)
2681 const char *selectraise;
2682 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2684 if (elm_widget_item_disabled_get(it)) return;
2685 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2686 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2687 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2688 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2691 if (!sd->highlight || it->highlighted) return;
2692 #if GENLIST_PINCH_ZOOM_SUPPORT
2693 if (sd->pinch_zoom_mode) return;
2696 selectraise = edje_object_data_get(VIEW(it), "selectraise");
2697 if ((selectraise) && (!strcmp(selectraise, "on")))
2699 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2700 else evas_object_raise(VIEW(it));
2701 if ((it->item->group_item) && (it->item->group_item->realized))
2702 evas_object_raise(it->item->VIEW(group_item));
2704 it->highlighted = EINA_TRUE;
2706 if (it->deco_all_view)
2707 edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
2708 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
2709 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
2713 _item_unhighlight(Elm_Gen_Item *it)
2715 if (!it->highlighted) return;
2717 if (!it->item->nostacking)
2719 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
2721 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
2722 else evas_object_lower(VIEW(it));
2726 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2727 else evas_object_raise(VIEW(it));
2730 it->highlighted = EINA_FALSE;
2732 if (it->deco_all_view)
2733 edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
2734 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
2735 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it);
2739 _item_unselect(Elm_Gen_Item *it)
2741 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2742 _item_unhighlight(it);
2743 if (!it->selected) return;
2745 it->selected = EINA_FALSE;
2746 sd->selected = eina_list_remove(sd->selected, it);
2747 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
2751 _item_select(Elm_Gen_Item *it)
2753 Evas_Object *obj = WIDGET(it);
2754 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2755 if (elm_widget_item_disabled_get(it)) return;
2756 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2757 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
2758 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2759 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
2762 #if GENLIST_PINCH_ZOOM_SUPPORT
2763 if (IS_ROOT_PARENT_IT(it) && (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
2765 elm_genlist_pinch_zoom_mode_set(obj, ELM_GEN_PINCH_ZOOM_EXPAND);
2766 elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
2772 // FIXME: difference from upstream
2773 if ((GL_IT(it)->wsd->last_selected_item) &&
2774 (it != (Elm_Gen_Item *) GL_IT(it)->wsd->last_selected_item))
2775 _item_unfocusable_set
2776 ((Elm_Gen_Item *)GL_IT(it)->wsd->last_selected_item, EINA_TRUE);
2779 // Do not check selected because always select mode can be used
2780 _item_highlight(it);
2781 it->selected = EINA_TRUE;
2782 sd->selected = eina_list_append(sd->selected, it);
2783 sd->last_selected_item = (Elm_Object_Item *)it;
2785 if (it->func.func) it->func.func((void *)it->func.data, obj, it);
2786 if (!EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC))
2788 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
2792 _item_select_unselect(Elm_Gen_Item *it, Eina_Bool selected)
2794 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2795 Evas_Object *obj = ELM_WIDGET_DATA(sd)->obj;
2796 if (elm_widget_item_disabled_get(it)) return;
2798 evas_object_ref(obj);
2801 const Eina_List *l, *ll;
2803 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
2804 if (it2 != it) _item_unselect(it2);
2806 if (selected) _item_select(it);
2807 else _item_unselect(it);
2808 evas_object_unref(obj);
2812 _item_block_position_update(Eina_Inlist *list,
2817 EINA_INLIST_FOREACH(list, tmp)
2819 tmp->position = idx++;
2820 tmp->position_update = EINA_TRUE;
2825 _item_position_update(Eina_List *list,
2831 EINA_LIST_FOREACH(list, l, it)
2833 it->position = idx++;
2834 it->position_update = EINA_TRUE;
2839 _item_block_merge(Item_Block *left,
2845 EINA_LIST_FOREACH(right->items, l, it2)
2847 it2->item->block = left;
2849 left->changed = EINA_TRUE;
2851 left->items = eina_list_merge(left->items, right->items);
2855 _item_block_del(Elm_Gen_Item *it)
2858 Item_Block *itb = it->item->block;
2859 Eina_Bool block_changed = EINA_FALSE;
2861 itb->items = eina_list_remove(itb->items, it);
2863 itb->changed = EINA_TRUE;
2864 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
2865 GL_IT(it)->wsd->calc_job = ecore_job_add(_calc_job, GL_IT(it)->wsd);
2870 il = EINA_INLIST_GET(itb);
2871 itbn = (Item_Block *)(il->next);
2873 it->parent->item->items =
2874 eina_list_remove(it->parent->item->items, it);
2877 _item_block_position_update(il->next, itb->position);
2879 GL_IT(it)->wsd->blocks =
2880 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
2883 if (itbn) itbn->changed = EINA_TRUE;
2887 if (itb->count < (itb->sd->max_items_per_block / 2))
2892 il = EINA_INLIST_GET(itb);
2893 itbp = (Item_Block *)(il->prev);
2894 itbn = (Item_Block *)(il->next);
2896 /* merge block with previous */
2898 ((itbp->count + itb->count) <
2899 (itb->sd->max_items_per_block +
2900 (itb->sd->max_items_per_block / 2))))
2902 _item_block_merge(itbp, itb);
2903 _item_block_position_update
2904 (EINA_INLIST_GET(itb)->next, itb->position);
2905 GL_IT(it)->wsd->blocks = eina_inlist_remove
2906 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
2908 block_changed = EINA_TRUE;
2910 /* merge block with next */
2912 ((itbn->count + itb->count) <
2913 (itb->sd->max_items_per_block +
2914 (itb->sd->max_items_per_block / 2))))
2916 _item_block_merge(itb, itbn);
2917 _item_block_position_update
2918 (EINA_INLIST_GET(itbn)->next, itbn->position);
2919 GL_IT(it)->wsd->blocks =
2920 eina_inlist_remove(GL_IT(it)->wsd->blocks,
2921 EINA_INLIST_GET(itbn));
2923 block_changed = EINA_TRUE;
2930 GL_IT(it)->wsd->pan_changed = EINA_TRUE;
2931 evas_object_smart_changed(GL_IT(it)->wsd->pan_obj);
2932 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
2933 GL_IT(it)->wsd->calc_job = NULL;
2935 #if GENLIST_FX_SUPPORT
2936 it->item->block = NULL;
2941 _decorate_all_item_unrealize(Elm_Gen_Item *it)
2945 if ((!it) || (!it->item->decorate_all_item_realized)) return;
2947 #if GENLIST_FX_SUPPORT
2948 if ((GL_IT(it)->has_proxy_it) && (!GL_IT(it)->wsd->genlist_clearing))
2950 if (!eina_list_data_find(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it))
2951 GL_IT(it)->wsd->pending_unrealized_decorate_all_items =
2952 eina_list_append(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it);
2957 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
2958 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
2959 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2960 _elm_genlist_item_odd_even_update(it);
2961 _elm_genlist_item_state_update(it);
2963 edje_object_signal_emit
2964 (it->deco_all_view, "elm,state,decorate,disabled", "elm");
2965 edje_object_signal_emit
2966 (VIEW(it), "elm,state,decorate,disabled", "elm");
2967 edje_object_signal_emit
2968 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
2969 edje_object_message_signal_process(VIEW(it));
2970 edje_object_message_signal_process(it->deco_all_view);
2972 evas_object_del(it->deco_all_view);
2973 it->deco_all_view = NULL;
2974 elm_widget_stringlist_free(it->item->deco_all_texts);
2975 it->item->deco_all_texts = NULL;
2976 elm_widget_stringlist_free(it->item->deco_all_contents);
2977 it->item->deco_all_contents = NULL;
2978 elm_widget_stringlist_free(it->item->deco_all_states);
2979 it->item->deco_all_states = NULL;
2980 EINA_LIST_FREE (it->item->deco_all_content_objs, icon)
2981 evas_object_del(icon);
2983 _item_mouse_callbacks_del(it, it->deco_all_view);
2984 _item_mouse_callbacks_add(it, VIEW(it));
2986 it->item->decorate_all_item_realized = EINA_FALSE;
2990 _item_free_common(Elm_Gen_Item *it)
2992 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2993 elm_widget_item_pre_notify_del(it);
2994 if (it->itc->func.del)
2995 it->itc->func.del((void *)it->base.data, WIDGET(it));
2996 if (it->tooltip.del_cb)
2997 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
2998 if (it->item->block) _item_block_del(it);
3000 it->parent->item->items =
3001 eina_list_remove(it->parent->item->items, it);
3002 if (it->item->queued) sd->queue = eina_list_remove(sd->queue, it);
3003 if (it->group) sd->group_items = eina_list_remove(sd->group_items, it);
3005 // FIXME: relative will be better to be fixed. it is too harsh.
3007 it->item->rel->item->rel_revs =
3008 eina_list_remove(it->item->rel->item->rel_revs, it);
3009 if (it->item->rel_revs)
3012 EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
3014 _item_sub_items_clear(it);
3016 #if GENLIST_ENTRY_SUPPORT
3017 it->item->unrealize_disabled = EINA_FALSE;
3020 if (it->selected) sd->selected = eina_list_remove(sd->selected, it);
3021 if (sd->show_item == it) sd->show_item = NULL;
3022 if (sd->anchor_item == it)
3025 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3026 if (!sd->anchor_item) sd->anchor_item =
3027 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3029 if (sd->expanded_item == it) sd->expanded_item = NULL;
3030 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3031 if (sd->state) eina_inlist_sorted_state_free(sd->state);
3033 if (sd->last_selected_item == (Elm_Object_Item *)it)
3034 sd->last_selected_item = NULL;
3038 ecore_timer_del(it->long_timer);
3039 it->long_timer = NULL;
3041 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
3043 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3048 _item_mouse_move_cb(void *data,
3049 Evas *evas __UNUSED__,
3053 EINA_SAFETY_ON_NULL_RETURN(data);
3054 Elm_Gen_Item *it = data;
3055 Elm_Genlist_Smart_Data *sd;
3056 Evas_Event_Mouse_Move *ev = event_info;
3057 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
3058 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
3060 sd = GL_IT(it)->wsd;
3062 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3064 if (!sd->on_hold) _item_unselect(it);
3065 sd->on_hold = EINA_TRUE;
3067 if (sd->multi_touched)
3069 sd->cur_x = ev->cur.canvas.x;
3070 sd->cur_y = ev->cur.canvas.y;
3073 if ((it->dragging) && (it->down))
3075 if (sd->movements == SWIPE_MOVES)
3076 sd->swipe = EINA_TRUE;
3079 sd->history[sd->movements].x = ev->cur.canvas.x;
3080 sd->history[sd->movements].y = ev->cur.canvas.y;
3081 if (abs((sd->history[sd->movements].x -
3082 sd->history[0].x)) > 40)
3083 sd->swipe = EINA_TRUE;
3089 ecore_timer_del(it->long_timer);
3090 it->long_timer = NULL;
3092 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
3095 if ((!it->down) || (sd->longpressed))
3099 ecore_timer_del(it->long_timer);
3100 it->long_timer = NULL;
3102 if ((sd->reorder_mode) && (sd->reorder_it))
3104 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3106 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
3107 sd->reorder_fast = 1;
3108 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
3109 sd->reorder_fast = -1;
3110 else sd->reorder_fast = 0;
3112 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
3114 if (!sd->reorder_start_y)
3115 sd->reorder_start_y = it->item->block->y + it->y;
3119 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
3120 y_pos = oy + oh - sd->reorder_it->item->h;
3124 if (it->deco_all_view)
3125 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
3126 else if (it->item->deco_it_view)
3128 (it, it->item->deco_it_view, it->item->scrl_x, y_pos);
3130 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
3132 if (sd->calc_job) ecore_job_del(sd->calc_job);
3133 sd->calc_job = ecore_job_add(_calc_job, sd);
3137 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3138 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3140 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3141 x = ev->cur.canvas.x - x;
3142 y = ev->cur.canvas.y - y;
3145 if (adx < 0) adx = -dx;
3149 if (ady < 0) ady = -dy;
3153 if ((adx > minw) || (ady > minh))
3155 it->dragging = EINA_TRUE;
3158 ecore_timer_del(it->long_timer);
3159 it->long_timer = NULL;
3164 evas_object_smart_callback_call
3165 (WIDGET(it), SIG_DRAG_START_UP, it);
3169 evas_object_smart_callback_call
3170 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3172 evas_object_smart_callback_call
3173 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3179 evas_object_smart_callback_call
3180 (WIDGET(it), SIG_DRAG_START_DOWN, it);
3184 evas_object_smart_callback_call
3185 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3187 evas_object_smart_callback_call
3188 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3195 _long_press_cb(void *data)
3197 Elm_Gen_Item *it = data, *it2;
3198 Elm_Genlist_Smart_Data *sd;
3201 sd = GL_IT(it)->wsd;
3203 it->long_timer = NULL;
3204 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
3205 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3206 return ECORE_CALLBACK_CANCEL;
3208 GL_IT(it)->wsd->longpressed = EINA_TRUE;
3209 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
3210 if ((GL_IT(it)->wsd->reorder_mode) && (!it->group))
3212 GL_IT(it)->wsd->reorder_it = it;
3213 GL_IT(it)->wsd->reorder_start_y = 0;
3214 if (it->deco_all_view)
3215 evas_object_raise(it->deco_all_view);
3217 evas_object_raise(VIEW(it));
3219 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
3220 sd->s_iface->bounce_allow_set
3221 (ELM_WIDGET_DATA(sd)->obj, EINA_FALSE, EINA_FALSE);
3223 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
3225 if (it != it2) _item_unselect(it2);
3228 // FIXME: difference from opensource
3229 if (it->item->items)
3231 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
3233 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
3235 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
3237 return ECORE_CALLBACK_RENEW;
3242 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
3244 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
3245 return ECORE_CALLBACK_RENEW;
3248 if (!GL_IT(it)->wsd->decorate_all_mode)
3249 edje_object_signal_emit
3250 (VIEW(it), "elm,state,reorder,enabled", "elm");
3253 return ECORE_CALLBACK_CANCEL;
3257 _swipe_do(Elm_Gen_Item *it)
3262 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3263 elm_widget_item_disabled_get(it)) return;
3265 GL_IT(it)->wsd->swipe = EINA_FALSE;
3266 for (i = 0; i < GL_IT(it)->wsd->movements; i++)
3268 sum += GL_IT(it)->wsd->history[i].x;
3269 if (abs(GL_IT(it)->wsd->history[0].y -
3270 GL_IT(it)->wsd->history[i].y) > 10) return;
3273 sum /= GL_IT(it)->wsd->movements;
3274 if (abs(sum - GL_IT(it)->wsd->history[0].x) <= 10) return;
3275 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
3279 _swipe_cancel(void *data)
3281 Elm_Gen_Item *it = data;
3283 if (!it) return ECORE_CALLBACK_CANCEL;
3284 GL_IT(it)->wsd->swipe = EINA_FALSE;
3285 GL_IT(it)->wsd->movements = 0;
3287 return ECORE_CALLBACK_RENEW;
3291 _multi_cancel(void *data)
3293 Elm_Genlist_Smart_Data *sd = data;
3295 if (!sd) return ECORE_CALLBACK_CANCEL;
3296 sd->multi_timeout = EINA_TRUE;
3298 return ECORE_CALLBACK_RENEW;
3302 _multi_touch_gesture_eval(void *data)
3304 Elm_Gen_Item *it = data;
3305 Evas_Coord minw = 0, minh = 0;
3306 Evas_Coord off_x, off_y, off_mx, off_my;
3308 GL_IT(it)->wsd->multi_touched = EINA_FALSE;
3309 if (GL_IT(it)->wsd->multi_timer)
3311 ecore_timer_del(GL_IT(it)->wsd->multi_timer);
3312 GL_IT(it)->wsd->multi_timer = NULL;
3314 if (GL_IT(it)->wsd->multi_timeout)
3316 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3320 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3321 off_x = abs(GL_IT(it)->wsd->cur_x - GL_IT(it)->wsd->prev_x);
3322 off_y = abs(GL_IT(it)->wsd->cur_y - GL_IT(it)->wsd->prev_y);
3323 off_mx = abs(GL_IT(it)->wsd->cur_mx - GL_IT(it)->wsd->prev_mx);
3324 off_my = abs(GL_IT(it)->wsd->cur_my - GL_IT(it)->wsd->prev_my);
3326 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
3327 || (off_my > minh)))
3329 if ((off_x + off_mx) > (off_y + off_my))
3331 if ((GL_IT(it)->wsd->cur_x > GL_IT(it)->wsd->prev_x)
3332 && (GL_IT(it)->wsd->cur_mx > GL_IT(it)->wsd->prev_mx))
3333 evas_object_smart_callback_call
3334 (WIDGET(it), SIG_MULTI_SWIPE_RIGHT, it);
3335 else if ((GL_IT(it)->wsd->cur_x < GL_IT(it)->wsd->prev_x)
3336 && (GL_IT(it)->wsd->cur_mx < GL_IT(it)->wsd->prev_mx))
3337 evas_object_smart_callback_call
3338 (WIDGET(it), SIG_MULTI_SWIPE_LEFT, it);
3339 else if (abs(GL_IT(it)->wsd->cur_x - GL_IT(it)->wsd->cur_mx) >
3340 abs(GL_IT(it)->wsd->prev_x - GL_IT(it)->wsd->prev_mx))
3341 evas_object_smart_callback_call
3342 (WIDGET(it), SIG_MULTI_PINCH_OUT, it);
3344 evas_object_smart_callback_call
3345 (WIDGET(it), SIG_MULTI_PINCH_IN, it);
3349 if ((GL_IT(it)->wsd->cur_y > GL_IT(it)->wsd->prev_y)
3350 && (GL_IT(it)->wsd->cur_my > GL_IT(it)->wsd->prev_my))
3351 evas_object_smart_callback_call
3352 (WIDGET(it), SIG_MULTI_SWIPE_DOWN, it);
3353 else if ((GL_IT(it)->wsd->cur_y < GL_IT(it)->wsd->prev_y)
3354 && (GL_IT(it)->wsd->cur_my < GL_IT(it)->wsd->prev_my))
3355 evas_object_smart_callback_call
3356 (WIDGET(it), SIG_MULTI_SWIPE_UP, it);
3357 else if (abs(GL_IT(it)->wsd->cur_y - GL_IT(it)->wsd->cur_my) >
3358 abs(GL_IT(it)->wsd->prev_y - GL_IT(it)->wsd->prev_my))
3360 evas_object_smart_callback_call
3361 (WIDGET(it), SIG_MULTI_PINCH_OUT, it);
3362 #if GENLIST_PINCH_ZOOM_SUPPORT
3363 if (IS_ROOT_PARENT_IT(it) && (GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
3365 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj, ELM_GEN_PINCH_ZOOM_EXPAND);
3366 elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
3372 evas_object_smart_callback_call
3373 (WIDGET(it), SIG_MULTI_PINCH_IN, it);
3374 #if GENLIST_PINCH_ZOOM_SUPPORT
3375 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj,
3376 ELM_GEN_PINCH_ZOOM_CONTRACT);
3382 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3386 _item_multi_down_cb(void *data,
3387 Evas *evas __UNUSED__,
3388 Evas_Object *obj __UNUSED__,
3391 Elm_Gen_Item *it = data;
3392 Evas_Event_Multi_Down *ev = event_info;
3394 if ((GL_IT(it)->wsd->multi_device != 0) || (GL_IT(it)->wsd->multi_touched)
3395 || (GL_IT(it)->wsd->multi_timeout))
3398 GL_IT(it)->wsd->multi_device = ev->device;
3399 GL_IT(it)->wsd->multi_down = EINA_TRUE;
3400 GL_IT(it)->wsd->multi_touched = EINA_TRUE;
3401 GL_IT(it)->wsd->prev_mx = ev->canvas.x;
3402 GL_IT(it)->wsd->prev_my = ev->canvas.y;
3405 ecore_timer_del(it->long_timer);
3406 it->long_timer = NULL;
3410 it->dragging = EINA_FALSE;
3411 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
3413 if (it->item->swipe_timer)
3415 ecore_timer_del(it->item->swipe_timer);
3416 it->item->swipe_timer = NULL;
3418 GL_IT(it)->wsd->longpressed = EINA_FALSE;
3419 if (GL_IT(it)->wsd->on_hold)
3421 GL_IT(it)->wsd->swipe = EINA_FALSE;
3422 GL_IT(it)->wsd->movements = 0;
3423 GL_IT(it)->wsd->on_hold = EINA_FALSE;
3428 _item_multi_up_cb(void *data,
3429 Evas *evas __UNUSED__,
3430 Evas_Object *obj __UNUSED__,
3433 Elm_Gen_Item *it = data;
3434 Evas_Event_Multi_Up *ev = event_info;
3436 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3437 GL_IT(it)->wsd->multi_device = 0;
3438 GL_IT(it)->wsd->multi_down = EINA_FALSE;
3439 if (GL_IT(it)->wsd->mouse_down) return;
3440 _multi_touch_gesture_eval(data);
3444 _item_multi_move_cb(void *data,
3445 Evas *evas __UNUSED__,
3446 Evas_Object *obj __UNUSED__,
3449 Elm_Gen_Item *it = data;
3450 Evas_Event_Multi_Move *ev = event_info;
3452 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3453 GL_IT(it)->wsd->cur_mx = ev->cur.canvas.x;
3454 GL_IT(it)->wsd->cur_my = ev->cur.canvas.y;
3458 // FIXME: difference from upstream
3460 _item_unfocusable_set(Elm_Gen_Item *it, Eina_Bool unfocus)
3463 Evas_Object *item_obj;
3464 Evas_Object *obj = WIDGET(it);
3468 EINA_LIST_FOREACH(it->content_objs, l, item_obj)
3470 if (unfocus) elm_widget_focused_object_clear(item_obj);
3471 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3473 EINA_LIST_FOREACH(it->item->flip_content_objs, l, item_obj)
3475 if (unfocus) elm_widget_focused_object_clear(item_obj);
3476 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3478 EINA_LIST_FOREACH(it->item->deco_all_content_objs, l, item_obj)
3480 if (unfocus) elm_widget_focused_object_clear(item_obj);
3481 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3483 it->can_focus = !unfocus;
3489 _item_mouse_down_cb(void *data,
3490 Evas *evas __UNUSED__,
3494 Evas_Event_Mouse_Down *ev = event_info;
3495 Elm_Gen_Item *it = data;
3496 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
3499 if (ev->button != 1) return;
3501 _item_unfocusable_set(it, EINA_FALSE);
3503 it->down = EINA_TRUE;
3504 it->dragging = EINA_FALSE;
3505 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3506 it->dx = ev->canvas.x - x;
3507 it->dy = ev->canvas.y - y;
3508 sd->mouse_down = EINA_TRUE;
3509 if (!sd->multi_touched)
3511 sd->prev_x = ev->canvas.x;
3512 sd->prev_y = ev->canvas.y;
3513 sd->multi_timeout = EINA_FALSE;
3514 if (sd->multi_timer) ecore_timer_del(sd->multi_timer);
3515 sd->multi_timer = ecore_timer_add(1, _multi_cancel, sd);
3517 sd->longpressed = EINA_FALSE;
3518 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3520 sd->on_hold = EINA_TRUE;
3523 else sd->on_hold = EINA_FALSE;
3524 _item_highlight(it);
3525 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
3526 if ((!elm_widget_item_disabled_get(it)) &&
3527 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3529 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
3530 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
3532 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
3533 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
3534 if (it->long_timer) ecore_timer_del(it->long_timer);
3536 it->long_timer = ecore_timer_add
3537 (sd->longpress_timeout, _long_press_cb, it);
3539 it->long_timer = NULL;
3540 sd->swipe = EINA_FALSE;
3545 _item_block_new(Elm_Genlist_Smart_Data *sd,
3550 itb = calloc(1, sizeof(Item_Block));
3551 if (!itb) return NULL;
3555 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
3556 _item_block_position_update(sd->blocks, 0);
3560 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3561 itb->position_update = EINA_TRUE;
3562 if (sd->blocks != EINA_INLIST_GET(itb))
3565 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
3577 _item_block_add(Elm_Genlist_Smart_Data *sd,
3580 Item_Block *itb = NULL;
3587 itb = calloc(1, sizeof(Item_Block));
3588 if (!itb) return EINA_FALSE;
3590 if (!it->item->rel->item->block)
3593 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3594 itb->items = eina_list_append(itb->items, it);
3595 itb->position_update = EINA_TRUE;
3596 it->position = eina_list_count(itb->items);
3597 it->position_update = EINA_TRUE;
3599 if (sd->blocks != EINA_INLIST_GET(itb))
3603 (EINA_INLIST_GET(itb)->prev))->position + 1;
3614 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3615 if (it->item->before)
3617 sd->blocks = eina_inlist_prepend_relative
3618 (sd->blocks, EINA_INLIST_GET(itb),
3619 EINA_INLIST_GET(it->item->rel->item->block));
3621 eina_list_prepend_relative_list(itb->items, it, tmp);
3623 /* Update index from where we prepended */
3624 _item_position_update
3625 (eina_list_prev(tmp), it->item->rel->position);
3626 _item_block_position_update
3627 (EINA_INLIST_GET(itb),
3628 it->item->rel->item->block->position);
3632 sd->blocks = eina_inlist_append_relative
3633 (sd->blocks, EINA_INLIST_GET(itb),
3634 EINA_INLIST_GET(it->item->rel->item->block));
3636 eina_list_append_relative_list(itb->items, it, tmp);
3638 /* Update block index from where we appended */
3639 _item_position_update
3640 (eina_list_next(tmp), it->item->rel->position + 1);
3641 _item_block_position_update
3642 (EINA_INLIST_GET(itb),
3643 it->item->rel->item->block->position + 1);
3649 if (it->item->before)
3653 itb = (Item_Block *)(sd->blocks);
3654 if (itb->count >= sd->max_items_per_block)
3656 itb = _item_block_new(sd, EINA_TRUE);
3657 if (!itb) return EINA_FALSE;
3662 itb = _item_block_new(sd, EINA_TRUE);
3663 if (!itb) return EINA_FALSE;
3665 itb->items = eina_list_prepend(itb->items, it);
3667 _item_position_update(itb->items, 0);
3673 itb = (Item_Block *)(sd->blocks->last);
3674 if (itb->count >= sd->max_items_per_block)
3676 itb = _item_block_new(sd, EINA_FALSE);
3677 if (!itb) return EINA_FALSE;
3682 itb = _item_block_new(sd, EINA_FALSE);
3683 if (!itb) return EINA_FALSE;
3685 itb->items = eina_list_append(itb->items, it);
3686 it->position = eina_list_count(itb->items);
3694 if (it->item->rel->item->queued)
3696 /* NOTE: for a strange reason eina_list and eina_inlist
3697 don't have the same property on sorted insertion
3698 order, so the queue is not always ordered like the
3699 item list. This lead to issue where we depend on an
3700 item that is not yet created. As a quick work around,
3701 we reschedule the calc of the item and stop reordering
3702 the list to prevent any nasty issue to show up here.
3704 sd->queue = eina_list_append(sd->queue, it);
3705 sd->requeued = EINA_TRUE;
3706 it->item->queued = EINA_TRUE;
3710 itb = it->item->rel->item->block;
3711 if (!itb) goto newblock;
3712 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3713 if (it->item->before)
3715 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3716 _item_position_update
3717 (eina_list_prev(tmp), it->item->rel->position);
3721 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3722 _item_position_update
3723 (eina_list_next(tmp), it->item->rel->position + 1);
3728 itb->changed = EINA_TRUE;
3729 it->item->block = itb;
3730 if (itb->sd->calc_job) ecore_job_del(itb->sd->calc_job);
3731 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd);
3733 if (itb->count > itb->sd->max_items_per_block)
3738 Eina_Bool done = EINA_FALSE;
3740 newc = itb->count / 2;
3742 if (EINA_INLIST_GET(itb)->prev)
3744 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3746 if (itbp->count + newc < sd->max_items_per_block / 2)
3748 /* moving items to previous block */
3749 while ((itb->count > newc) && (itb->items))
3751 it2 = eina_list_data_get(itb->items);
3752 itb->items = eina_list_remove_list
3753 (itb->items, itb->items);
3756 itbp->items = eina_list_append(itbp->items, it2);
3757 it2->item->block = itbp;
3765 if (!done && EINA_INLIST_GET(itb)->next)
3767 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3769 if (itbn->count + newc < sd->max_items_per_block / 2)
3771 /* moving items to next block */
3772 while ((itb->count > newc) && (itb->items))
3776 l = eina_list_last(itb->items);
3777 it2 = eina_list_data_get(l);
3778 itb->items = eina_list_remove_list(itb->items, l);
3781 itbn->items = eina_list_prepend(itbn->items, it2);
3782 it2->item->block = itbn;
3792 /* moving items to new block */
3793 itb2 = calloc(1, sizeof(Item_Block));
3794 if (!itb2) return EINA_FALSE;
3797 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
3798 EINA_INLIST_GET(itb));
3799 itb2->changed = EINA_TRUE;
3800 while ((itb->count > newc) && (itb->items))
3804 l = eina_list_last(itb->items);
3806 itb->items = eina_list_remove_list(itb->items, l);
3809 itb2->items = eina_list_prepend(itb2->items, it2);
3810 it2->item->block = itb2;
3820 _item_process(Elm_Genlist_Smart_Data *sd,
3823 if (!_item_block_add(sd, it)) return 1;
3825 _item_block_realize(it->item->block);
3831 _item_process_post(Elm_Genlist_Smart_Data *sd,
3835 Eina_Bool show_me = EINA_FALSE;
3837 if (it->item->block->changed)
3839 show_me = _item_block_recalc
3840 (it->item->block, it->item->block->num, qadd);
3841 it->item->block->changed = 0;
3842 if (sd->pan_changed)
3844 if (sd->calc_job) ecore_job_del(sd->calc_job);
3845 sd->calc_job = NULL;
3847 sd->pan_changed = EINA_FALSE;
3850 if (show_me) it->item->block->show_me = EINA_TRUE;
3852 /* when prepending, move the scroller along with the first selected
3853 * item to create the illusion that we're watching the selected
3854 * item this prevents the selected item being scrolled off the
3857 if (sd->selected && it->item->before)
3862 it2 = sd->selected->data;
3863 if (!it2->item->block) return;
3864 sd->s_iface->content_pos_get(ELM_WIDGET_DATA(sd)->obj, NULL, &y);
3865 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
3866 if ((it->y + it->item->block->y > y + h) ||
3867 (it->y + it->item->block->y + it->item->h < y))
3868 /* offscreen, just update */
3869 sd->s_iface->content_region_show
3870 (ELM_WIDGET_DATA(sd)->obj, it2->x + it2->item->block->x, y,
3871 it2->item->block->w, h);
3873 sd->s_iface->content_region_show
3874 (ELM_WIDGET_DATA(sd)->obj, it->x + it->item->block->x,
3875 y + it->item->h, it->item->block->w, h);
3880 _queue_process(Elm_Genlist_Smart_Data *sd)
3885 t0 = ecore_loop_time_get();
3886 for (n = 0; (sd->queue) && (n < 128); n++)
3890 it = eina_list_data_get(sd->queue);
3891 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
3892 it->item->queued = EINA_FALSE;
3893 if (_item_process(sd, it)) continue;
3894 t = ecore_time_get();
3895 _item_process_post(sd, it, EINA_TRUE);
3896 /* same as eina_inlist_count > 1 */
3897 if (sd->blocks && sd->blocks->next)
3899 if ((t - t0) > (ecore_animator_frametime_get())) break;
3906 _item_idle_enterer(void *data)
3908 Elm_Genlist_Smart_Data *sd = data;
3910 if (sd->prev_viewport_w == 0) return ECORE_CALLBACK_RENEW;
3911 if (_queue_process(sd) > 0)
3914 // Job always be alive because idle_enterer should be alive
3915 if (sd->calc_job) ecore_job_del(sd->calc_job);
3916 sd->calc_job = ecore_job_add(_calc_job, sd);
3920 sd->queue_idle_enterer = NULL;
3921 return ECORE_CALLBACK_CANCEL;
3924 #if GENLIST_FX_SUPPORT
3925 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
3927 return ECORE_CALLBACK_RENEW;
3931 _item_queue(Elm_Genlist_Smart_Data *sd,
3935 if (it->item->queued) return;
3937 it->item->queued = EINA_TRUE;
3938 if (cb && !sd->requeued)
3939 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
3941 sd->queue = eina_list_append(sd->queue, it);
3943 if (sd->queue_idle_enterer)
3944 ecore_idle_enterer_del(sd->queue_idle_enterer);
3945 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd);
3947 if (sd->prev_viewport_w != 0)
3949 while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
3952 while ((sd->queue) && (sd->blocks) &&
3953 (sd->homogeneous) && (sd->mode == ELM_LIST_COMPRESS))
3958 /* If the application wants to know the relative item, use
3959 * elm_genlist_item_prev_get(it)*/
3961 _item_move_after(Elm_Gen_Item *it,
3962 Elm_Gen_Item *after)
3966 if (it == after) return;
3968 GL_IT(it)->wsd->items =
3969 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
3970 if (it->item->block) _item_block_del(it);
3972 GL_IT(it)->wsd->items = eina_inlist_append_relative
3973 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3974 it->item->rel = after;
3975 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
3976 it->item->before = EINA_FALSE;
3977 if (after->item->group_item) it->item->group_item = after->item->group_item;
3978 _item_queue(GL_IT(it)->wsd, it, NULL);
3980 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
3984 _access_activate_cb(void *data __UNUSED__,
3985 Evas_Object *part_obj __UNUSED__,
3986 Elm_Object_Item *item)
3988 _item_select_unselect((Elm_Gen_Item *)item, EINA_TRUE);
3991 /* If the application wants to know the relative item, use
3992 * elm_genlist_item_next_get(it)*/
3994 _item_move_before(Elm_Gen_Item *it,
3995 Elm_Gen_Item *before)
3998 if (!before) return;
3999 if (it == before) return;
4001 GL_IT(it)->wsd->items =
4002 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
4003 if (it->item->block) _item_block_del(it);
4004 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
4005 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4006 it->item->rel = before;
4007 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
4008 it->item->before = EINA_TRUE;
4009 if (before->item->group_item)
4010 it->item->group_item = before->item->group_item;
4011 _item_queue(GL_IT(it)->wsd, it, NULL);
4013 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4017 _item_mouse_up_cb(void *data,
4018 Evas *evas __UNUSED__,
4019 Evas_Object *obj __UNUSED__,
4022 Evas_Event_Mouse_Up *ev = event_info;
4023 Eina_Bool dragged = EINA_FALSE;
4024 Elm_Genlist_Smart_Data *sd;
4025 Elm_Gen_Item *it = data;
4027 if (ev->button != 1) return;
4028 it->down = EINA_FALSE;
4029 sd = GL_IT(it)->wsd;
4031 sd->mouse_down = EINA_FALSE;
4032 if (sd->multi_touched)
4034 if ((!sd->multi) && (!it->selected) && (it->highlighted))
4035 _item_unhighlight(it);
4036 if (sd->multi_down) return;
4037 _multi_touch_gesture_eval(data);
4042 ecore_timer_del(it->long_timer);
4043 it->long_timer = NULL;
4047 it->dragging = EINA_FALSE;
4048 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
4051 if (it->item->swipe_timer)
4053 ecore_timer_del(it->item->swipe_timer);
4054 it->item->swipe_timer = NULL;
4056 if (sd->multi_timer)
4058 ecore_timer_del(sd->multi_timer);
4059 sd->multi_timer = NULL;
4060 sd->multi_timeout = EINA_FALSE;
4062 sd->on_hold = EINA_FALSE;
4063 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4065 if (sd->swipe) _swipe_do(data);
4066 sd->longpressed = EINA_FALSE;
4069 if ((sd->reorder_mode) && (sd->reorder_it))
4071 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
4072 sd->reorder_fast = 0;
4074 if (sd->reorder_rel &&
4075 (sd->reorder_it->parent == sd->reorder_rel->parent))
4077 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
4078 _item_move_before(sd->reorder_it, sd->reorder_rel);
4080 _item_move_after(sd->reorder_it, sd->reorder_rel);
4081 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4085 if (sd->calc_job) ecore_job_del(sd->calc_job);
4086 sd->calc_job = ecore_job_add(_calc_job, sd);
4088 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
4089 sd->reorder_it = sd->reorder_rel = NULL;
4090 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4091 sd->s_iface->bounce_allow_set
4092 (ELM_WIDGET_DATA(sd)->obj, sd->h_bounce, sd->v_bounce);
4096 if (it->want_unrealize && !(it->item->unrealize_disabled))
4098 _item_unrealize(it, EINA_FALSE);
4099 if (it->item->block->want_unrealize)
4100 _item_block_unrealize(it->item->block);
4105 if (!sd->longpressed)
4106 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
4107 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
4108 _item_select_unselect(it, EINA_TRUE);
4109 else _item_select_unselect(it, !it->selected);
4111 _item_unhighlight(it);
4115 _item_mouse_callbacks_add(Elm_Gen_Item *it,
4118 evas_object_event_callback_add
4119 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4120 evas_object_event_callback_add
4121 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4122 evas_object_event_callback_add
4123 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4124 evas_object_event_callback_add
4125 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4126 evas_object_event_callback_add
4127 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4128 evas_object_event_callback_add
4129 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4133 _item_mouse_callbacks_del(Elm_Gen_Item *it,
4136 evas_object_event_callback_del_full
4137 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4138 evas_object_event_callback_del_full
4139 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4140 evas_object_event_callback_del_full
4141 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4142 evas_object_event_callback_del_full
4143 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4144 evas_object_event_callback_del_full
4145 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4146 evas_object_event_callback_del_full
4147 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4151 _scroll_hold_timer_cb(void *data)
4153 Elm_Genlist_Smart_Data *sd = data;
4155 if (!data) return ECORE_CALLBACK_CANCEL;
4157 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4158 sd->scr_hold_timer = NULL;
4160 return ECORE_CALLBACK_CANCEL;
4164 _decorate_item_finished_signal_cb(void *data,
4166 const char *emission __UNUSED__,
4167 const char *source __UNUSED__)
4169 Elm_Gen_Item *it = data;
4172 if (!data || !obj) return;
4173 if ((!it->realized) || (!it->item->deco_it_view)) return;
4175 it->item->nocache_once = EINA_FALSE;
4176 _decorate_item_unrealize(it);
4177 if (it->item->group_item)
4178 evas_object_raise(it->item->VIEW(group_item));
4180 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
4181 GL_IT(it)->wsd->decorate_it_type);
4182 edje_object_signal_callback_del_full
4183 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
4187 _item_mode_content_unrealize(Elm_Gen_Item *it,
4188 Evas_Object *target,
4191 Eina_List **contents_list)
4193 Eina_List *res = *contents_list;
4195 if (it->itc->func.content_get)
4199 Evas_Object *ic = NULL;
4201 EINA_LIST_FOREACH(*source, l, key)
4203 if (parts && fnmatch(parts, key, FNM_PERIOD))
4206 ic = edje_object_part_swallow_get(target, key);
4209 res = eina_list_remove(res, ic);
4210 edje_object_part_unswallow(target, ic);
4211 evas_object_del(ic);
4220 _item_content_unrealize(Elm_Gen_Item *it,
4221 Evas_Object *target,
4225 Eina_List *res = it->content_objs;
4227 if (it->itc->func.content_get)
4231 Evas_Object *ic = NULL;
4233 EINA_LIST_FOREACH(*source, l, key)
4235 if (parts && fnmatch(parts, key, FNM_PERIOD))
4238 ic = edje_object_part_swallow_get(target, key);
4241 res = eina_list_remove(res, ic);
4242 edje_object_part_unswallow(target, ic);
4243 // FIXME: If parent-child relationship was broken before 'ic'
4244 // is deleted, freeze_pop will not be called. ex) elm_slider
4245 // If layout is used instead of edje, this problme can be
4247 if (0 != elm_widget_scroll_freeze_get(ic))
4248 elm_widget_scroll_freeze_pop(ic);
4249 evas_object_del(ic);
4258 _item_block_recalc(Item_Block *itb,
4262 const Eina_List *l, *ll;
4264 Evas_Coord minw = 0, minh = 0;
4265 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
4269 EINA_LIST_FOREACH_SAFE(itb->items, l, ll, it)
4271 show_me |= it->item->show_me;
4276 if (!it->item->mincalcd) changed = EINA_TRUE;
4279 _item_realize(it, in, EINA_TRUE);
4280 _item_unrealize(it, EINA_TRUE);
4285 if ((itb->sd->homogeneous) &&
4286 (itb->sd->mode == ELM_LIST_COMPRESS))
4290 it->item->w = it->item->minw =
4291 GL_IT(it)->wsd->group_item_width;
4292 it->item->h = it->item->minh =
4293 GL_IT(it)->wsd->group_item_height;
4297 it->item->w = it->item->minw =
4298 GL_IT(it)->wsd->item_width;
4299 it->item->h = it->item->minh =
4300 GL_IT(it)->wsd->item_height;
4305 _item_realize(it, in, EINA_TRUE);
4306 _item_unrealize(it, EINA_TRUE);
4312 if (!it->item->mincalcd) changed = EINA_TRUE;
4313 _item_realize(it, in, EINA_FALSE);
4315 minh += it->item->minh;
4316 if (minw < it->item->minw) minw = it->item->minw;
4320 #if GENLIST_PINCH_ZOOM_SUPPORT
4321 if (IS_ROOT_PARENT_IT(it))
4322 it->item->pan_scrl_y = itb->y + it->y;
4326 if (changed) itb->sd->pan_changed = changed;
4329 itb->changed = EINA_FALSE;
4330 itb->position_update = EINA_FALSE;
4336 _update_job(void *data)
4338 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
4339 Elm_Genlist_Smart_Data *sd = data;
4344 sd->update_job = NULL;
4347 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4348 EINA_INLIST_FOREACH(sd->blocks, itb)
4350 Evas_Coord itminw, itminh;
4357 _item_block_position(itb, num);
4361 recalc = EINA_FALSE;
4362 EINA_LIST_FOREACH(itb->items, l2, it)
4364 if (it->item->updateme)
4366 itminw = it->item->minw;
4367 itminh = it->item->minh;
4369 it->item->updateme = EINA_FALSE;
4372 _item_unrealize(it, EINA_FALSE);
4373 _item_realize(it, num, EINA_FALSE);
4374 position = EINA_TRUE;
4378 _item_realize(it, num, EINA_TRUE);
4379 _item_unrealize(it, EINA_TRUE);
4381 if ((it->item->minw != itminw) || (it->item->minh != itminh))
4386 itb->updateme = EINA_FALSE;
4389 position = EINA_TRUE;
4390 itb->changed = EINA_TRUE;
4391 _item_block_recalc(itb, num0, EINA_FALSE);
4392 _item_block_position(itb, num0);
4397 if (sd->calc_job) ecore_job_del(sd->calc_job);
4398 sd->calc_job = ecore_job_add(_calc_job, sd);
4400 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4401 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4405 _scroll_animate_start_cb(Evas_Object *obj,
4406 void *data __UNUSED__)
4408 #if GENLIST_FX_SUPPORT
4409 _elm_genlist_fx_clear(obj, EINA_FALSE);
4411 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
4415 _scroll_animate_stop_cb(Evas_Object *obj,
4416 void *data __UNUSED__)
4418 #if GENLIST_FX_SUPPORT
4419 _elm_genlist_fx_clear(obj, EINA_FALSE);
4421 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
4425 _scroll_drag_start_cb(Evas_Object *obj,
4426 void *data __UNUSED__)
4428 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
4432 _scroll_drag_stop_cb(Evas_Object *obj,
4433 void *data __UNUSED__)
4435 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
4439 _edge_left_cb(Evas_Object *obj,
4440 void *data __UNUSED__)
4442 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
4446 _edge_right_cb(Evas_Object *obj,
4447 void *data __UNUSED__)
4449 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
4453 _edge_top_cb(Evas_Object *obj,
4454 void *data __UNUSED__)
4456 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
4460 _edge_bottom_cb(Evas_Object *obj,
4461 void *data __UNUSED__)
4463 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
4467 _vbar_drag_cb(Evas_Object *obj,
4468 void *data __UNUSED__)
4470 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
4474 _vbar_press_cb(Evas_Object *obj,
4475 void *data __UNUSED__)
4477 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
4481 _vbar_unpress_cb(Evas_Object *obj,
4482 void *data __UNUSED__)
4484 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
4488 _hbar_drag_cb(Evas_Object *obj,
4489 void *data __UNUSED__)
4491 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
4495 _hbar_press_cb(Evas_Object *obj,
4496 void *data __UNUSED__)
4498 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
4502 _hbar_unpress_cb(Evas_Object *obj,
4503 void *data __UNUSED__)
4505 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
4509 _decorate_item_realize(Elm_Gen_Item *it)
4512 if (it->item->deco_it_view) return;
4514 //evas_event_freeze(evas_object_evas_get(obj));
4515 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
4516 edje_object_scale_set
4517 (it->item->deco_it_view, elm_widget_scale_get(WIDGET(it)) *
4518 elm_config_scale_get());
4519 evas_object_smart_member_add
4520 (it->item->deco_it_view, GL_IT(it)->wsd->pan_obj);
4521 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
4523 strncpy(buf, "item", sizeof(buf));
4524 if (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)
4525 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
4527 if (it->item->order_num_in & 0x1)
4528 strncat(buf, "_odd", sizeof(buf) - strlen(buf));
4529 strncat(buf, "/", sizeof(buf) - strlen(buf));
4530 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
4532 elm_widget_theme_object_set
4533 (WIDGET(it), it->item->deco_it_view, "genlist", buf,
4534 elm_widget_style_get(WIDGET(it)));
4535 edje_object_mirrored_set
4536 (it->item->deco_it_view, elm_widget_mirrored_get(WIDGET(it)));
4538 /* signal callback add */
4539 evas_object_event_callback_add
4540 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb,
4542 evas_object_event_callback_add
4543 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4544 evas_object_event_callback_add
4545 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb,
4548 if (eina_list_count(it->item->deco_it_content_objs) != 0)
4549 ERR_ABORT("If you see this error, please notify us and we"
4552 /* text_get, content_get, state_get */
4554 (it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
4555 if (!it->item->deco_it_contents)
4556 it->item->deco_it_contents =
4557 elm_widget_stringlist_get
4558 (edje_object_data_get(it->item->deco_it_view, "contents"));
4559 it->item->deco_it_content_objs =
4560 _item_mode_content_realize
4561 (it, it->item->deco_it_view, &it->item->deco_it_contents, NULL,
4562 &it->item->deco_it_content_objs);
4564 (it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
4565 edje_object_part_swallow
4566 (it->item->deco_it_view,
4567 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
4569 it->want_unrealize = EINA_FALSE;
4570 //evas_event_thaw(evas_object_evas_get(obj));
4571 //evas_event_thaw_eval(evas_object_evas_get(obj));
4575 _decorate_item_set(Elm_Gen_Item *it)
4577 Elm_Genlist_Smart_Data *sd;
4582 sd = GL_IT(it)->wsd;
4585 it->item->nocache_once = EINA_TRUE;
4587 if (sd->scr_hold_timer)
4589 ecore_timer_del(sd->scr_hold_timer);
4590 sd->scr_hold_timer = NULL;
4592 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
4593 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
4595 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4596 _decorate_item_realize(it);
4597 if (it->item->group_item)
4598 evas_object_raise(it->item->VIEW(group_item));
4600 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
4601 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4602 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4604 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
4605 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4609 _decorate_item_unset(Elm_Genlist_Smart_Data *sd)
4611 char buf[1024], buf2[1024];
4614 if (!sd->mode_item) return;
4617 it->item->nocache_once = EINA_TRUE;
4619 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
4620 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
4621 sd->decorate_it_type);
4622 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4623 edje_object_signal_callback_add
4624 (it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb,
4626 sd->mode_item = NULL;
4630 // FIXME: difference from upstream
4632 _mouse_down_scroller(void *data,
4633 Evas *evas __UNUSED__,
4634 Evas_Object *obj __UNUSED__,
4635 void *event_info __UNUSED__)
4637 Widget_Data *wd = elm_widget_data_get(data);
4640 wd->drag_started = EINA_FALSE;
4644 _mouse_up_scroller(void *data,
4645 Evas *evas __UNUSED__,
4646 Evas_Object *obj __UNUSED__,
4647 void *event_info __UNUSED__)
4649 Widget_Data *wd = elm_widget_data_get(data);
4652 wd->drag_started = EINA_FALSE;
4656 _mouse_move_scroller(void *data,
4657 Evas *evas __UNUSED__,
4658 Evas_Object *obj __UNUSED__,
4661 Widget_Data *wd = elm_widget_data_get(data);
4662 Evas_Event_Mouse_Move *ev = event_info;
4663 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
4666 if (wd->drag_started) return;
4668 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4669 dx = ev->cur.canvas.x - ev->prev.canvas.x;
4670 dy = ev->cur.canvas.y - ev->prev.canvas.y;
4673 if (adx < 0) adx = -dx;
4674 if (ady < 0) ady = -dy;
4675 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
4679 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
4680 wd->drag_started = EINA_TRUE;
4684 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
4685 wd->drag_started = EINA_TRUE;
4692 _elm_genlist_smart_add(Evas_Object *obj)
4694 Evas_Coord minw, minh;
4695 Elm_Genlist_Pan_Smart_Data *pan_data;
4697 EVAS_SMART_DATA_ALLOC(obj, Elm_Genlist_Smart_Data);
4699 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.add(obj);
4701 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
4702 evas_object_smart_member_add(priv->hit_rect, obj);
4703 elm_widget_sub_object_add(obj, priv->hit_rect);
4705 /* common scroller hit rectangle setup */
4706 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
4707 evas_object_show(priv->hit_rect);
4708 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
4710 elm_widget_can_focus_set(obj, EINA_TRUE);
4711 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
4713 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
4715 /* interface's add() routine issued AFTER the object's smart_add() */
4716 priv->s_iface = evas_object_smart_interface_get
4717 (obj, ELM_SCROLLABLE_IFACE_NAME);
4719 priv->s_iface->objects_set
4720 (obj, ELM_WIDGET_DATA(priv)->resize_obj, priv->hit_rect);
4722 priv->s_iface->bounce_allow_set
4723 (obj, EINA_FALSE, _elm_config->thumbscroll_bounce_enable);
4724 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
4726 priv->s_iface->animate_start_cb_set(obj, _scroll_animate_start_cb);
4727 priv->s_iface->animate_stop_cb_set(obj, _scroll_animate_stop_cb);
4728 priv->s_iface->drag_start_cb_set(obj, _scroll_drag_start_cb);
4729 priv->s_iface->drag_stop_cb_set(obj, _scroll_drag_stop_cb);
4730 priv->s_iface->edge_left_cb_set(obj, _edge_left_cb);
4731 priv->s_iface->edge_right_cb_set(obj, _edge_right_cb);
4732 priv->s_iface->edge_top_cb_set(obj, _edge_top_cb);
4733 priv->s_iface->edge_bottom_cb_set(obj, _edge_bottom_cb);
4734 priv->s_iface->vbar_drag_cb_set(obj, _vbar_drag_cb);
4735 priv->s_iface->vbar_press_cb_set(obj, _vbar_press_cb);
4736 priv->s_iface->vbar_unpress_cb_set(obj, _vbar_unpress_cb);
4737 priv->s_iface->hbar_drag_cb_set(obj, _hbar_drag_cb);
4738 priv->s_iface->hbar_press_cb_set(obj, _hbar_press_cb);
4739 priv->s_iface->hbar_unpress_cb_set(obj, _hbar_unpress_cb);
4741 priv->mode = ELM_LIST_SCROLL;
4742 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
4743 priv->item_cache_max = priv->max_items_per_block * 2;
4744 priv->longpress_timeout = _elm_config->longpress_timeout;
4745 priv->highlight = EINA_TRUE;
4747 #if GENLIST_FX_SUPPORT
4748 priv->fx_mode = EINA_FALSE;
4749 priv->rendered = EINA_FALSE;
4750 priv->fx_first_captured = EINA_FALSE;
4751 priv->fx_playing = EINA_FALSE;
4752 priv->fx_items_deleted = EINA_FALSE;
4753 priv->genlist_clearing = EINA_FALSE;
4756 priv->pan_obj = evas_object_smart_add
4757 (evas_object_evas_get(obj), _elm_genlist_pan_smart_class_new());
4758 pan_data = evas_object_smart_data_get(priv->pan_obj);
4759 pan_data->wsd = priv;
4762 // FIXME: difference from upstream
4763 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
4764 _mouse_down_scroller, obj);
4765 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
4766 _mouse_up_scroller, obj);
4767 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
4768 _mouse_move_scroller, obj);
4771 priv->s_iface->extern_pan_set(obj, priv->pan_obj);
4773 edje_object_size_min_calc(ELM_WIDGET_DATA(priv)->resize_obj, &minw, &minh);
4774 evas_object_size_hint_min_set(obj, minw, minh);
4776 _item_cache_all_free(priv);
4777 _mirrored_set(obj, elm_widget_mirrored_get(obj));
4779 elm_layout_sizing_eval(obj);
4783 _elm_genlist_smart_del(Evas_Object *obj)
4785 ELM_GENLIST_DATA_GET(obj, sd);
4787 elm_genlist_clear(obj);
4788 if (sd->calc_job) ecore_job_del(sd->calc_job);
4789 if (sd->update_job) ecore_job_del(sd->update_job);
4790 if (sd->queue_idle_enterer) ecore_idle_enterer_del(sd->queue_idle_enterer);
4791 if (sd->must_recalc_idler) ecore_idler_del(sd->must_recalc_idler);
4792 if (sd->multi_timer) ecore_timer_del(sd->multi_timer);
4793 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
4794 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
4796 evas_object_del(sd->pan_obj);
4797 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.del(obj);
4801 _elm_genlist_smart_move(Evas_Object *obj,
4805 ELM_GENLIST_DATA_GET(obj, sd);
4807 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.move(obj, x, y);
4809 evas_object_move(sd->hit_rect, x, y);
4813 _elm_genlist_smart_resize(Evas_Object *obj,
4817 ELM_GENLIST_DATA_GET(obj, sd);
4819 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.resize(obj, w, h);
4821 evas_object_resize(sd->hit_rect, w, h);
4825 _elm_genlist_smart_member_add(Evas_Object *obj,
4826 Evas_Object *member)
4828 ELM_GENLIST_DATA_GET(obj, sd);
4830 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.member_add(obj, member);
4833 evas_object_raise(sd->hit_rect);
4837 _access_obj_process(Elm_Genlist_Smart_Data *sd, Eina_Bool is_access)
4840 Eina_Bool done = EINA_FALSE;
4842 EINA_INLIST_FOREACH(sd->blocks, itb)
4850 EINA_LIST_FOREACH(itb->items, l, it)
4852 if (!it->realized) continue;
4853 if (is_access) _access_widget_item_register(it);
4855 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
4858 else if (done) break;
4863 _elm_genlist_smart_access(Evas_Object *obj, Eina_Bool is_access)
4865 ELM_GENLIST_CHECK(obj);
4866 ELM_GENLIST_DATA_GET(obj, sd);
4869 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
4870 _elm_genlist_smart_focus_next;
4872 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
4873 _access_obj_process(sd, is_access);
4877 _elm_genlist_smart_set_user(Elm_Genlist_Smart_Class *sc)
4879 ELM_WIDGET_CLASS(sc)->base.add = _elm_genlist_smart_add;
4880 ELM_WIDGET_CLASS(sc)->base.del = _elm_genlist_smart_del;
4881 ELM_WIDGET_CLASS(sc)->base.move = _elm_genlist_smart_move;
4882 ELM_WIDGET_CLASS(sc)->base.resize = _elm_genlist_smart_resize;
4883 ELM_WIDGET_CLASS(sc)->base.member_add = _elm_genlist_smart_member_add;
4885 ELM_WIDGET_CLASS(sc)->sub_object_add = _elm_genlist_smart_sub_object_add;
4886 ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_genlist_smart_sub_object_del;
4887 ELM_WIDGET_CLASS(sc)->on_focus = _elm_genlist_smart_on_focus;
4888 ELM_WIDGET_CLASS(sc)->theme = _elm_genlist_smart_theme;
4889 ELM_WIDGET_CLASS(sc)->event = _elm_genlist_smart_event;
4890 ELM_WIDGET_CLASS(sc)->translate = _elm_genlist_smart_translate;
4892 /* not a 'focus chain manager' */
4893 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
4894 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
4896 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_genlist_smart_sizing_eval;
4899 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
4900 ELM_WIDGET_CLASS(sc)->focus_next = _elm_genlist_smart_focus_next;
4902 ELM_WIDGET_CLASS(sc)->access = _elm_genlist_smart_access;
4905 EAPI const Elm_Genlist_Smart_Class *
4906 elm_genlist_smart_class_get(void)
4908 static Elm_Genlist_Smart_Class _sc =
4909 ELM_GENLIST_SMART_CLASS_INIT_NAME_VERSION(ELM_GENLIST_SMART_NAME);
4910 static const Elm_Genlist_Smart_Class *class = NULL;
4911 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
4916 _elm_genlist_smart_set(&_sc);
4917 esc->callbacks = _smart_callbacks;
4924 elm_genlist_add(Evas_Object *parent)
4928 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
4930 obj = elm_widget_add(_elm_genlist_smart_class_new(), parent);
4931 if (!obj) return NULL;
4933 if (!elm_widget_sub_object_add(parent, obj))
4934 ERR("could not add %p as sub object of %p", obj, parent);
4940 static Evas_Object *
4941 _item_content_get_hook(Elm_Gen_Item *it,
4944 Evas_Object *ret = NULL;
4945 if (it->deco_all_view)
4946 ret = edje_object_part_swallow_get(it->deco_all_view, part);
4947 else if (it->decorate_it_set)
4948 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
4950 ret = edje_object_part_swallow_get(VIEW(it), part);
4955 _item_text_get_hook(Elm_Gen_Item *it,
4958 if (!it->itc->func.text_get) return NULL;
4959 const char *ret = NULL;
4960 if (it->deco_all_view)
4961 ret = edje_object_part_text_get(it->deco_all_view, part);
4962 else if (it->decorate_it_set)
4963 ret = edje_object_part_text_get(it->item->deco_it_view, part);
4965 ret = edje_object_part_text_get(VIEW(it), part);
4970 _item_disable_hook(Elm_Object_Item *item)
4974 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4977 elm_genlist_item_selected_set(item, EINA_FALSE);
4981 if (elm_widget_item_disabled_get(it))
4983 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4984 if (it->deco_all_view)
4985 edje_object_signal_emit
4986 (it->deco_all_view, "elm,state,disabled", "elm");
4990 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
4991 if (it->deco_all_view)
4992 edje_object_signal_emit
4993 (it->deco_all_view, "elm,state,enabled", "elm");
4995 EINA_LIST_FOREACH(it->content_objs, l, obj)
4996 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(it));
5001 _item_free(Elm_Gen_Item *it)
5003 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5005 #if GENLIST_FX_SUPPORT
5006 if (sd->fx_mode) GL_IT(it)->has_proxy_it = EINA_FALSE;
5007 _elm_genlist_proxy_item_del((Elm_Object_Item *)it);
5008 if ((!sd->fx_mode) || (sd->genlist_clearing))
5011 _item_free_common(it);
5013 _item_unrealize(it, EINA_FALSE);
5014 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
5017 if (sd->calc_job) ecore_job_del(sd->calc_job);
5018 sd->calc_job = ecore_job_add(_calc_job, sd);
5021 #if GENLIST_FX_SUPPORT
5023 _item_del_pre_fx_process(Elm_Gen_Item *it)
5025 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5027 sd->fx_items_deleted = EINA_TRUE;
5028 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5029 if (!eina_list_data_find(sd->pending_del_items, it))
5030 sd->pending_del_items = eina_list_append(sd->pending_del_items, it);
5032 _item_free_common(it);
5038 _item_del_pre_hook(Elm_Object_Item *item)
5040 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5042 #if GENLIST_FX_SUPPORT
5043 if ((GL_IT(it)->wsd->fx_mode) && (!GL_IT(it)->wsd->genlist_clearing))
5045 _item_del_pre_fx_process(it);
5054 _item_signal_emit_hook(Elm_Object_Item *it,
5055 const char *emission,
5058 edje_object_signal_emit(VIEW(it), emission, source);
5061 static Elm_Gen_Item *
5062 _elm_genlist_item_new(Elm_Genlist_Smart_Data *sd,
5063 const Elm_Genlist_Item_Class *itc,
5065 Elm_Gen_Item *parent,
5066 Elm_Genlist_Item_Type type,
5068 const void *func_data)
5070 Elm_Gen_Item *it, *it2;
5073 if (!itc) return NULL;
5075 it = elm_widget_item_new(ELM_WIDGET_DATA(sd)->obj, Elm_Gen_Item);
5076 if (!it) return NULL;
5079 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
5081 it->base.data = data;
5082 it->parent = parent;
5083 it->func.func = func;
5084 it->func.data = func_data;
5086 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
5087 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
5088 elm_widget_item_disable_hook_set(it, _item_disable_hook);
5089 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
5090 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
5092 #if 0 // FIXME: difference from upstream
5093 it->can_focus = EINA_TRUE;
5095 //it->del_cb = (Ecore_Cb)_item_free;
5096 //it->highlight_cb = (Ecore_Cb)_item_highlight;
5097 //it->unhighlight_cb = (Ecore_Cb)_item_unhighlight;
5098 //it->sel_cb = (Ecore_Cb)_item_select;
5099 //it->unsel_cb = (Ecore_Cb)_item_unselect;
5100 //it->unrealize_cb = (Ecore_Cb)_item_unrealize_cb;
5102 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
5103 GL_IT(it)->wsd = sd;
5104 GL_IT(it)->type = type;
5105 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
5109 if (it->parent->group)
5110 GL_IT(it)->group_item = parent;
5111 else if (GL_IT(it->parent)->group_item)
5112 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
5114 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
5116 if (!it2->parent->group) depth += 1;
5118 GL_IT(it)->expanded_depth = depth;
5121 #if GENLIST_FX_SUPPORT
5122 it->item->num = sd->item_count;
5125 sd->fx_items_deleted = EINA_FALSE;
5126 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5133 _elm_genlist_item_compare(const void *data,
5136 const Elm_Gen_Item *it, *item1;
5138 it = ELM_GEN_ITEM_FROM_INLIST(data);
5139 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
5140 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5144 _elm_genlist_item_list_compare(const void *data,
5147 const Elm_Gen_Item *it = data;
5148 const Elm_Gen_Item *item1 = data1;
5150 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5154 elm_genlist_items_count(const Evas_Object *obj)
5156 ELM_GENLIST_CHECK(obj) 0;
5157 ELM_GENLIST_DATA_GET(obj, sd);
5159 return sd->item_count;
5162 EAPI Elm_Object_Item *
5163 elm_genlist_item_append(Evas_Object *obj,
5164 const Elm_Genlist_Item_Class *itc,
5166 Elm_Object_Item *parent,
5167 Elm_Genlist_Item_Type type,
5169 const void *func_data)
5173 ELM_GENLIST_CHECK(obj) NULL;
5174 ELM_GENLIST_DATA_GET(obj, sd);
5176 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(((Elm_Widget_Item *)parent),NULL);
5178 it = _elm_genlist_item_new
5179 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5180 if (!it) return NULL;
5185 sd->group_items = eina_list_append(sd->group_items, it);
5186 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
5187 it->item->rel = NULL;
5191 Elm_Gen_Item *it2 = NULL;
5192 Eina_List *ll = eina_list_last(it->parent->item->items);
5194 if (ll) it2 = ll->data;
5195 it->parent->item->items =
5196 eina_list_append(it->parent->item->items, it);
5197 if (!it2) it2 = it->parent;
5198 sd->items = eina_inlist_append_relative
5199 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5200 it->item->rel = it2;
5201 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5203 it->item->before = EINA_FALSE;
5204 _item_queue(sd, it, NULL);
5206 return (Elm_Object_Item *)it;
5209 EAPI Elm_Object_Item *
5210 elm_genlist_item_prepend(Evas_Object *obj,
5211 const Elm_Genlist_Item_Class *itc,
5213 Elm_Object_Item *parent,
5214 Elm_Genlist_Item_Type type,
5216 const void *func_data)
5220 ELM_GENLIST_CHECK(obj) NULL;
5221 ELM_GENLIST_DATA_GET(obj, sd);
5222 it = _elm_genlist_item_new
5223 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5224 if (!it) return NULL;
5229 sd->group_items = eina_list_prepend(sd->group_items, it);
5230 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
5231 it->item->rel = NULL;
5235 Elm_Gen_Item *it2 = NULL;
5236 Eina_List *ll = it->parent->item->items;
5238 if (ll) it2 = ll->data;
5239 it->parent->item->items =
5240 eina_list_prepend(it->parent->item->items, it);
5241 if (!it2) it2 = it->parent;
5242 sd->items = eina_inlist_prepend_relative
5243 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5244 it->item->rel = it2;
5245 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5247 it->item->before = EINA_TRUE;
5248 _item_queue(sd, it, NULL);
5250 return (Elm_Object_Item *)it;
5253 EAPI Elm_Object_Item *
5254 elm_genlist_item_insert_after(Evas_Object *obj,
5255 const Elm_Genlist_Item_Class *itc,
5257 Elm_Object_Item *parent,
5258 Elm_Object_Item *after_it,
5259 Elm_Genlist_Item_Type type,
5261 const void *func_data)
5263 Elm_Gen_Item *after = (Elm_Gen_Item *)after_it;
5266 ELM_GENLIST_CHECK(obj) NULL;
5267 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
5268 ELM_GENLIST_DATA_GET(obj, sd);
5270 /* It makes no sense to insert after in an empty list with after !=
5271 * NULL, something really bad is happening in your app. */
5272 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5274 it = _elm_genlist_item_new
5275 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5276 if (!it) return NULL;
5280 if ((it->group) && (after->group))
5281 sd->group_items = eina_list_append_relative
5282 (sd->group_items, it, after);
5286 it->parent->item->items =
5287 eina_list_append_relative(it->parent->item->items, it, after);
5289 sd->items = eina_inlist_append_relative
5290 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5292 it->item->rel = after;
5293 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5294 it->item->before = EINA_FALSE;
5295 _item_queue(sd, it, NULL);
5297 return (Elm_Object_Item *)it;
5300 EAPI Elm_Object_Item *
5301 elm_genlist_item_insert_before(Evas_Object *obj,
5302 const Elm_Genlist_Item_Class *itc,
5304 Elm_Object_Item *parent,
5305 Elm_Object_Item *before_it,
5306 Elm_Genlist_Item_Type type,
5308 const void *func_data)
5310 Elm_Gen_Item *before = (Elm_Gen_Item *)before_it;
5313 ELM_GENLIST_CHECK(obj) NULL;
5314 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
5315 ELM_GENLIST_DATA_GET(obj, sd);
5317 /* It makes no sense to insert before in an empty list with before
5318 * != NULL, something really bad is happening in your app. */
5319 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5321 it = _elm_genlist_item_new
5322 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5323 if (!it) return NULL;
5327 if (it->group && before->group)
5329 eina_list_prepend_relative(sd->group_items, it, before);
5333 it->parent->item->items =
5334 eina_list_prepend_relative(it->parent->item->items, it, before);
5336 sd->items = eina_inlist_prepend_relative
5337 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5339 it->item->rel = before;
5340 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5341 it->item->before = EINA_TRUE;
5342 _item_queue(sd, it, NULL);
5344 return (Elm_Object_Item *)it;
5347 EAPI Elm_Object_Item *
5348 elm_genlist_item_sorted_insert(Evas_Object *obj,
5349 const Elm_Genlist_Item_Class *itc,
5351 Elm_Object_Item *parent,
5352 Elm_Genlist_Item_Type type,
5353 Eina_Compare_Cb comp,
5355 const void *func_data)
5357 Elm_Gen_Item *rel = NULL;
5360 ELM_GENLIST_CHECK(obj) NULL;
5361 ELM_GENLIST_DATA_GET(obj, sd);
5363 it = _elm_genlist_item_new
5364 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5365 if (!it) return NULL;
5367 sd->item_compare_cb = comp;
5374 l = eina_list_search_sorted_near_list
5375 (it->parent->item->items, _elm_genlist_item_list_compare, it,
5379 rel = eina_list_data_get(l);
5383 if (cmp_result >= 0)
5385 it->parent->item->items = eina_list_prepend_relative_list
5386 (it->parent->item->items, it, l);
5387 sd->items = eina_inlist_prepend_relative
5388 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5389 it->item->before = EINA_FALSE;
5391 else if (cmp_result < 0)
5393 it->parent->item->items = eina_list_append_relative_list
5394 (it->parent->item->items, it, l);
5395 sd->items = eina_inlist_append_relative
5396 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5397 it->item->before = EINA_TRUE;
5404 sd->state = eina_inlist_sorted_state_new();
5405 eina_inlist_sorted_state_init(sd->state, sd->items);
5406 sd->requeued = EINA_FALSE;
5410 sd->group_items = eina_list_append(sd->group_items, it);
5412 sd->items = eina_inlist_sorted_state_insert
5413 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
5416 if (EINA_INLIST_GET(it)->next)
5418 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5419 it->item->before = EINA_TRUE;
5421 else if (EINA_INLIST_GET(it)->prev)
5423 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5424 it->item->before = EINA_FALSE;
5430 it->item->rel = rel;
5431 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
5434 _item_queue(sd, it, _elm_genlist_item_list_compare);
5436 return (Elm_Object_Item *)it;
5440 _elm_genlist_fx_clear(Evas_Object *obj, Eina_Bool force)
5442 ELM_GENLIST_DATA_GET(obj, sd);
5444 Elm_Gen_FX_Item *fi;
5448 if ((!force) && (!sd->fx_first_captured)) return;
5450 EINA_LIST_FREE(sd->capture_before_items, pi)
5452 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
5453 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
5454 if (pi->proxy) evas_object_del(pi->proxy);
5457 EINA_LIST_FREE(sd->capture_after_items, pi)
5459 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
5460 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
5461 if (pi->proxy) evas_object_del(pi->proxy);
5465 EINA_LIST_FREE(sd->fx_items, fi)
5467 if (fi->trans) elm_transit_del(fi->trans);
5471 EINA_LIST_FREE (sd->pending_unrealized_items, it)
5472 _item_unrealize(it, EINA_FALSE);
5474 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
5475 _decorate_all_item_unrealize(it);
5477 EINA_LIST_FREE (sd->pending_del_items, it)
5480 _elm_widget_item_free((Elm_Widget_Item *)it);
5482 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5483 sd->alpha_bg = NULL;
5484 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
5485 sd->fx_timer = NULL;
5487 sd->genlist_clearing = EINA_TRUE;
5488 sd->fx_playing = EINA_FALSE;
5489 sd->sorting = EINA_FALSE;
5490 sd->fx_first_captured = EINA_FALSE;
5491 sd->fx_items_deleted = EINA_FALSE;
5495 elm_genlist_clear(Evas_Object *obj)
5497 ELM_GENLIST_CHECK(obj);
5498 ELM_GENLIST_DATA_GET(obj, sd);
5503 eina_inlist_sorted_state_free(sd->state);
5507 #if GENLIST_FX_SUPPORT
5510 _elm_genlist_fx_clear(obj, EINA_TRUE);
5511 sd->genlist_clearing = EINA_TRUE;
5512 sd->rendered = EINA_FALSE;
5515 #if GENLIST_PINCH_ZOOM_SUPPORT
5516 sd->pinch_zoom_h = 0;
5517 sd->realized_top_item = NULL;
5518 sd->pinch_zoom_mode = ELM_GEN_PINCH_ZOOM_NONE;
5521 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5523 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
5524 // because sd->items can be modified inside elm_widget_item_del()
5527 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
5528 it->item->nocache_once = EINA_TRUE;
5529 elm_widget_item_del(it);
5533 _item_cache_all_free(sd);
5535 sd->pan_changed = EINA_TRUE;
5536 if (sd->selected) sd->selected = eina_list_free(sd->selected);
5537 sd->selected = NULL;
5539 sd->anchor_item = NULL;
5540 if (sd->multi_timer)
5542 ecore_timer_del(sd->multi_timer);
5543 sd->multi_timer = NULL;
5547 ecore_job_del(sd->update_job);
5548 sd->update_job = NULL;
5552 ecore_job_del(sd->calc_job);
5553 sd->calc_job = NULL;
5555 if (sd->queue_idle_enterer)
5557 ecore_idle_enterer_del(sd->queue_idle_enterer);
5558 sd->queue_idle_enterer = NULL;
5560 if (sd->must_recalc_idler)
5562 ecore_idler_del(sd->must_recalc_idler);
5563 sd->must_recalc_idler = NULL;
5565 if (sd->queue) sd->queue = eina_list_free(sd->queue);
5566 if (sd->reorder_move_animator)
5568 ecore_animator_del(sd->reorder_move_animator);
5569 sd->reorder_move_animator = NULL;
5571 sd->show_item = NULL;
5572 sd->reorder_old_pan_y = 0;
5579 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5580 sd->alpha_bg = NULL;
5584 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
5585 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
5587 elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
5588 sd->s_iface->content_region_show(obj, 0, 0, 0, 0);
5590 #if GENLIST_FX_SUPPORT
5591 sd->genlist_clearing = EINA_FALSE;
5593 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5594 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5598 elm_genlist_multi_select_set(Evas_Object *obj,
5601 ELM_GENLIST_CHECK(obj);
5602 ELM_GENLIST_DATA_GET(obj, sd);
5604 sd->multi = !!multi;
5608 elm_genlist_multi_select_get(const Evas_Object *obj)
5610 ELM_GENLIST_CHECK(obj) EINA_FALSE;
5611 ELM_GENLIST_DATA_GET(obj, sd);
5616 EAPI Elm_Object_Item *
5617 elm_genlist_selected_item_get(const Evas_Object *obj)
5619 ELM_GENLIST_CHECK(obj) NULL;
5620 ELM_GENLIST_DATA_GET(obj, sd);
5623 return sd->selected->data;
5629 elm_genlist_selected_items_get(const Evas_Object *obj)
5631 ELM_GENLIST_CHECK(obj) NULL;
5632 ELM_GENLIST_DATA_GET(obj, sd);
5634 return sd->selected;
5638 elm_genlist_realized_items_get(const Evas_Object *obj)
5641 Eina_List *list = NULL;
5642 Eina_Bool done = EINA_FALSE;
5644 ELM_GENLIST_CHECK(obj) NULL;
5645 ELM_GENLIST_DATA_GET(obj, sd);
5647 EINA_INLIST_FOREACH(sd->blocks, itb)
5655 EINA_LIST_FOREACH(itb->items, l, it)
5657 if (it->realized) list = eina_list_append(list, it);
5668 EAPI Elm_Object_Item *
5669 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5674 Evas_Coord ox, oy, ow, oh;
5678 ELM_GENLIST_CHECK(obj) NULL;
5679 ELM_GENLIST_DATA_GET(obj, sd);
5681 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
5683 EINA_INLIST_FOREACH(sd->blocks, itb)
5688 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
5689 oy + itb->y - itb->sd->pan_y,
5690 itb->w, itb->h, x, y, 1, 1))
5692 EINA_LIST_FOREACH(itb->items, l, it)
5694 Evas_Coord itx, ity;
5696 itx = ox + itb->x + it->x - itb->sd->pan_x;
5697 ity = oy + itb->y + it->y - itb->sd->pan_y;
5698 if (ELM_RECTS_INTERSECT
5699 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5703 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5704 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5709 return (Elm_Object_Item *)it;
5711 lasty = ity + it->item->h;
5716 if (y > lasty) *posret = 1;
5723 EAPI Elm_Object_Item *
5724 elm_genlist_first_item_get(const Evas_Object *obj)
5726 Elm_Gen_Item *tit, *it = NULL;
5728 ELM_GENLIST_CHECK(obj) NULL;
5729 ELM_GENLIST_DATA_GET(obj, sd);
5731 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
5733 return (Elm_Object_Item *)it;
5736 EAPI Elm_Object_Item *
5737 elm_genlist_last_item_get(const Evas_Object *obj)
5741 ELM_GENLIST_CHECK(obj) NULL;
5742 ELM_GENLIST_DATA_GET(obj, sd);
5743 if (!sd->items) return NULL;
5745 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
5746 return (Elm_Object_Item *)it;
5749 EAPI Elm_Object_Item *
5750 elm_genlist_item_next_get(const Elm_Object_Item *item)
5754 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
5756 it = (Elm_Gen_Item *)item;
5759 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5763 return (Elm_Object_Item *)it;
5766 EAPI Elm_Object_Item *
5767 elm_genlist_item_prev_get(const Elm_Object_Item *item)
5771 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
5773 it = (Elm_Gen_Item *)item;
5776 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5780 return (Elm_Object_Item *)it;
5783 EAPI Elm_Object_Item *
5784 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5786 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
5788 return (Elm_Object_Item *)((Elm_Gen_Item *)it)->parent;
5792 elm_genlist_item_subitems_clear(Elm_Object_Item *item)
5794 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5796 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5797 _item_sub_items_clear(it);
5801 elm_genlist_item_selected_set(Elm_Object_Item *item,
5804 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5805 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5807 if (elm_widget_item_disabled_get(it)) return;
5808 selected = !!selected;
5809 if (it->selected == selected) return;
5811 _item_select_unselect(it, selected);
5815 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5817 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5819 return ((Elm_Gen_Item *)it)->selected;
5822 static Elm_Gen_Item *
5823 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5827 if (it->item->expanded)
5829 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
5833 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
5836 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5837 it2 = (Elm_Gen_Item *)
5838 elm_genlist_item_next_get((Elm_Object_Item *)it2);
5844 static Evas_Object *
5845 _tray_alpha_bg_create(const Evas_Object *obj)
5847 Evas_Object *bg = NULL;
5848 Evas_Coord ox, oy, ow, oh;
5850 ELM_GENLIST_CHECK(obj) NULL;
5851 ELM_GENLIST_DATA_GET(obj, sd);
5853 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
5854 bg = evas_object_rectangle_add
5855 (evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5856 evas_object_color_set(bg, 0, 0, 0, 0);
5857 evas_object_resize(bg, ow, oh);
5858 evas_object_move(bg, ox, oy);
5864 elm_genlist_item_expanded_set(Elm_Object_Item *item,
5867 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5869 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5871 expanded = !!expanded;
5872 if (it->item->expanded == expanded) return;
5873 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
5874 it->item->expanded = expanded;
5875 GL_IT(it)->wsd->expanded_item = it;
5876 GL_IT(it)->wsd->expanded_next_item =
5877 _elm_genlist_expanded_next_item_get(it);
5879 if (it->item->expanded)
5882 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
5883 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
5884 GL_IT(it)->wsd->auto_scroll_enabled = EINA_TRUE;
5889 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
5890 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
5891 GL_IT(it)->wsd->auto_scroll_enabled = EINA_FALSE;
5896 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5898 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5900 return ((Elm_Gen_Item *)it)->item->expanded;
5904 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5906 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
5908 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5912 _elm_genlist_item_coordinates_calc(Elm_Object_Item *item,
5913 Elm_Genlist_Item_Scrollto_Type type,
5920 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5921 Evas_Coord gith = 0;
5923 if (!((GL_IT(it)->wsd->homogeneous) &&
5924 (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)))
5926 if ((it->item->queued) || (!it->item->mincalcd))
5928 GL_IT(it)->wsd->show_item = it;
5929 GL_IT(it)->wsd->bring_in = bring_in;
5930 GL_IT(it)->wsd->scroll_to_type = type;
5931 it->item->show_me = EINA_TRUE;
5935 if (GL_IT(it)->wsd->show_item)
5937 GL_IT(it)->wsd->show_item->item->show_me = EINA_FALSE;
5938 GL_IT(it)->wsd->show_item = NULL;
5941 evas_object_geometry_get(GL_IT(it)->wsd->pan_obj, NULL, NULL, w, h);
5944 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5945 if ((it->item->group_item) &&
5946 (GL_IT(it)->wsd->pan_y > (it->y + it->item->block->y)))
5947 gith = it->item->group_item->item->h;
5949 *y = it->y + it->item->block->y - gith;
5952 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5953 if (it->item->group_item) gith = it->item->group_item->item->h;
5954 *y = it->y + it->item->block->y - gith;
5957 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5958 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
5965 *x = it->x + it->item->block->x;
5966 *w = it->item->block->w;
5972 elm_genlist_item_promote(Elm_Object_Item *item)
5974 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5975 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5977 (it, (Elm_Gen_Item *)elm_genlist_first_item_get(WIDGET(it)));
5981 elm_genlist_item_demote(Elm_Object_Item *item)
5983 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5984 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5985 _item_move_after(it, (Elm_Gen_Item *)elm_genlist_last_item_get(WIDGET(it)));
5989 elm_genlist_item_show(Elm_Object_Item *item,
5990 Elm_Genlist_Item_Scrollto_Type type)
5992 Evas_Coord x, y, w, h;
5993 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5994 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5996 if (_elm_genlist_item_coordinates_calc
5997 (item, type, EINA_FALSE, &x, &y, &w, &h))
5998 GL_IT(it)->wsd->s_iface->content_region_show(WIDGET(item), x, y, w, h);
6002 elm_genlist_item_bring_in(Elm_Object_Item *item,
6003 Elm_Genlist_Item_Scrollto_Type type)
6005 Evas_Coord x, y, w, h;
6006 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6007 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6009 if (_elm_genlist_item_coordinates_calc
6010 (item, type, EINA_TRUE, &x, &y, &w, &h))
6011 GL_IT(it)->wsd->s_iface->region_bring_in(WIDGET(item), x, y, w, h);
6015 elm_genlist_item_all_contents_unset(Elm_Object_Item *item,
6018 Evas_Object *content;
6020 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6021 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6023 EINA_LIST_FREE (it->content_objs, content)
6025 evas_object_smart_member_del(content);
6026 evas_object_hide(content);
6027 if (l) *l = eina_list_append(*l, content);
6032 elm_genlist_item_update(Elm_Object_Item *item)
6034 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6035 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6037 if (!it->item->block) return;
6038 it->item->mincalcd = EINA_FALSE;
6039 it->item->updateme = EINA_TRUE;
6040 it->item->block->updateme = EINA_TRUE;
6041 #if GENLIST_ENTRY_SUPPORT
6042 it->item->unrealize_disabled = EINA_FALSE;
6045 #if GENLIST_FX_SUPPORT
6046 _elm_genlist_fx_clear(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj, EINA_FALSE);
6049 if (GL_IT(it)->wsd->update_job) ecore_job_del(GL_IT(it)->wsd->update_job);
6050 GL_IT(it)->wsd->update_job = ecore_job_add(_update_job, GL_IT(it)->wsd);
6054 elm_genlist_item_fields_update(Elm_Object_Item *item,
6056 Elm_Genlist_Item_Field_Type itf)
6058 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6059 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6061 if (!it->item->block) return;
6063 #if GENLIST_ENTRY_SUPPORT
6064 it->item->unrealize_disabled = EINA_FALSE;
6066 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
6068 _item_text_realize(it, VIEW(it), &it->texts, parts);
6070 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
6072 it->content_objs = _item_content_unrealize(it, VIEW(it),
6073 &it->contents, parts);
6074 it->content_objs = _item_content_realize(it, VIEW(it),
6075 &it->contents, parts);
6079 it->item->flip_content_objs =
6080 _item_mode_content_unrealize(it, VIEW(it),
6081 &it->item->flip_contents, parts,
6082 &it->item->flip_content_objs);
6083 it->item->flip_content_objs =
6084 _item_mode_content_realize(it, VIEW(it),
6085 &it->item->flip_contents, parts,
6086 &it->item->flip_content_objs);
6088 if (it->item->deco_it_view)
6090 it->item->deco_it_content_objs =
6091 _item_mode_content_unrealize(it, it->item->deco_it_view,
6092 &it->item->deco_it_contents, parts,
6093 &it->item->deco_it_content_objs);
6094 it->item->deco_it_content_objs =
6095 _item_mode_content_realize(it, it->item->deco_it_view,
6096 &it->item->deco_it_contents, parts,
6097 &it->item->deco_it_content_objs);
6099 if (GL_IT(it)->wsd->decorate_all_mode)
6101 it->item->deco_all_content_objs =
6102 _item_mode_content_unrealize
6103 (it, it->deco_all_view, &it->item->deco_all_contents, parts,
6104 &it->item->deco_all_content_objs);
6105 it->item->deco_all_content_objs =
6106 _item_mode_content_realize(it, it->deco_all_view,
6107 &it->item->deco_all_contents, parts,
6108 &it->item->deco_all_content_objs);
6112 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
6113 _item_state_realize(it, VIEW(it), &it->states, parts);
6117 elm_genlist_item_item_class_update(Elm_Object_Item *item,
6118 const Elm_Genlist_Item_Class *itc)
6120 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6121 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6123 if (!it->item->block) return;
6124 EINA_SAFETY_ON_NULL_RETURN(itc);
6127 it->item->nocache_once = EINA_TRUE;
6129 elm_widget_stringlist_free(it->texts);
6131 elm_widget_stringlist_free(it->contents);
6132 it->contents = NULL;
6133 elm_widget_stringlist_free(it->states);
6138 elm_widget_stringlist_free(it->item->flip_contents);
6139 it->item->flip_contents = NULL;
6141 if (it->item->deco_it_view)
6143 elm_widget_stringlist_free(it->item->deco_it_texts);
6144 it->item->deco_it_texts = NULL;
6145 elm_widget_stringlist_free(it->item->deco_it_contents);
6146 it->item->deco_it_contents = NULL;
6148 if (GL_IT(it)->wsd->decorate_all_mode)
6150 elm_widget_stringlist_free(it->item->deco_all_texts);
6151 it->item->deco_all_texts = NULL;
6152 elm_widget_stringlist_free(it->item->deco_all_contents);
6153 it->item->deco_all_contents = NULL;
6156 elm_genlist_item_update(item);
6159 EAPI const Elm_Genlist_Item_Class *
6160 elm_genlist_item_item_class_get(const Elm_Object_Item *item)
6162 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6163 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6167 static Evas_Object *
6168 _elm_genlist_item_label_create(void *data,
6169 Evas_Object *obj __UNUSED__,
6170 Evas_Object *tooltip,
6171 void *it __UNUSED__)
6173 Evas_Object *label = elm_label_add(tooltip);
6178 elm_object_style_set(label, "tooltip");
6179 elm_object_text_set(label, data);
6185 _elm_genlist_item_label_del_cb(void *data,
6186 Evas_Object *obj __UNUSED__,
6187 void *event_info __UNUSED__)
6189 eina_stringshare_del(data);
6193 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
6196 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6198 text = eina_stringshare_add(text);
6199 elm_genlist_item_tooltip_content_cb_set
6200 (it, _elm_genlist_item_label_create, text,
6201 _elm_genlist_item_label_del_cb);
6205 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
6206 Elm_Tooltip_Item_Content_Cb func,
6208 Evas_Smart_Cb del_cb)
6210 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6212 ELM_GENLIST_ITEM_CHECK_OR_GOTO(item, error);
6214 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
6217 if (it->tooltip.del_cb)
6218 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6220 it->tooltip.content_cb = func;
6221 it->tooltip.data = data;
6222 it->tooltip.del_cb = del_cb;
6226 elm_widget_item_tooltip_content_cb_set
6227 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
6228 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
6229 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
6235 if (del_cb) del_cb((void *)data, NULL, NULL);
6239 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
6241 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6243 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6245 if ((VIEW(it)) && (it->tooltip.content_cb))
6246 elm_widget_item_tooltip_unset(it);
6248 if (it->tooltip.del_cb)
6249 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6250 it->tooltip.del_cb = NULL;
6251 it->tooltip.content_cb = NULL;
6252 it->tooltip.data = NULL;
6253 it->tooltip.free_size = EINA_FALSE;
6254 if (it->tooltip.style)
6255 elm_genlist_item_tooltip_style_set(item, NULL);
6259 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
6262 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6264 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6266 eina_stringshare_replace(&it->tooltip.style, style);
6267 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
6271 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
6273 return elm_object_item_tooltip_style_get(it);
6277 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
6280 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6282 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
6284 it->tooltip.free_size = disable;
6285 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
6291 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
6293 return elm_object_tooltip_window_mode_get(VIEW(it));
6297 elm_genlist_item_cursor_set(Elm_Object_Item *item,
6300 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6302 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6303 eina_stringshare_replace(&it->mouse_cursor, cursor);
6304 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
6308 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
6310 return elm_widget_item_cursor_get(it);
6314 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
6316 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6318 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6320 if (!it->mouse_cursor) return;
6322 if (VIEW(it)) elm_widget_item_cursor_unset(it);
6324 eina_stringshare_del(it->mouse_cursor);
6325 it->mouse_cursor = NULL;
6329 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
6332 elm_widget_item_cursor_style_set(it, style);
6336 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
6338 return elm_widget_item_cursor_style_get(it);
6342 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
6343 Eina_Bool engine_only)
6345 elm_widget_item_cursor_engine_only_set(it, engine_only);
6349 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
6351 return elm_widget_item_cursor_engine_only_get(it);
6355 elm_genlist_item_index_get(const Elm_Object_Item *item)
6359 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6361 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, -1);
6363 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
6365 if (tmp == it) break;
6372 elm_genlist_mode_set(Evas_Object *obj,
6375 ELM_GENLIST_CHECK(obj);
6376 ELM_GENLIST_DATA_GET(obj, sd);
6378 if (sd->mode == mode) return;
6380 elm_layout_sizing_eval(obj);
6384 elm_genlist_mode_get(const Evas_Object *obj)
6386 ELM_GENLIST_CHECK(obj) ELM_LIST_LAST;
6387 ELM_GENLIST_DATA_GET(obj, sd);
6393 elm_genlist_bounce_set(Evas_Object *obj,
6397 ELM_GENLIST_CHECK(obj);
6398 ELM_GENLIST_DATA_GET(obj, sd);
6400 sd->h_bounce = !!h_bounce;
6401 sd->v_bounce = !!v_bounce;
6402 sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
6406 elm_genlist_bounce_get(const Evas_Object *obj,
6407 Eina_Bool *h_bounce,
6408 Eina_Bool *v_bounce)
6410 ELM_GENLIST_CHECK(obj);
6411 ELM_GENLIST_DATA_GET(obj, sd);
6413 if (h_bounce) *h_bounce = sd->h_bounce;
6414 if (v_bounce) *v_bounce = sd->v_bounce;
6418 elm_genlist_homogeneous_set(Evas_Object *obj,
6419 Eina_Bool homogeneous)
6421 ELM_GENLIST_CHECK(obj);
6422 ELM_GENLIST_DATA_GET(obj, sd);
6424 sd->homogeneous = !!homogeneous;
6428 elm_genlist_homogeneous_get(const Evas_Object *obj)
6430 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6431 ELM_GENLIST_DATA_GET(obj, sd);
6433 return sd->homogeneous;
6437 elm_genlist_block_count_set(Evas_Object *obj,
6440 ELM_GENLIST_CHECK(obj);
6441 ELM_GENLIST_DATA_GET(obj, sd);
6442 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
6444 sd->max_items_per_block = count;
6445 sd->item_cache_max = sd->max_items_per_block * 2;
6446 _item_cache_all_free(sd);
6450 elm_genlist_block_count_get(const Evas_Object *obj)
6452 ELM_GENLIST_CHECK(obj) 0;
6453 ELM_GENLIST_DATA_GET(obj, sd);
6455 return sd->max_items_per_block;
6459 elm_genlist_longpress_timeout_set(Evas_Object *obj,
6462 ELM_GENLIST_CHECK(obj);
6463 ELM_GENLIST_DATA_GET(obj, sd);
6465 sd->longpress_timeout = timeout;
6469 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
6471 ELM_GENLIST_CHECK(obj) 0;
6472 ELM_GENLIST_DATA_GET(obj, sd);
6474 return sd->longpress_timeout;
6478 elm_genlist_scroller_policy_set(Evas_Object *obj,
6479 Elm_Scroller_Policy policy_h,
6480 Elm_Scroller_Policy policy_v)
6482 ELM_GENLIST_CHECK(obj);
6483 ELM_GENLIST_DATA_GET(obj, sd);
6485 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
6486 (policy_v >= ELM_SCROLLER_POLICY_LAST))
6489 sd->s_iface->policy_set(obj, policy_h, policy_v);
6493 elm_genlist_scroller_policy_get(const Evas_Object *obj,
6494 Elm_Scroller_Policy *policy_h,
6495 Elm_Scroller_Policy *policy_v)
6497 Elm_Scroller_Policy s_policy_h, s_policy_v;
6499 ELM_GENLIST_CHECK(obj);
6500 ELM_GENLIST_DATA_GET(obj, sd);
6502 sd->s_iface->policy_get(obj, &s_policy_h, &s_policy_v);
6503 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
6504 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
6508 elm_genlist_realized_items_update(Evas_Object *obj)
6510 Eina_List *list, *l;
6511 Elm_Object_Item *it;
6513 ELM_GENLIST_CHECK(obj);
6515 list = elm_genlist_realized_items_get(obj);
6516 EINA_LIST_FOREACH(list, l, it)
6517 elm_genlist_item_update(it);
6521 elm_genlist_item_decorate_mode_set(Elm_Object_Item *item,
6522 const char *decorate_it_type,
6523 Eina_Bool decorate_it_set)
6525 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6526 Elm_Genlist_Smart_Data *sd;
6528 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6529 sd = GL_IT(it)->wsd;
6531 if (elm_widget_item_disabled_get(it)) return;
6532 if (!decorate_it_type) return;
6533 if (sd->decorate_all_mode) return;
6535 if ((sd->mode_item == it) &&
6536 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
6539 if (!it->itc->decorate_item_style) return;
6540 it->decorate_it_set = decorate_it_set;
6543 if (((sd->decorate_it_type)
6544 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
6545 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
6546 _decorate_item_unset(sd);
6548 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
6549 if (decorate_it_set) _decorate_item_set(it);
6553 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *item)
6555 Elm_Gen_Item *i = (Elm_Gen_Item *)item;
6557 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6558 return GL_IT(i)->wsd->decorate_it_type;
6561 EAPI Elm_Object_Item *
6562 elm_genlist_decorated_item_get(const Evas_Object *obj)
6564 ELM_GENLIST_CHECK(obj) NULL;
6565 ELM_GENLIST_DATA_GET(obj, sd);
6567 return (Elm_Object_Item *)sd->mode_item;
6571 elm_genlist_decorate_mode_get(const Evas_Object *obj)
6573 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6574 ELM_GENLIST_DATA_GET(obj, sd);
6576 return sd->decorate_all_mode;
6580 elm_genlist_decorate_mode_set(Evas_Object *obj,
6581 Eina_Bool decorated)
6584 Eina_List *list, *l;
6586 ELM_GENLIST_CHECK(obj);
6587 ELM_GENLIST_DATA_GET(obj, sd);
6589 decorated = !!decorated;
6590 if (sd->decorate_all_mode == decorated) return;
6591 // decorate_all_mode should be set first
6592 // because content_get func. will be called after this
6593 // and user can check whether deocrate_all_mode is enabeld.
6594 sd->decorate_all_mode = decorated;
6596 list = elm_genlist_realized_items_get(obj);
6597 if (!sd->decorate_all_mode)
6599 EINA_LIST_FOREACH(list, l, it)
6601 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6602 _decorate_all_item_unrealize(it);
6604 _item_cache_all_free(sd);
6608 EINA_LIST_FOREACH(list, l, it)
6610 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6612 if (it->itc->decorate_all_item_style)
6613 _decorate_all_item_realize(it, EINA_TRUE);
6617 #if GENLIST_FX_SUPPORT
6618 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
6620 if (sd->calc_job) ecore_job_del(sd->calc_job);
6621 sd->calc_job = ecore_job_add(_calc_job, sd);
6625 elm_genlist_reorder_mode_set(Evas_Object *obj,
6626 Eina_Bool reorder_mode)
6628 #if 1 // FIXME: difference from upstream
6629 Eina_List *list, *l;
6632 ELM_GENLIST_CHECK(obj);
6633 ELM_GENLIST_DATA_GET(obj, sd);
6635 if (sd->reorder_mode == !!reorder_mode) return;
6636 sd->reorder_mode = !!reorder_mode;
6637 #if 1 // FIXME: difference from upstream
6638 list = elm_genlist_realized_items_get(obj);
6639 EINA_LIST_FOREACH(list, l, it)
6641 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6643 if (sd->reorder_mode)
6644 edje_object_signal_emit
6645 (VIEW(it), "elm,state,reorder,mode_set", "elm");
6647 edje_object_signal_emit
6648 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
6650 if (sd->decorate_all_mode)
6652 if (sd->reorder_mode)
6653 edje_object_signal_emit
6654 (it->deco_all_view, "elm,state,reorder,mode_set", "elm");
6656 edje_object_signal_emit
6657 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
6660 eina_list_free(list);
6665 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6667 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6668 ELM_GENLIST_DATA_GET(obj, sd);
6670 return sd->reorder_mode;
6673 EAPI Elm_Genlist_Item_Type
6674 elm_genlist_item_type_get(const Elm_Object_Item *item)
6676 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6678 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_GENLIST_ITEM_MAX);
6680 return it->item->type;
6683 EAPI Elm_Genlist_Item_Class *
6684 elm_genlist_item_class_new(void)
6686 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
6687 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6689 itc->version = CLASS_ALLOCATED;
6691 itc->delete_me = EINA_FALSE;
6697 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6699 if (itc && (itc->version == CLASS_ALLOCATED))
6701 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6702 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6712 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6714 if (itc && (itc->version == CLASS_ALLOCATED))
6717 if (itc->refcount == 0) itc->refcount--;
6722 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6724 if (itc && (itc->version == CLASS_ALLOCATED))
6726 if (itc->refcount > 0) itc->refcount--;
6727 if (itc->delete_me && (!itc->refcount))
6728 elm_genlist_item_class_free(itc);
6733 elm_genlist_item_flip_set(Elm_Object_Item *item,
6736 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6737 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6738 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
6741 if (it->flipped == flip) return;
6743 it->item->unrealize_disabled = EINA_FALSE;
6747 _item_unrealize(it, EINA_FALSE);
6748 it->flipped = EINA_TRUE;
6749 it->item->nocache = EINA_TRUE;
6753 _item_unrealize(it, EINA_FALSE);
6754 it->flipped = EINA_FALSE;
6755 it->item->nocache = EINA_FALSE;
6757 if (sd->calc_job) ecore_job_del(sd->calc_job);
6758 sd->calc_job = ecore_job_add(_calc_job, sd);
6762 elm_genlist_item_flip_get(const Elm_Object_Item *item)
6764 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6766 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
6772 elm_genlist_select_mode_set(Evas_Object *obj,
6773 Elm_Object_Select_Mode mode)
6775 ELM_GENLIST_CHECK(obj);
6776 ELM_GENLIST_DATA_GET(obj, sd);
6778 if (mode >= ELM_OBJECT_SELECT_MODE_MAX || (sd->select_mode == mode))
6781 sd->select_mode = mode;
6782 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
6783 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
6787 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it)
6792 EAPI Elm_Object_Select_Mode
6793 elm_genlist_select_mode_get(const Evas_Object *obj)
6795 ELM_GENLIST_CHECK(obj) ELM_OBJECT_SELECT_MODE_MAX;
6796 ELM_GENLIST_DATA_GET(obj, sd);
6798 return sd->select_mode;
6802 elm_genlist_highlight_mode_set(Evas_Object *obj,
6803 Eina_Bool highlight)
6805 ELM_GENLIST_CHECK(obj);
6806 ELM_GENLIST_DATA_GET(obj, sd);
6808 sd->highlight = !!highlight;
6812 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6814 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6815 ELM_GENLIST_DATA_GET(obj, sd);
6817 return sd->highlight;
6821 elm_genlist_item_select_mode_set(Elm_Object_Item *item,
6822 Elm_Object_Select_Mode mode)
6824 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6826 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6827 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6829 if (it->select_mode != mode)
6830 it->select_mode = mode;
6832 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
6833 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
6836 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6838 it->item->mincalcd = EINA_FALSE;
6839 it->item->updateme = EINA_TRUE;
6840 if (it->item->block) it->item->block->updateme = EINA_TRUE;
6841 if (GL_IT(it)->wsd->update_job)
6842 ecore_job_del(GL_IT(it)->wsd->update_job);
6843 GL_IT(it)->wsd->update_job =
6844 ecore_job_add(_update_job, GL_IT(it)->wsd);
6846 // reset homogeneous item size
6847 if (GL_IT(it)->wsd->homogeneous)
6850 GL_IT(it)->wsd->group_item_width =
6851 GL_IT(it)->wsd->group_item_height = 0;
6853 GL_IT(it)->wsd->item_width = GL_IT(it)->wsd->item_height = 0;
6858 EAPI Elm_Object_Select_Mode
6859 elm_genlist_item_select_mode_get(const Elm_Object_Item *item)
6861 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6863 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_OBJECT_SELECT_MODE_MAX);
6865 return it->select_mode;
6868 // will be deprecated
6870 elm_genlist_tree_effect_enabled_set(Evas_Object *obj __UNUSED__,
6871 Eina_Bool enabled __UNUSED__)
6873 ELM_GENLIST_CHECK(obj);
6876 // will be deprecated
6878 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj __UNUSED__)
6880 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6885 EAPI Elm_Object_Item *
6886 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
6888 Elm_Gen_Item *it = NULL;
6892 ELM_GENLIST_CHECK(obj) NULL;
6893 ELM_GENLIST_DATA_GET(obj, sd);
6895 if (!sd->items) return NULL;
6897 a = eina_inlist_accessor_new(sd->items);
6898 if (!a) return NULL;
6899 if (eina_accessor_data_get(a, nth, &data))
6900 it = ELM_GEN_ITEM_FROM_INLIST(data);
6901 eina_accessor_free(a);
6902 return (Elm_Object_Item *)it;
6905 #if GENLIST_FX_SUPPORT
6907 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
6909 ELM_GENLIST_CHECK(obj);
6910 ELM_GENLIST_DATA_GET(obj, sd);
6916 elm_genlist_fx_mode_get(const Evas_Object *obj)
6918 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6919 ELM_GENLIST_DATA_GET(obj, sd);
6925 _elm_genlist_proxy_item_del(const Elm_Object_Item *item)
6927 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6928 if ((!it) || (!it->item)) return;
6930 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
6934 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
6935 if (pi->it == it) pi->it = NULL;
6937 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
6938 if (pi->it == it) pi->it = NULL;
6942 _elm_genlist_proxy_item_new(const Elm_Object_Item *item)
6944 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6945 if ((!it) || (!it->item)) return EINA_FALSE;
6948 Proxy_Item *pi = NULL;
6949 pi = calloc(1, sizeof(Proxy_Item));
6950 if (!pi) return NULL;
6952 pi->proxy = evas_object_image_filled_add
6953 (evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
6959 evas_object_clip_set(pi->proxy, evas_object_clip_get(GL_IT(it)->wsd->pan_obj));
6960 evas_object_smart_member_add(pi->proxy, GL_IT(it)->wsd->pan_obj);
6961 evas_object_hide(pi->proxy);
6963 if ((GL_IT(it)->wsd->decorate_all_mode) && (it->deco_all_view))
6964 evas_object_image_source_set(pi->proxy, it->deco_all_view);
6966 evas_object_image_source_set(pi->proxy, VIEW(it));
6968 GL_IT(it)->has_proxy_it = EINA_TRUE;
6970 pi->num = it->item->num;
6971 pi->x = it->item->scrl_x;
6972 pi->y = it->item->scrl_y;
6973 pi->w = it->item->w;
6974 pi->h = it->item->h;
6976 evas_object_geometry_get(VIEW(it), NULL, NULL, &w, &h);
6978 if (w <= 0 || h <= 0)
6980 evas_object_size_hint_min_get(VIEW(it), &w, &h);
6981 evas_object_size_hint_min_set(pi->proxy, w, h);
6983 else evas_object_resize(pi->proxy, w, h);
6989 _elm_genlist_fx_capture(Evas_Object *obj, int level)
6991 ELM_GENLIST_DATA_GET(obj, sd);
6995 Eina_Bool done = EINA_FALSE;
6998 Evas_Coord ox, oy, ow, oh;
7002 if ((!sd->rendered) || (sd->fx_playing)) return EINA_FALSE;
7003 if ((!level) && (sd->fx_first_captured)) return EINA_FALSE;
7004 if ((level) && (!sd->fx_first_captured)) return EINA_FALSE;
7006 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7010 sd->fx_first_captured = EINA_TRUE;
7011 EINA_LIST_FREE(sd->capture_before_items, pi)
7013 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
7014 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
7015 if (pi->proxy) evas_object_del(pi->proxy);
7021 EINA_LIST_FREE(sd->capture_after_items, pi)
7023 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
7024 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
7025 if (pi->proxy) evas_object_del(pi->proxy);
7029 EINA_INLIST_FOREACH(sd->blocks, itb)
7033 EINA_LIST_FOREACH(itb->items, l, it)
7035 if (it->realized && it->item->scrl_y >= oy)
7037 sd->realized_top_item = it;
7042 if (sd->realized_top_item) break;
7046 #if GENLIST_PINCH_ZOOM_SUPPORT
7047 if (sd->pinch_zoom_mode)
7049 EINA_INLIST_FOREACH(sd->blocks, itb)
7051 EINA_LIST_FOREACH(itb->items, l, it)
7054 if (IS_ROOT_PARENT_IT(it) && it->realized
7055 && (GL_IT(it)->scrl_y + GL_IT(it)->h >= oy && GL_IT(it)->scrl_y <= oy + oh))
7057 pi = _elm_genlist_proxy_item_new((Elm_Object_Item *)it);
7058 if (!level) sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
7059 else sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
7063 if ((sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT) && (level)) return EINA_TRUE;
7064 if ((sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND) && (!level)) return EINA_TRUE;
7068 EINA_INLIST_FOREACH(sd->blocks, itb)
7073 EINA_LIST_FOREACH(itb->items, l, it)
7075 #if GENLIST_PINCH_ZOOM_SUPPORT
7076 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7080 pi = _elm_genlist_proxy_item_new((Elm_Object_Item *)it);
7083 sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
7085 sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
7089 else if (done) break;
7094 static Elm_Gen_FX_Item *
7095 _elm_genlist_fx_item_find(const Elm_Object_Item *item)
7097 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
7098 if (!it) return EINA_FALSE;
7100 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
7101 if (!sd) return NULL;
7103 Elm_Gen_FX_Item *fi = NULL;
7106 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7108 if (fi->it == it) return fi;
7113 static Elm_Gen_FX_Item *
7114 _elm_genlist_fx_item_new(const Proxy_Item *pi)
7116 if ((!pi) || (!pi->it)) return NULL;
7118 Elm_Gen_FX_Item *fi = NULL;
7119 fi = calloc(1, sizeof(Elm_Gen_FX_Item));
7120 if (!fi) return NULL;
7123 GL_IT(fi->it)->fi = fi;
7124 fi->proxy = pi->proxy;
7126 fi->from.x = fi->to.x = pi->x;
7127 fi->from.y = fi->to.y = pi->y;
7128 fi->from.w = fi->to.w = pi->w;
7129 fi->from.h = fi->to.h = pi->h;
7130 fi->update = EINA_FALSE;
7135 static Elm_Object_Item *
7136 _elm_genlist_fx_item_prev_get(const Elm_Object_Item *item)
7139 it = (Elm_Gen_Item *)item;
7140 if (!it) return NULL;
7141 if (GL_IT(it)->wsd->pinch_zoom_mode) return NULL;
7145 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7149 return (Elm_Object_Item *)it;
7153 _elm_genlist_fx_items_make(Evas_Object *obj)
7155 ELM_GENLIST_CHECK(obj) EINA_FALSE;
7156 ELM_GENLIST_DATA_GET(obj, sd);
7158 Elm_Gen_FX_Item *fi;
7161 Elm_Gen_Item *prev = NULL;
7162 Evas_Coord ox, oy, ow, oh, mv_dist, max_mv_dist = 0;
7164 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7166 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7168 fi = _elm_genlist_fx_item_new(pi);
7169 if (fi) sd->fx_items = eina_list_append(sd->fx_items, fi);
7172 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
7174 fi = _elm_genlist_fx_item_find((Elm_Object_Item *)pi->it);
7176 if (fi) // pi exists in both before and after capture items
7178 fi->type = ELM_GEN_ITEM_FX_TYPE_SAME;
7179 fi->update = EINA_TRUE;
7185 // find the max distance between before and after capture items
7186 mv_dist = abs(fi->to.y - fi->from.y);
7187 if (max_mv_dist < mv_dist) max_mv_dist = mv_dist;
7189 else // pi only exists in after capture items
7191 fi = _elm_genlist_fx_item_new(pi);
7194 fi->type = ELM_GEN_ITEM_FX_TYPE_ADD;
7195 fi->update = EINA_TRUE;
7196 sd->fx_items = eina_list_append(sd->fx_items, fi);
7201 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7203 // find deleted items
7204 if (!fi->update) // pi only exists in before capture items
7206 fi->type = ELM_GEN_ITEM_FX_TYPE_DEL;
7207 fi->update = EINA_TRUE;
7209 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7210 if ((prev) && (GL_IT(prev)->fi))
7212 fi->to.y = GL_IT(prev)->fi->to.y + GL_IT(prev)->fi->to.h;
7215 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7217 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7218 if ((prev) && (prev->realized) && (GL_IT(prev)->fi))
7220 fi->from.y = GL_IT(prev)->fi->from.y + GL_IT(prev)->fi->from.h;
7224 if (sd->realized_top_item)
7227 if (fi->num <= sd->realized_top_item->item->num)
7228 fi->from.y -= max_mv_dist;
7230 fi->from.y += max_mv_dist;
7236 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7238 if ((GL_IT(fi->it)->items) && (GL_IT(fi->it)->expanded_depth == 0))
7240 #if GENLIST_PINCH_ZOOM_SUPPORT
7241 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7243 fi->from.y = oy + GL_IT(fi->it)->pan_scrl_y - sd->pinch_pan_y;
7246 if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7248 if (sd->realized_top_item)
7250 if (fi->num <= sd->realized_top_item->item->num)
7251 fi->to.y = oy - fi->from.h;
7262 static Elm_Gen_FX_Item *
7263 _fx_cover_item_get(const Elm_Gen_FX_Item *fi)
7265 Elm_Gen_FX_Item *cover_fi;
7267 if (!fi) return NULL;
7269 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7270 Evas_Coord ox, oy, ow, oh;
7271 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7273 EINA_LIST_FOREACH(sd->fx_items, l, cover_fi)
7275 if (fi == cover_fi) continue;
7276 if (sd->fx_items_deleted)
7278 if ((cover_fi->from.y >= oy+oh || cover_fi->from.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y > 0))
7283 if ((cover_fi->to.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y < 0))
7291 _item_fx_op(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__, double progress __UNUSED__)
7293 Elm_Gen_FX_Item *fi = data, *cover_it;
7294 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7295 Evas_Coord fi_ox, fi_oy, cover_it_ox, cover_it_oy, ox, oy, ow, oh;
7297 evas_object_show(VIEW(fi->it));
7298 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7299 evas_object_geometry_get(fi->proxy, &fi_ox, &fi_oy, NULL, NULL);
7300 evas_object_move(fi->proxy, ox, fi_oy);
7301 evas_object_show(fi->proxy);
7302 #if GENLIST_PINCH_ZOOM_SUPPORT
7303 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(fi->it))) evas_object_raise(fi->proxy);
7306 if ((!sd->expanded_next_item) || (sd->expanded_next_item == fi->it)) goto raise_event_block;
7307 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME) goto raise_event_block;
7309 // find the closest item that cover current item when deleting
7310 cover_it = _fx_cover_item_get(fi);
7313 evas_object_geometry_get(cover_it->proxy, &cover_it_ox, &cover_it_oy, NULL, NULL);
7315 if (sd->fx_items_deleted)
7318 && (fi_oy + fi->to.h >= cover_it_oy + cover_it->to.h ) && (fi->from.y < cover_it->from.y))
7319 evas_object_hide(fi->proxy);
7321 else if (cover_it_oy && (fi_oy >= cover_it_oy))
7322 evas_object_hide(fi->proxy);
7324 evas_object_show(fi->proxy);
7328 evas_object_raise(sd->alpha_bg);
7335 _item_fx_done(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__)
7337 Elm_Gen_FX_Item *fx_done_it = data;
7338 Elm_Genlist_Smart_Data *sd = GL_IT(fx_done_it->it)->wsd;
7340 if (!fx_done_it) return;
7341 if ((!fx_done_it->it) || (!sd)) return;
7343 evas_object_image_source_visible_set(fx_done_it->proxy, EINA_TRUE);
7344 evas_object_lower(fx_done_it->proxy);
7346 if ((sd->decorate_all_mode) && (fx_done_it->it->deco_all_view))
7347 evas_object_move(fx_done_it->it->deco_all_view, fx_done_it->to.x, fx_done_it->to.y);
7349 evas_object_move(VIEW(fx_done_it->it), fx_done_it->to.x, fx_done_it->to.y);
7350 GL_IT(fx_done_it->it)->has_proxy_it = EINA_FALSE;
7352 evas_object_clip_unset(fx_done_it->proxy);
7356 _item_fx_del_cb(void *data, Elm_Transit *transit __UNUSED__)
7358 Elm_Gen_FX_Item *fx_done_it = data;
7359 Elm_Gen_Item *it = NULL;
7360 Proxy_Item *pi = NULL;
7362 Elm_Genlist_Smart_Data *sd = GL_IT(fx_done_it->it)->wsd;
7364 if (!fx_done_it) return;
7365 if ((!fx_done_it->it) || (!sd)) return;
7367 sd->fx_items = eina_list_remove(sd->fx_items, fx_done_it);
7368 GL_IT(fx_done_it->it)->fi = NULL;
7371 if (!eina_list_count(sd->fx_items))
7373 EINA_LIST_FREE (sd->pending_unrealized_items, it)
7375 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7376 #if GENLIST_PINCH_ZOOM_SUPPORT
7377 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7379 _item_unrealize(it, EINA_FALSE);
7381 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
7383 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7384 #if GENLIST_PINCH_ZOOM_SUPPORT
7385 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7387 _decorate_all_item_unrealize(it);
7390 EINA_LIST_FREE (sd->pending_del_items, it)
7393 _elm_widget_item_free((Elm_Widget_Item *)it);
7396 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7397 evas_object_hide(pi->proxy);
7398 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
7399 evas_object_hide(pi->proxy);
7401 sd->fx_playing = EINA_FALSE;
7402 sd->sorting = EINA_FALSE;
7403 sd->fx_first_captured = EINA_FALSE;
7404 evas_object_hide(sd->alpha_bg);
7406 sd->realized_top_item = NULL;
7407 sd->pan_changed = EINA_TRUE;
7408 evas_object_smart_changed(sd->pan_obj);
7413 _sorting_effect_animator_cb(void *data)
7415 Elm_Genlist_Smart_Data *sd = data;
7416 Elm_Gen_FX_Item *fi;
7419 Evas_Coord ox, oy, ow, oh;
7420 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7422 sd->fx_timer = NULL;
7423 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7427 fi->changed = EINA_TRUE;
7428 evas_object_resize(fi->proxy, ow, fi->to.h);
7430 fi->trans = elm_transit_add();
7431 elm_transit_object_add(fi->trans, fi->proxy);
7432 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7433 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7435 elm_transit_effect_translation_add(fi->trans, fi->to.x, fi->to.y - 30 * elm_config_scale_get(), fi->to.x, fi->to.y);
7436 elm_transit_effect_color_add(fi->trans,0, 0, 0, 0, 255,255,255,255);
7438 elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
7439 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7440 elm_transit_duration_set(fi->trans,0.3);
7441 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7442 elm_transit_go(fi->trans);
7444 return ECORE_CALLBACK_RENEW;
7447 return ECORE_CALLBACK_CANCEL;
7451 _elm_genlist_fx_play(Evas_Object *obj)
7453 ELM_GENLIST_CHECK(obj);
7454 ELM_GENLIST_DATA_GET(obj, sd);
7456 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
7457 Elm_Gen_FX_Item *fi;
7460 if (!sd->fx_mode) return;
7462 EINA_LIST_FREE(sd->fx_items, fi)
7464 if (fi->trans) elm_transit_del(fi->trans);
7467 _item_cache_all_free(sd);
7469 _elm_genlist_fx_items_make(obj);
7470 if (!eina_list_count(sd->fx_items) || (sd->queue))
7472 _elm_genlist_fx_clear(obj, EINA_TRUE);
7476 sd->fx_playing = EINA_TRUE;
7478 if (!sd->alpha_bg) sd->alpha_bg = _tray_alpha_bg_create(obj);
7479 evas_object_show(sd->alpha_bg);
7481 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7482 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
7486 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7487 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7488 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
7489 sd->fx_timer = ecore_timer_add(0.05, _sorting_effect_animator_cb, sd);
7493 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7495 if (!fi->proxy) continue;
7497 if ((fi->from.y <= oy) || (fi->from.y + fi->from.h >= oy + oh))
7499 if ((sd->decorate_all_mode) && (fi->it->deco_all_view))
7500 evas_object_move(fi->it->deco_all_view, cvx, fi->to.y);
7502 evas_object_move(VIEW(fi->it), cvx, fi->to.y);
7504 else if ((fi->to.y <= oy) || (fi->to.y + fi->to.h >= oy + oh))
7506 if ((sd->decorate_all_mode) && (fi->it->deco_all_view))
7507 evas_object_move(fi->it->deco_all_view, cvx, fi->from.y);
7509 evas_object_move(VIEW(fi->it), cvx, fi->from.y);
7512 evas_object_resize(fi->proxy, ow, fi->to.h);
7513 evas_object_show(fi->proxy);
7515 fi->trans = elm_transit_add();
7516 elm_transit_object_add(fi->trans, fi->proxy);
7518 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7519 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7521 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME)
7523 evas_object_raise(fi->proxy);
7524 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7527 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7529 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7530 elm_transit_effect_color_add(fi->trans, 0, 0, 0, 0, 255, 255, 255, 255);
7531 if ((!sd->pinch_zoom_mode) && (!sd->expanded_item))
7532 elm_transit_effect_zoom_add(fi->trans, 0.8, 1.0);
7534 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7536 _item_unhighlight(fi->it);
7537 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7538 elm_transit_effect_color_add(fi->trans, 255, 255, 255, 255, 0, 0, 0, 0);
7539 if ((!sd->pinch_zoom_mode) && (!sd->expanded_item))
7540 elm_transit_effect_zoom_add(fi->trans, 1.0, 0.8);
7542 elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
7543 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7545 elm_transit_duration_set(fi->trans, FX_MOVE_TIME);
7546 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7547 elm_transit_go(fi->trans);
7552 #if GENLIST_PINCH_ZOOM_SUPPORT
7554 elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Elm_Gen_Pinch_Zoom_Mode mode)
7556 ELM_GENLIST_DATA_GET(obj, sd);
7561 Eina_Bool done = EINA_FALSE;
7563 if ((sd->queue) || (!sd->rendered)
7564 || (sd->queue_idle_enterer) || (!sd->fx_mode)) return EINA_FALSE;
7566 EINA_INLIST_FOREACH(sd->blocks, itb)
7568 EINA_LIST_FOREACH(itb->items, l, it)
7571 if (IS_ROOT_PARENT_IT(it))
7579 if (!done) return EINA_FALSE;
7581 sd->pinch_zoom_mode = mode;
7583 _item_cache_all_free(sd);
7584 _elm_genlist_fx_capture(obj, 0);
7586 sd->pinch_pan_y = sd->pan_y;
7588 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7589 sd->s_iface->content_region_show(obj, 0,0,0,0);
7591 sd->pan_changed = EINA_TRUE;
7592 evas_object_smart_changed(sd->pan_obj);
7599 eina_list_sort_merge(Eina_List *a, Eina_List *b, Eina_Compare_Cb func)
7601 Eina_List *first, *last;
7603 if (func(a->data, b->data) > 0)
7605 _item_move_after(a->data, b->data);
7606 a = (last = first = a)->next;
7610 b = (last = first = b)->next;
7613 if (func(a->data, b->data) > 0)
7615 _item_move_after(a->data, b->data);
7616 a = (last = last->next = a)->next;
7619 b = (last = last->next = b)->next;
7621 last->next = a ? a : b;
7627 elm_genlist_sort(Evas_Object *obj, Eina_Compare_Cb func)
7629 ELM_GENLIST_CHECK(obj) NULL;
7630 ELM_GENLIST_DATA_GET(obj, sd);
7631 Eina_List *list = NULL;
7632 Elm_Gen_Item *it, *next;
7633 unsigned int limit = 0, i = 0, n = 0;
7634 Eina_List *tail = NULL, *unsort = NULL, *stack[32], *prev = NULL;
7636 sd->sorting = EINA_TRUE;
7638 it = (Elm_Gen_Item*)elm_genlist_first_item_get(obj);
7641 list = eina_list_append(list, it);
7642 next = (Elm_Gen_Item*)elm_genlist_item_next_get((Elm_Object_Item *)it);
7650 limit = eina_list_count(list);
7654 (limit > list->accounting->count))
7655 limit = list->accounting->count;
7657 if (limit != list->accounting->count)
7659 unsort = eina_list_nth_list(list, limit);
7661 unsort->prev->next = NULL;
7666 unsigned int idx, tmp;
7668 Eina_List *a = tail;
7669 Eina_List *b = tail->next;
7679 if (func(a->data, b->data) > 0)
7680 ((stack[i++] = a)->next = b)->next = 0;
7682 ((stack[i++] = b)->next = a)->next = 0;
7685 for (idx = n ^ tmp; idx &= idx - 1; i--)
7686 stack[i - 2] = eina_list_sort_merge(stack[i - 2], stack[i - 1], func);
7690 stack[i - 1] = eina_list_sort_merge(stack[i - 1], stack[i], func);
7694 for (; stack[0]; stack[0] = stack[0]->next)
7696 stack[0]->prev = prev;
7703 tail->next = unsort;
7704 unsort->prev = tail;
7707 list->accounting->last = tail;
7709 if (!sd->fx_mode) sd->sorting = EINA_FALSE;
7710 if (sd->decorate_all_mode) sd->sorting = EINA_FALSE;
7711 sd->s_iface->content_region_show(obj, 0,0,0,0);
7712 sd->pan_changed = EINA_TRUE;
7713 evas_object_smart_changed(sd->pan_obj);