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 = 6 * 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);
2583 /* check item which displays more than half of its size */
2584 if (ELM_RECTS_INTERSECT
2585 (x + (w / 2), y + (h / 2), 0, 0, sx, sy, sw, sh))
2586 items = eina_list_append(items, it->base.access_obj);
2588 if (!it->base.access_order) continue;
2592 EINA_LIST_FOREACH(it->base.access_order, subl, subo)
2593 items = eina_list_append(items, subo);
2597 else if (done) break;
2600 return elm_widget_focus_list_next_get
2601 (obj, items, eina_list_data_get, dir, next);
2605 _mirrored_set(Evas_Object *obj,
2608 ELM_GENLIST_DATA_GET(obj, sd);
2610 sd->s_iface->mirrored_set(obj, rtl);
2614 _elm_genlist_smart_theme(Evas_Object *obj)
2618 ELM_GENLIST_DATA_GET(obj, sd);
2620 if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->theme(obj))
2623 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2624 _item_cache_all_free(sd);
2625 _mirrored_set(obj, elm_widget_mirrored_get(obj));
2628 // FIXME: difference from opensource
2629 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
2632 sd->item_width = sd->item_height = 0;
2633 sd->group_item_width = sd->group_item_height = 0;
2634 sd->minw = sd->minh = sd->realminw = 0;
2635 EINA_INLIST_FOREACH(sd->blocks, itb)
2640 if (itb->realized) _item_block_unrealize(itb);
2641 EINA_LIST_FOREACH(itb->items, l, it)
2642 it->item->mincalcd = EINA_FALSE;
2644 itb->changed = EINA_TRUE;
2646 if (sd->calc_job) ecore_job_del(sd->calc_job);
2647 sd->calc_job = NULL;
2648 elm_layout_sizing_eval(obj);
2649 sd->pan_changed = EINA_TRUE;
2650 evas_object_smart_changed(sd->pan_obj);
2651 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2652 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
2657 /* FIXME: take off later. maybe this show region coords belong in the
2658 * interface (new api functions, set/get)? */
2660 _show_region_hook(void *data,
2663 Evas_Coord x, y, w, h;
2665 ELM_GENLIST_DATA_GET(data, sd);
2667 elm_widget_show_region_get(obj, &x, &y, &w, &h);
2668 //x & y are screen coordinates, Add with pan coordinates
2671 sd->s_iface->content_region_show(obj, x, y, w, h);
2675 _elm_genlist_smart_translate(Evas_Object *obj)
2677 evas_object_smart_callback_call(obj, "language,changed", NULL);
2683 _item_highlight(Elm_Gen_Item *it)
2685 const char *selectraise;
2686 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2688 if (elm_widget_item_disabled_get(it)) return;
2689 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2690 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2691 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2692 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2695 if (!sd->highlight || it->highlighted) return;
2696 #if GENLIST_PINCH_ZOOM_SUPPORT
2697 if (sd->pinch_zoom_mode) return;
2700 selectraise = edje_object_data_get(VIEW(it), "selectraise");
2701 if ((selectraise) && (!strcmp(selectraise, "on")))
2703 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2704 else evas_object_raise(VIEW(it));
2705 if ((it->item->group_item) && (it->item->group_item->realized))
2706 evas_object_raise(it->item->VIEW(group_item));
2708 it->highlighted = EINA_TRUE;
2710 if (it->deco_all_view)
2711 edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
2712 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
2713 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
2717 _item_unhighlight(Elm_Gen_Item *it)
2719 if (!it->highlighted) return;
2721 if (!it->item->nostacking)
2723 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
2725 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
2726 else evas_object_lower(VIEW(it));
2730 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2731 else evas_object_raise(VIEW(it));
2734 it->highlighted = EINA_FALSE;
2736 if (it->deco_all_view)
2737 edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
2738 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
2739 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it);
2743 _item_unselect(Elm_Gen_Item *it)
2745 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2746 _item_unhighlight(it);
2747 if (!it->selected) return;
2749 it->selected = EINA_FALSE;
2750 sd->selected = eina_list_remove(sd->selected, it);
2751 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
2755 _item_select(Elm_Gen_Item *it)
2757 Evas_Object *obj = WIDGET(it);
2758 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2759 if (elm_widget_item_disabled_get(it)) return;
2760 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2761 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
2762 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2763 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
2766 #if GENLIST_PINCH_ZOOM_SUPPORT
2767 if (IS_ROOT_PARENT_IT(it) && (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
2769 elm_genlist_pinch_zoom_mode_set(obj, ELM_GEN_PINCH_ZOOM_EXPAND);
2770 elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
2776 // FIXME: difference from upstream
2777 if ((GL_IT(it)->wsd->last_selected_item) &&
2778 (it != (Elm_Gen_Item *) GL_IT(it)->wsd->last_selected_item))
2779 _item_unfocusable_set
2780 ((Elm_Gen_Item *)GL_IT(it)->wsd->last_selected_item, EINA_TRUE);
2783 // Do not check selected because always select mode can be used
2784 _item_highlight(it);
2785 it->selected = EINA_TRUE;
2786 sd->selected = eina_list_append(sd->selected, it);
2787 sd->last_selected_item = (Elm_Object_Item *)it;
2789 if (it->func.func) it->func.func((void *)it->func.data, obj, it);
2790 if (!EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC))
2792 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
2796 _item_select_unselect(Elm_Gen_Item *it, Eina_Bool selected)
2798 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2799 Evas_Object *obj = ELM_WIDGET_DATA(sd)->obj;
2800 if (elm_widget_item_disabled_get(it)) return;
2802 evas_object_ref(obj);
2805 const Eina_List *l, *ll;
2807 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
2808 if (it2 != it) _item_unselect(it2);
2810 if (selected) _item_select(it);
2811 else _item_unselect(it);
2812 evas_object_unref(obj);
2816 _item_block_position_update(Eina_Inlist *list,
2821 EINA_INLIST_FOREACH(list, tmp)
2823 tmp->position = idx++;
2824 tmp->position_update = EINA_TRUE;
2829 _item_position_update(Eina_List *list,
2835 EINA_LIST_FOREACH(list, l, it)
2837 it->position = idx++;
2838 it->position_update = EINA_TRUE;
2843 _item_block_merge(Item_Block *left,
2849 EINA_LIST_FOREACH(right->items, l, it2)
2851 it2->item->block = left;
2853 left->changed = EINA_TRUE;
2855 left->items = eina_list_merge(left->items, right->items);
2859 _item_block_del(Elm_Gen_Item *it)
2862 Item_Block *itb = it->item->block;
2863 Eina_Bool block_changed = EINA_FALSE;
2865 itb->items = eina_list_remove(itb->items, it);
2867 itb->changed = EINA_TRUE;
2868 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
2869 GL_IT(it)->wsd->calc_job = ecore_job_add(_calc_job, GL_IT(it)->wsd);
2874 il = EINA_INLIST_GET(itb);
2875 itbn = (Item_Block *)(il->next);
2877 it->parent->item->items =
2878 eina_list_remove(it->parent->item->items, it);
2881 _item_block_position_update(il->next, itb->position);
2883 GL_IT(it)->wsd->blocks =
2884 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
2887 if (itbn) itbn->changed = EINA_TRUE;
2891 if (itb->count < (itb->sd->max_items_per_block / 2))
2896 il = EINA_INLIST_GET(itb);
2897 itbp = (Item_Block *)(il->prev);
2898 itbn = (Item_Block *)(il->next);
2900 /* merge block with previous */
2902 ((itbp->count + itb->count) <
2903 (itb->sd->max_items_per_block +
2904 (itb->sd->max_items_per_block / 2))))
2906 _item_block_merge(itbp, itb);
2907 _item_block_position_update
2908 (EINA_INLIST_GET(itb)->next, itb->position);
2909 GL_IT(it)->wsd->blocks = eina_inlist_remove
2910 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
2912 block_changed = EINA_TRUE;
2914 /* merge block with next */
2916 ((itbn->count + itb->count) <
2917 (itb->sd->max_items_per_block +
2918 (itb->sd->max_items_per_block / 2))))
2920 _item_block_merge(itb, itbn);
2921 _item_block_position_update
2922 (EINA_INLIST_GET(itbn)->next, itbn->position);
2923 GL_IT(it)->wsd->blocks =
2924 eina_inlist_remove(GL_IT(it)->wsd->blocks,
2925 EINA_INLIST_GET(itbn));
2927 block_changed = EINA_TRUE;
2934 GL_IT(it)->wsd->pan_changed = EINA_TRUE;
2935 evas_object_smart_changed(GL_IT(it)->wsd->pan_obj);
2936 if (GL_IT(it)->wsd->calc_job) ecore_job_del(GL_IT(it)->wsd->calc_job);
2937 GL_IT(it)->wsd->calc_job = NULL;
2939 #if GENLIST_FX_SUPPORT
2940 it->item->block = NULL;
2945 _decorate_all_item_unrealize(Elm_Gen_Item *it)
2949 if ((!it) || (!it->item->decorate_all_item_realized)) return;
2951 #if GENLIST_FX_SUPPORT
2952 if ((GL_IT(it)->has_proxy_it) && (!GL_IT(it)->wsd->genlist_clearing))
2954 if (!eina_list_data_find(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it))
2955 GL_IT(it)->wsd->pending_unrealized_decorate_all_items =
2956 eina_list_append(GL_IT(it)->wsd->pending_unrealized_decorate_all_items, it);
2961 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
2962 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
2963 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2964 _elm_genlist_item_odd_even_update(it);
2965 _elm_genlist_item_state_update(it);
2967 edje_object_signal_emit
2968 (it->deco_all_view, "elm,state,decorate,disabled", "elm");
2969 edje_object_signal_emit
2970 (VIEW(it), "elm,state,decorate,disabled", "elm");
2971 edje_object_signal_emit
2972 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
2973 edje_object_message_signal_process(VIEW(it));
2974 edje_object_message_signal_process(it->deco_all_view);
2976 evas_object_del(it->deco_all_view);
2977 it->deco_all_view = NULL;
2978 elm_widget_stringlist_free(it->item->deco_all_texts);
2979 it->item->deco_all_texts = NULL;
2980 elm_widget_stringlist_free(it->item->deco_all_contents);
2981 it->item->deco_all_contents = NULL;
2982 elm_widget_stringlist_free(it->item->deco_all_states);
2983 it->item->deco_all_states = NULL;
2984 EINA_LIST_FREE (it->item->deco_all_content_objs, icon)
2985 evas_object_del(icon);
2987 _item_mouse_callbacks_del(it, it->deco_all_view);
2988 _item_mouse_callbacks_add(it, VIEW(it));
2990 it->item->decorate_all_item_realized = EINA_FALSE;
2994 _item_free_common(Elm_Gen_Item *it)
2996 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
2997 elm_widget_item_pre_notify_del(it);
2998 if (it->itc->func.del)
2999 it->itc->func.del((void *)it->base.data, WIDGET(it));
3000 if (it->tooltip.del_cb)
3001 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
3002 if (it->item->block) _item_block_del(it);
3004 it->parent->item->items =
3005 eina_list_remove(it->parent->item->items, it);
3006 if (it->item->queued) sd->queue = eina_list_remove(sd->queue, it);
3007 if (it->group) sd->group_items = eina_list_remove(sd->group_items, it);
3009 // FIXME: relative will be better to be fixed. it is too harsh.
3011 it->item->rel->item->rel_revs =
3012 eina_list_remove(it->item->rel->item->rel_revs, it);
3013 if (it->item->rel_revs)
3016 EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
3018 _item_sub_items_clear(it);
3020 #if GENLIST_ENTRY_SUPPORT
3021 it->item->unrealize_disabled = EINA_FALSE;
3024 if (it->selected) sd->selected = eina_list_remove(sd->selected, it);
3025 if (sd->show_item == it) sd->show_item = NULL;
3026 if (sd->anchor_item == it)
3029 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3030 if (!sd->anchor_item) sd->anchor_item =
3031 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3033 if (sd->expanded_item == it) sd->expanded_item = NULL;
3034 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3035 if (sd->state) eina_inlist_sorted_state_free(sd->state);
3037 if (sd->last_selected_item == (Elm_Object_Item *)it)
3038 sd->last_selected_item = NULL;
3042 ecore_timer_del(it->long_timer);
3043 it->long_timer = NULL;
3045 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
3047 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3052 _item_mouse_move_cb(void *data,
3053 Evas *evas __UNUSED__,
3057 EINA_SAFETY_ON_NULL_RETURN(data);
3058 Elm_Gen_Item *it = data;
3059 Elm_Genlist_Smart_Data *sd;
3060 Evas_Event_Mouse_Move *ev = event_info;
3061 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
3062 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
3064 sd = GL_IT(it)->wsd;
3066 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3068 if (!sd->on_hold) _item_unselect(it);
3069 sd->on_hold = EINA_TRUE;
3071 if (sd->multi_touched)
3073 sd->cur_x = ev->cur.canvas.x;
3074 sd->cur_y = ev->cur.canvas.y;
3077 if ((it->dragging) && (it->down))
3079 if (sd->movements == SWIPE_MOVES)
3080 sd->swipe = EINA_TRUE;
3083 sd->history[sd->movements].x = ev->cur.canvas.x;
3084 sd->history[sd->movements].y = ev->cur.canvas.y;
3085 if (abs((sd->history[sd->movements].x -
3086 sd->history[0].x)) > 40)
3087 sd->swipe = EINA_TRUE;
3093 ecore_timer_del(it->long_timer);
3094 it->long_timer = NULL;
3096 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
3099 if ((!it->down) || (sd->longpressed))
3103 ecore_timer_del(it->long_timer);
3104 it->long_timer = NULL;
3106 if ((sd->reorder_mode) && (sd->reorder_it))
3108 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3110 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
3111 sd->reorder_fast = 1;
3112 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
3113 sd->reorder_fast = -1;
3114 else sd->reorder_fast = 0;
3116 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
3118 if (!sd->reorder_start_y)
3119 sd->reorder_start_y = it->item->block->y + it->y;
3123 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
3124 y_pos = oy + oh - sd->reorder_it->item->h;
3128 if (it->deco_all_view)
3129 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
3130 else if (it->item->deco_it_view)
3132 (it, it->item->deco_it_view, it->item->scrl_x, y_pos);
3134 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
3136 if (sd->calc_job) ecore_job_del(sd->calc_job);
3137 sd->calc_job = ecore_job_add(_calc_job, sd);
3141 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3142 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3144 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3145 x = ev->cur.canvas.x - x;
3146 y = ev->cur.canvas.y - y;
3149 if (adx < 0) adx = -dx;
3153 if (ady < 0) ady = -dy;
3157 if ((adx > minw) || (ady > minh))
3159 it->dragging = EINA_TRUE;
3162 ecore_timer_del(it->long_timer);
3163 it->long_timer = NULL;
3168 evas_object_smart_callback_call
3169 (WIDGET(it), SIG_DRAG_START_UP, it);
3173 evas_object_smart_callback_call
3174 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3176 evas_object_smart_callback_call
3177 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3183 evas_object_smart_callback_call
3184 (WIDGET(it), SIG_DRAG_START_DOWN, it);
3188 evas_object_smart_callback_call
3189 (WIDGET(it), SIG_DRAG_START_LEFT, it);
3191 evas_object_smart_callback_call
3192 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
3199 _long_press_cb(void *data)
3201 Elm_Gen_Item *it = data, *it2;
3202 Elm_Genlist_Smart_Data *sd;
3205 sd = GL_IT(it)->wsd;
3207 it->long_timer = NULL;
3208 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
3209 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3210 return ECORE_CALLBACK_CANCEL;
3212 GL_IT(it)->wsd->longpressed = EINA_TRUE;
3213 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
3214 if ((GL_IT(it)->wsd->reorder_mode) && (!it->group))
3216 GL_IT(it)->wsd->reorder_it = it;
3217 GL_IT(it)->wsd->reorder_start_y = 0;
3218 if (it->deco_all_view)
3219 evas_object_raise(it->deco_all_view);
3221 evas_object_raise(VIEW(it));
3223 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
3224 sd->s_iface->bounce_allow_set
3225 (ELM_WIDGET_DATA(sd)->obj, EINA_FALSE, EINA_FALSE);
3227 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
3229 if (it != it2) _item_unselect(it2);
3232 // FIXME: difference from opensource
3233 if (it->item->items)
3235 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
3237 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
3239 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
3241 return ECORE_CALLBACK_RENEW;
3246 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
3248 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
3249 return ECORE_CALLBACK_RENEW;
3252 if (!GL_IT(it)->wsd->decorate_all_mode)
3253 edje_object_signal_emit
3254 (VIEW(it), "elm,state,reorder,enabled", "elm");
3257 return ECORE_CALLBACK_CANCEL;
3261 _swipe_do(Elm_Gen_Item *it)
3266 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3267 elm_widget_item_disabled_get(it)) return;
3269 GL_IT(it)->wsd->swipe = EINA_FALSE;
3270 for (i = 0; i < GL_IT(it)->wsd->movements; i++)
3272 sum += GL_IT(it)->wsd->history[i].x;
3273 if (abs(GL_IT(it)->wsd->history[0].y -
3274 GL_IT(it)->wsd->history[i].y) > 10) return;
3277 sum /= GL_IT(it)->wsd->movements;
3278 if (abs(sum - GL_IT(it)->wsd->history[0].x) <= 10) return;
3279 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
3283 _swipe_cancel(void *data)
3285 Elm_Gen_Item *it = data;
3287 if (!it) return ECORE_CALLBACK_CANCEL;
3288 GL_IT(it)->wsd->swipe = EINA_FALSE;
3289 GL_IT(it)->wsd->movements = 0;
3291 return ECORE_CALLBACK_RENEW;
3295 _multi_cancel(void *data)
3297 Elm_Genlist_Smart_Data *sd = data;
3299 if (!sd) return ECORE_CALLBACK_CANCEL;
3300 sd->multi_timeout = EINA_TRUE;
3302 return ECORE_CALLBACK_RENEW;
3306 _multi_touch_gesture_eval(void *data)
3308 Elm_Gen_Item *it = data;
3309 Evas_Coord minw = 0, minh = 0;
3310 Evas_Coord off_x, off_y, off_mx, off_my;
3312 GL_IT(it)->wsd->multi_touched = EINA_FALSE;
3313 if (GL_IT(it)->wsd->multi_timer)
3315 ecore_timer_del(GL_IT(it)->wsd->multi_timer);
3316 GL_IT(it)->wsd->multi_timer = NULL;
3318 if (GL_IT(it)->wsd->multi_timeout)
3320 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3324 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3325 off_x = abs(GL_IT(it)->wsd->cur_x - GL_IT(it)->wsd->prev_x);
3326 off_y = abs(GL_IT(it)->wsd->cur_y - GL_IT(it)->wsd->prev_y);
3327 off_mx = abs(GL_IT(it)->wsd->cur_mx - GL_IT(it)->wsd->prev_mx);
3328 off_my = abs(GL_IT(it)->wsd->cur_my - GL_IT(it)->wsd->prev_my);
3330 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
3331 || (off_my > minh)))
3333 if ((off_x + off_mx) > (off_y + off_my))
3335 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_RIGHT, it);
3339 else if ((GL_IT(it)->wsd->cur_x < GL_IT(it)->wsd->prev_x)
3340 && (GL_IT(it)->wsd->cur_mx < GL_IT(it)->wsd->prev_mx))
3341 evas_object_smart_callback_call
3342 (WIDGET(it), SIG_MULTI_SWIPE_LEFT, it);
3343 else if (abs(GL_IT(it)->wsd->cur_x - GL_IT(it)->wsd->cur_mx) >
3344 abs(GL_IT(it)->wsd->prev_x - GL_IT(it)->wsd->prev_mx))
3345 evas_object_smart_callback_call
3346 (WIDGET(it), SIG_MULTI_PINCH_OUT, it);
3348 evas_object_smart_callback_call
3349 (WIDGET(it), SIG_MULTI_PINCH_IN, it);
3353 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_DOWN, it);
3357 else if ((GL_IT(it)->wsd->cur_y < GL_IT(it)->wsd->prev_y)
3358 && (GL_IT(it)->wsd->cur_my < GL_IT(it)->wsd->prev_my))
3359 evas_object_smart_callback_call
3360 (WIDGET(it), SIG_MULTI_SWIPE_UP, it);
3361 else if (abs(GL_IT(it)->wsd->cur_y - GL_IT(it)->wsd->cur_my) >
3362 abs(GL_IT(it)->wsd->prev_y - GL_IT(it)->wsd->prev_my))
3364 evas_object_smart_callback_call
3365 (WIDGET(it), SIG_MULTI_PINCH_OUT, it);
3366 #if GENLIST_PINCH_ZOOM_SUPPORT
3367 if (IS_ROOT_PARENT_IT(it) && (GL_IT(it)->wsd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
3369 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj, ELM_GEN_PINCH_ZOOM_EXPAND);
3370 elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
3376 evas_object_smart_callback_call
3377 (WIDGET(it), SIG_MULTI_PINCH_IN, it);
3378 #if GENLIST_PINCH_ZOOM_SUPPORT
3379 elm_genlist_pinch_zoom_mode_set(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj,
3380 ELM_GEN_PINCH_ZOOM_CONTRACT);
3386 GL_IT(it)->wsd->multi_timeout = EINA_FALSE;
3390 _item_multi_down_cb(void *data,
3391 Evas *evas __UNUSED__,
3392 Evas_Object *obj __UNUSED__,
3395 Elm_Gen_Item *it = data;
3396 Evas_Event_Multi_Down *ev = event_info;
3398 if ((GL_IT(it)->wsd->multi_device != 0) || (GL_IT(it)->wsd->multi_touched)
3399 || (GL_IT(it)->wsd->multi_timeout))
3402 GL_IT(it)->wsd->multi_device = ev->device;
3403 GL_IT(it)->wsd->multi_down = EINA_TRUE;
3404 GL_IT(it)->wsd->multi_touched = EINA_TRUE;
3405 GL_IT(it)->wsd->prev_mx = ev->canvas.x;
3406 GL_IT(it)->wsd->prev_my = ev->canvas.y;
3408 if (!GL_IT(it)->wsd->wasselected)
3410 GL_IT(it)->wsd->wasselected = EINA_FALSE;
3414 ecore_timer_del(it->long_timer);
3415 it->long_timer = NULL;
3419 it->dragging = EINA_FALSE;
3420 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
3422 if (it->item->swipe_timer)
3424 ecore_timer_del(it->item->swipe_timer);
3425 it->item->swipe_timer = NULL;
3427 GL_IT(it)->wsd->longpressed = EINA_FALSE;
3428 if (GL_IT(it)->wsd->on_hold)
3430 GL_IT(it)->wsd->swipe = EINA_FALSE;
3431 GL_IT(it)->wsd->movements = 0;
3432 GL_IT(it)->wsd->on_hold = EINA_FALSE;
3437 _item_multi_up_cb(void *data,
3438 Evas *evas __UNUSED__,
3439 Evas_Object *obj __UNUSED__,
3442 Elm_Gen_Item *it = data;
3443 Evas_Event_Multi_Up *ev = event_info;
3445 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3446 GL_IT(it)->wsd->multi_device = 0;
3447 GL_IT(it)->wsd->multi_down = EINA_FALSE;
3448 if (GL_IT(it)->wsd->mouse_down) return;
3449 _multi_touch_gesture_eval(data);
3453 _item_multi_move_cb(void *data,
3454 Evas *evas __UNUSED__,
3455 Evas_Object *obj __UNUSED__,
3458 Elm_Gen_Item *it = data;
3459 Evas_Event_Multi_Move *ev = event_info;
3461 if (GL_IT(it)->wsd->multi_device != ev->device) return;
3462 GL_IT(it)->wsd->cur_mx = ev->cur.canvas.x;
3463 GL_IT(it)->wsd->cur_my = ev->cur.canvas.y;
3467 // FIXME: difference from upstream
3469 _item_unfocusable_set(Elm_Gen_Item *it, Eina_Bool unfocus)
3472 Evas_Object *item_obj;
3473 Evas_Object *obj = WIDGET(it);
3477 EINA_LIST_FOREACH(it->content_objs, l, item_obj)
3479 if (unfocus) elm_widget_focused_object_clear(item_obj);
3480 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3482 EINA_LIST_FOREACH(it->item->flip_content_objs, l, item_obj)
3484 if (unfocus) elm_widget_focused_object_clear(item_obj);
3485 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3487 EINA_LIST_FOREACH(it->item->deco_all_content_objs, l, item_obj)
3489 if (unfocus) elm_widget_focused_object_clear(item_obj);
3490 elm_widget_tree_unfocusable_set(item_obj, unfocus);
3492 it->can_focus = !unfocus;
3498 _item_mouse_down_cb(void *data,
3499 Evas *evas __UNUSED__,
3503 Evas_Event_Mouse_Down *ev = event_info;
3504 Elm_Gen_Item *it = data;
3505 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
3508 if (ev->button != 1) return;
3510 _item_unfocusable_set(it, EINA_FALSE);
3512 it->down = EINA_TRUE;
3513 it->dragging = EINA_FALSE;
3514 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3515 it->dx = ev->canvas.x - x;
3516 it->dy = ev->canvas.y - y;
3517 sd->mouse_down = EINA_TRUE;
3518 if (!sd->multi_touched)
3520 sd->prev_x = ev->canvas.x;
3521 sd->prev_y = ev->canvas.y;
3522 sd->multi_timeout = EINA_FALSE;
3523 if (sd->multi_timer) ecore_timer_del(sd->multi_timer);
3524 sd->multi_timer = ecore_timer_add(1, _multi_cancel, sd);
3526 sd->longpressed = EINA_FALSE;
3527 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3529 sd->on_hold = EINA_TRUE;
3532 else sd->on_hold = EINA_FALSE;
3533 _item_highlight(it);
3534 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
3535 if ((!elm_widget_item_disabled_get(it)) &&
3536 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3538 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
3539 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
3541 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
3542 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
3543 if (it->long_timer) ecore_timer_del(it->long_timer);
3545 it->long_timer = ecore_timer_add
3546 (sd->longpress_timeout, _long_press_cb, it);
3548 it->long_timer = NULL;
3549 sd->swipe = EINA_FALSE;
3554 _item_block_new(Elm_Genlist_Smart_Data *sd,
3559 itb = calloc(1, sizeof(Item_Block));
3560 if (!itb) return NULL;
3564 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
3565 _item_block_position_update(sd->blocks, 0);
3569 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3570 itb->position_update = EINA_TRUE;
3571 if (sd->blocks != EINA_INLIST_GET(itb))
3574 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
3586 _item_block_add(Elm_Genlist_Smart_Data *sd,
3589 Item_Block *itb = NULL;
3596 itb = calloc(1, sizeof(Item_Block));
3597 if (!itb) return EINA_FALSE;
3599 if (!it->item->rel->item->block)
3602 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
3603 itb->items = eina_list_append(itb->items, it);
3604 itb->position_update = EINA_TRUE;
3605 it->position = eina_list_count(itb->items);
3606 it->position_update = EINA_TRUE;
3608 if (sd->blocks != EINA_INLIST_GET(itb))
3612 (EINA_INLIST_GET(itb)->prev))->position + 1;
3623 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3624 if (it->item->before)
3626 sd->blocks = eina_inlist_prepend_relative
3627 (sd->blocks, EINA_INLIST_GET(itb),
3628 EINA_INLIST_GET(it->item->rel->item->block));
3630 eina_list_prepend_relative_list(itb->items, it, tmp);
3632 /* Update index from where we prepended */
3633 _item_position_update
3634 (eina_list_prev(tmp), it->item->rel->position);
3635 _item_block_position_update
3636 (EINA_INLIST_GET(itb),
3637 it->item->rel->item->block->position);
3641 sd->blocks = eina_inlist_append_relative
3642 (sd->blocks, EINA_INLIST_GET(itb),
3643 EINA_INLIST_GET(it->item->rel->item->block));
3645 eina_list_append_relative_list(itb->items, it, tmp);
3647 /* Update block index from where we appended */
3648 _item_position_update
3649 (eina_list_next(tmp), it->item->rel->position + 1);
3650 _item_block_position_update
3651 (EINA_INLIST_GET(itb),
3652 it->item->rel->item->block->position + 1);
3658 if (it->item->before)
3662 itb = (Item_Block *)(sd->blocks);
3663 if (itb->count >= sd->max_items_per_block)
3665 itb = _item_block_new(sd, EINA_TRUE);
3666 if (!itb) return EINA_FALSE;
3671 itb = _item_block_new(sd, EINA_TRUE);
3672 if (!itb) return EINA_FALSE;
3674 itb->items = eina_list_prepend(itb->items, it);
3676 _item_position_update(itb->items, 0);
3682 itb = (Item_Block *)(sd->blocks->last);
3683 if (itb->count >= sd->max_items_per_block)
3685 itb = _item_block_new(sd, EINA_FALSE);
3686 if (!itb) return EINA_FALSE;
3691 itb = _item_block_new(sd, EINA_FALSE);
3692 if (!itb) return EINA_FALSE;
3694 itb->items = eina_list_append(itb->items, it);
3695 it->position = eina_list_count(itb->items);
3703 if (it->item->rel->item->queued)
3705 /* NOTE: for a strange reason eina_list and eina_inlist
3706 don't have the same property on sorted insertion
3707 order, so the queue is not always ordered like the
3708 item list. This lead to issue where we depend on an
3709 item that is not yet created. As a quick work around,
3710 we reschedule the calc of the item and stop reordering
3711 the list to prevent any nasty issue to show up here.
3713 sd->queue = eina_list_append(sd->queue, it);
3714 sd->requeued = EINA_TRUE;
3715 it->item->queued = EINA_TRUE;
3719 itb = it->item->rel->item->block;
3720 if (!itb) goto newblock;
3721 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3722 if (it->item->before)
3724 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3725 _item_position_update
3726 (eina_list_prev(tmp), it->item->rel->position);
3730 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3731 _item_position_update
3732 (eina_list_next(tmp), it->item->rel->position + 1);
3737 itb->changed = EINA_TRUE;
3738 it->item->block = itb;
3739 if (itb->sd->calc_job) ecore_job_del(itb->sd->calc_job);
3740 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd);
3742 if (itb->count > itb->sd->max_items_per_block)
3747 Eina_Bool done = EINA_FALSE;
3749 newc = itb->count / 2;
3751 if (EINA_INLIST_GET(itb)->prev)
3753 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3755 if (itbp->count + newc < sd->max_items_per_block / 2)
3757 /* moving items to previous block */
3758 while ((itb->count > newc) && (itb->items))
3760 it2 = eina_list_data_get(itb->items);
3761 itb->items = eina_list_remove_list
3762 (itb->items, itb->items);
3765 itbp->items = eina_list_append(itbp->items, it2);
3766 it2->item->block = itbp;
3774 if (!done && EINA_INLIST_GET(itb)->next)
3776 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3778 if (itbn->count + newc < sd->max_items_per_block / 2)
3780 /* moving items to next block */
3781 while ((itb->count > newc) && (itb->items))
3785 l = eina_list_last(itb->items);
3786 it2 = eina_list_data_get(l);
3787 itb->items = eina_list_remove_list(itb->items, l);
3790 itbn->items = eina_list_prepend(itbn->items, it2);
3791 it2->item->block = itbn;
3801 /* moving items to new block */
3802 itb2 = calloc(1, sizeof(Item_Block));
3803 if (!itb2) return EINA_FALSE;
3806 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
3807 EINA_INLIST_GET(itb));
3808 itb2->changed = EINA_TRUE;
3809 while ((itb->count > newc) && (itb->items))
3813 l = eina_list_last(itb->items);
3815 itb->items = eina_list_remove_list(itb->items, l);
3818 itb2->items = eina_list_prepend(itb2->items, it2);
3819 it2->item->block = itb2;
3829 _item_process(Elm_Genlist_Smart_Data *sd,
3832 if (!_item_block_add(sd, it)) return 1;
3834 _item_block_realize(it->item->block);
3840 _item_process_post(Elm_Genlist_Smart_Data *sd,
3844 Eina_Bool show_me = EINA_FALSE;
3846 if (it->item->block->changed)
3848 show_me = _item_block_recalc
3849 (it->item->block, it->item->block->num, qadd);
3850 it->item->block->changed = 0;
3851 if (sd->pan_changed)
3853 if (sd->calc_job) ecore_job_del(sd->calc_job);
3854 sd->calc_job = NULL;
3856 sd->pan_changed = EINA_FALSE;
3859 if (show_me) it->item->block->show_me = EINA_TRUE;
3861 /* when prepending, move the scroller along with the first selected
3862 * item to create the illusion that we're watching the selected
3863 * item this prevents the selected item being scrolled off the
3866 if (sd->selected && it->item->before)
3871 it2 = sd->selected->data;
3872 if (!it2->item->block) return;
3873 sd->s_iface->content_pos_get(ELM_WIDGET_DATA(sd)->obj, NULL, &y);
3874 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
3875 if ((it->y + it->item->block->y > y + h) ||
3876 (it->y + it->item->block->y + it->item->h < y))
3877 /* offscreen, just update */
3878 sd->s_iface->content_region_show
3879 (ELM_WIDGET_DATA(sd)->obj, it2->x + it2->item->block->x, y,
3880 it2->item->block->w, h);
3882 sd->s_iface->content_region_show
3883 (ELM_WIDGET_DATA(sd)->obj, it->x + it->item->block->x,
3884 y + it->item->h, it->item->block->w, h);
3889 _queue_process(Elm_Genlist_Smart_Data *sd)
3894 t0 = ecore_loop_time_get();
3895 for (n = 0; (sd->queue) && (n < 128); n++)
3899 it = eina_list_data_get(sd->queue);
3900 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
3901 it->item->queued = EINA_FALSE;
3902 if (_item_process(sd, it)) continue;
3903 t = ecore_time_get();
3904 _item_process_post(sd, it, EINA_TRUE);
3905 /* same as eina_inlist_count > 1 */
3906 if (sd->blocks && sd->blocks->next)
3908 if ((t - t0) > (ecore_animator_frametime_get())) break;
3915 _item_idle_enterer(void *data)
3917 Elm_Genlist_Smart_Data *sd = data;
3919 if (sd->prev_viewport_w == 0) return ECORE_CALLBACK_RENEW;
3920 if (_queue_process(sd) > 0)
3923 // Job always be alive because idle_enterer should be alive
3924 if (sd->calc_job) ecore_job_del(sd->calc_job);
3925 sd->calc_job = ecore_job_add(_calc_job, sd);
3929 sd->queue_idle_enterer = NULL;
3930 return ECORE_CALLBACK_CANCEL;
3933 #if GENLIST_FX_SUPPORT
3934 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
3936 return ECORE_CALLBACK_RENEW;
3940 _item_queue(Elm_Genlist_Smart_Data *sd,
3944 if (it->item->queued) return;
3946 it->item->queued = EINA_TRUE;
3947 if (cb && !sd->requeued)
3948 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
3950 sd->queue = eina_list_append(sd->queue, it);
3952 if (sd->queue_idle_enterer)
3953 ecore_idle_enterer_del(sd->queue_idle_enterer);
3954 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd);
3956 if (sd->prev_viewport_w != 0)
3958 while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
3961 while ((sd->queue) && (sd->blocks) &&
3962 (sd->homogeneous) && (sd->mode == ELM_LIST_COMPRESS))
3967 /* If the application wants to know the relative item, use
3968 * elm_genlist_item_prev_get(it)*/
3970 _item_move_after(Elm_Gen_Item *it,
3971 Elm_Gen_Item *after)
3975 if (it == after) return;
3977 GL_IT(it)->wsd->items =
3978 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
3979 if (it->item->block) _item_block_del(it);
3981 GL_IT(it)->wsd->items = eina_inlist_append_relative
3982 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3983 it->item->rel = after;
3984 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
3985 it->item->before = EINA_FALSE;
3986 if (after->item->group_item) it->item->group_item = after->item->group_item;
3987 _item_queue(GL_IT(it)->wsd, it, NULL);
3989 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
3993 _access_activate_cb(void *data __UNUSED__,
3994 Evas_Object *part_obj __UNUSED__,
3995 Elm_Object_Item *item)
3997 _item_select_unselect((Elm_Gen_Item *)item, EINA_TRUE);
4000 /* If the application wants to know the relative item, use
4001 * elm_genlist_item_next_get(it)*/
4003 _item_move_before(Elm_Gen_Item *it,
4004 Elm_Gen_Item *before)
4007 if (!before) return;
4008 if (it == before) return;
4010 GL_IT(it)->wsd->items =
4011 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
4012 if (it->item->block) _item_block_del(it);
4013 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
4014 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4015 it->item->rel = before;
4016 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
4017 it->item->before = EINA_TRUE;
4018 if (before->item->group_item)
4019 it->item->group_item = before->item->group_item;
4020 _item_queue(GL_IT(it)->wsd, it, NULL);
4022 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4026 _item_mouse_up_cb(void *data,
4027 Evas *evas __UNUSED__,
4028 Evas_Object *obj __UNUSED__,
4031 Evas_Event_Mouse_Up *ev = event_info;
4032 Eina_Bool dragged = EINA_FALSE;
4033 Elm_Genlist_Smart_Data *sd;
4034 Elm_Gen_Item *it = data;
4036 if (ev->button != 1) return;
4037 it->down = EINA_FALSE;
4038 sd = GL_IT(it)->wsd;
4040 sd->mouse_down = EINA_FALSE;
4041 if (sd->multi_touched)
4043 if ((!sd->multi) && (!it->selected) && (it->highlighted))
4044 _item_unhighlight(it);
4045 if (sd->multi_down) return;
4046 _multi_touch_gesture_eval(data);
4051 ecore_timer_del(it->long_timer);
4052 it->long_timer = NULL;
4056 it->dragging = EINA_FALSE;
4057 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
4060 if (it->item->swipe_timer)
4062 ecore_timer_del(it->item->swipe_timer);
4063 it->item->swipe_timer = NULL;
4065 if (sd->multi_timer)
4067 ecore_timer_del(sd->multi_timer);
4068 sd->multi_timer = NULL;
4069 sd->multi_timeout = EINA_FALSE;
4071 sd->on_hold = EINA_FALSE;
4072 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4074 if (sd->swipe) _swipe_do(data);
4075 sd->longpressed = EINA_FALSE;
4078 if ((sd->reorder_mode) && (sd->reorder_it))
4080 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
4081 sd->reorder_fast = 0;
4083 if (sd->reorder_rel &&
4084 (sd->reorder_it->parent == sd->reorder_rel->parent))
4086 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
4087 _item_move_before(sd->reorder_it, sd->reorder_rel);
4089 _item_move_after(sd->reorder_it, sd->reorder_rel);
4090 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4094 if (sd->calc_job) ecore_job_del(sd->calc_job);
4095 sd->calc_job = ecore_job_add(_calc_job, sd);
4097 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
4098 sd->reorder_it = sd->reorder_rel = NULL;
4099 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4100 sd->s_iface->bounce_allow_set
4101 (ELM_WIDGET_DATA(sd)->obj, sd->h_bounce, sd->v_bounce);
4105 if (it->want_unrealize && !(it->item->unrealize_disabled))
4107 _item_unrealize(it, EINA_FALSE);
4108 if (it->item->block->want_unrealize)
4109 _item_block_unrealize(it->item->block);
4114 if (!sd->longpressed)
4115 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
4116 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
4117 _item_select_unselect(it, EINA_TRUE);
4118 else _item_select_unselect(it, !it->selected);
4120 _item_unhighlight(it);
4124 _item_mouse_callbacks_add(Elm_Gen_Item *it,
4127 evas_object_event_callback_add
4128 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4129 evas_object_event_callback_add
4130 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4131 evas_object_event_callback_add
4132 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4133 evas_object_event_callback_add
4134 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4135 evas_object_event_callback_add
4136 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4137 evas_object_event_callback_add
4138 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4142 _item_mouse_callbacks_del(Elm_Gen_Item *it,
4145 evas_object_event_callback_del_full
4146 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4147 evas_object_event_callback_del_full
4148 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4149 evas_object_event_callback_del_full
4150 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4151 evas_object_event_callback_del_full
4152 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4153 evas_object_event_callback_del_full
4154 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4155 evas_object_event_callback_del_full
4156 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4160 _scroll_hold_timer_cb(void *data)
4162 Elm_Genlist_Smart_Data *sd = data;
4164 if (!data) return ECORE_CALLBACK_CANCEL;
4166 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
4167 sd->scr_hold_timer = NULL;
4169 return ECORE_CALLBACK_CANCEL;
4173 _decorate_item_finished_signal_cb(void *data,
4175 const char *emission __UNUSED__,
4176 const char *source __UNUSED__)
4178 Elm_Gen_Item *it = data;
4181 if (!data || !obj) return;
4182 if ((!it->realized) || (!it->item->deco_it_view)) return;
4184 it->item->nocache_once = EINA_FALSE;
4185 _decorate_item_unrealize(it);
4186 if (it->item->group_item)
4187 evas_object_raise(it->item->VIEW(group_item));
4189 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
4190 GL_IT(it)->wsd->decorate_it_type);
4191 edje_object_signal_callback_del_full
4192 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
4196 _item_mode_content_unrealize(Elm_Gen_Item *it,
4197 Evas_Object *target,
4200 Eina_List **contents_list)
4202 Eina_List *res = *contents_list;
4204 if (it->itc->func.content_get)
4208 Evas_Object *ic = NULL;
4210 EINA_LIST_FOREACH(*source, l, key)
4212 if (parts && fnmatch(parts, key, FNM_PERIOD))
4215 ic = edje_object_part_swallow_get(target, key);
4218 res = eina_list_remove(res, ic);
4219 edje_object_part_unswallow(target, ic);
4220 evas_object_del(ic);
4229 _item_content_unrealize(Elm_Gen_Item *it,
4230 Evas_Object *target,
4234 Eina_List *res = it->content_objs;
4236 if (it->itc->func.content_get)
4240 Evas_Object *ic = NULL;
4242 EINA_LIST_FOREACH(*source, l, key)
4244 if (parts && fnmatch(parts, key, FNM_PERIOD))
4247 ic = edje_object_part_swallow_get(target, key);
4250 res = eina_list_remove(res, ic);
4251 edje_object_part_unswallow(target, ic);
4252 // FIXME: If parent-child relationship was broken before 'ic'
4253 // is deleted, freeze_pop will not be called. ex) elm_slider
4254 // If layout is used instead of edje, this problme can be
4256 if (0 != elm_widget_scroll_freeze_get(ic))
4257 elm_widget_scroll_freeze_pop(ic);
4258 evas_object_del(ic);
4267 _item_block_recalc(Item_Block *itb,
4271 const Eina_List *l, *ll;
4273 Evas_Coord minw = 0, minh = 0;
4274 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
4278 EINA_LIST_FOREACH_SAFE(itb->items, l, ll, it)
4280 show_me |= it->item->show_me;
4285 if (!it->item->mincalcd) changed = EINA_TRUE;
4288 _item_realize(it, in, EINA_TRUE);
4289 _item_unrealize(it, EINA_TRUE);
4294 if ((itb->sd->homogeneous) &&
4295 (itb->sd->mode == ELM_LIST_COMPRESS))
4299 it->item->w = it->item->minw =
4300 GL_IT(it)->wsd->group_item_width;
4301 it->item->h = it->item->minh =
4302 GL_IT(it)->wsd->group_item_height;
4306 it->item->w = it->item->minw =
4307 GL_IT(it)->wsd->item_width;
4308 it->item->h = it->item->minh =
4309 GL_IT(it)->wsd->item_height;
4314 _item_realize(it, in, EINA_TRUE);
4315 _item_unrealize(it, EINA_TRUE);
4321 if (!it->item->mincalcd) changed = EINA_TRUE;
4322 _item_realize(it, in, EINA_FALSE);
4324 minh += it->item->minh;
4325 if (minw < it->item->minw) minw = it->item->minw;
4329 #if GENLIST_PINCH_ZOOM_SUPPORT
4330 if (IS_ROOT_PARENT_IT(it))
4331 it->item->pan_scrl_y = itb->y + it->y;
4335 if (changed) itb->sd->pan_changed = changed;
4338 itb->changed = EINA_FALSE;
4339 itb->position_update = EINA_FALSE;
4345 _update_job(void *data)
4347 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
4348 Elm_Genlist_Smart_Data *sd = data;
4353 sd->update_job = NULL;
4356 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4357 EINA_INLIST_FOREACH(sd->blocks, itb)
4359 Evas_Coord itminw, itminh;
4366 _item_block_position(itb, num);
4370 recalc = EINA_FALSE;
4371 EINA_LIST_FOREACH(itb->items, l2, it)
4373 if (it->item->updateme)
4375 itminw = it->item->minw;
4376 itminh = it->item->minh;
4378 it->item->updateme = EINA_FALSE;
4381 _item_unrealize(it, EINA_FALSE);
4382 _item_realize(it, num, EINA_FALSE);
4383 position = EINA_TRUE;
4387 _item_realize(it, num, EINA_TRUE);
4388 _item_unrealize(it, EINA_TRUE);
4390 if ((it->item->minw != itminw) || (it->item->minh != itminh))
4395 itb->updateme = EINA_FALSE;
4398 position = EINA_TRUE;
4399 itb->changed = EINA_TRUE;
4400 _item_block_recalc(itb, num0, EINA_FALSE);
4401 _item_block_position(itb, num0);
4406 if (sd->calc_job) ecore_job_del(sd->calc_job);
4407 sd->calc_job = ecore_job_add(_calc_job, sd);
4409 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4410 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4414 _scroll_animate_start_cb(Evas_Object *obj,
4415 void *data __UNUSED__)
4417 #if GENLIST_FX_SUPPORT
4418 _elm_genlist_fx_clear(obj, EINA_FALSE);
4420 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
4424 _scroll_animate_stop_cb(Evas_Object *obj,
4425 void *data __UNUSED__)
4427 #if GENLIST_FX_SUPPORT
4428 _elm_genlist_fx_clear(obj, EINA_FALSE);
4430 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
4434 _scroll_drag_start_cb(Evas_Object *obj,
4435 void *data __UNUSED__)
4437 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
4441 _scroll_drag_stop_cb(Evas_Object *obj,
4442 void *data __UNUSED__)
4444 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
4448 _edge_left_cb(Evas_Object *obj,
4449 void *data __UNUSED__)
4451 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
4455 _edge_right_cb(Evas_Object *obj,
4456 void *data __UNUSED__)
4458 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
4462 _edge_top_cb(Evas_Object *obj,
4463 void *data __UNUSED__)
4465 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
4469 _edge_bottom_cb(Evas_Object *obj,
4470 void *data __UNUSED__)
4472 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
4476 _vbar_drag_cb(Evas_Object *obj,
4477 void *data __UNUSED__)
4479 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
4483 _vbar_press_cb(Evas_Object *obj,
4484 void *data __UNUSED__)
4486 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
4490 _vbar_unpress_cb(Evas_Object *obj,
4491 void *data __UNUSED__)
4493 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
4497 _hbar_drag_cb(Evas_Object *obj,
4498 void *data __UNUSED__)
4500 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
4504 _hbar_press_cb(Evas_Object *obj,
4505 void *data __UNUSED__)
4507 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
4511 _hbar_unpress_cb(Evas_Object *obj,
4512 void *data __UNUSED__)
4514 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
4518 _decorate_item_realize(Elm_Gen_Item *it)
4521 if (it->item->deco_it_view) return;
4523 //evas_event_freeze(evas_object_evas_get(obj));
4524 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
4525 edje_object_scale_set
4526 (it->item->deco_it_view, elm_widget_scale_get(WIDGET(it)) *
4527 elm_config_scale_get());
4528 evas_object_smart_member_add
4529 (it->item->deco_it_view, GL_IT(it)->wsd->pan_obj);
4530 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
4532 strncpy(buf, "item", sizeof(buf));
4533 if (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)
4534 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
4536 if (it->item->order_num_in & 0x1)
4537 strncat(buf, "_odd", sizeof(buf) - strlen(buf));
4538 strncat(buf, "/", sizeof(buf) - strlen(buf));
4539 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
4541 elm_widget_theme_object_set
4542 (WIDGET(it), it->item->deco_it_view, "genlist", buf,
4543 elm_widget_style_get(WIDGET(it)));
4544 edje_object_mirrored_set
4545 (it->item->deco_it_view, elm_widget_mirrored_get(WIDGET(it)));
4547 /* signal callback add */
4548 evas_object_event_callback_add
4549 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb,
4551 evas_object_event_callback_add
4552 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4553 evas_object_event_callback_add
4554 (it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb,
4557 if (eina_list_count(it->item->deco_it_content_objs) != 0)
4558 ERR_ABORT("If you see this error, please notify us and we"
4561 /* text_get, content_get, state_get */
4563 (it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
4564 if (!it->item->deco_it_contents)
4565 it->item->deco_it_contents =
4566 elm_widget_stringlist_get
4567 (edje_object_data_get(it->item->deco_it_view, "contents"));
4568 it->item->deco_it_content_objs =
4569 _item_mode_content_realize
4570 (it, it->item->deco_it_view, &it->item->deco_it_contents, NULL,
4571 &it->item->deco_it_content_objs);
4573 (it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
4574 edje_object_part_swallow
4575 (it->item->deco_it_view,
4576 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
4578 it->want_unrealize = EINA_FALSE;
4579 //evas_event_thaw(evas_object_evas_get(obj));
4580 //evas_event_thaw_eval(evas_object_evas_get(obj));
4584 _decorate_item_set(Elm_Gen_Item *it)
4586 Elm_Genlist_Smart_Data *sd;
4591 sd = GL_IT(it)->wsd;
4594 it->item->nocache_once = EINA_TRUE;
4596 if (sd->scr_hold_timer)
4598 ecore_timer_del(sd->scr_hold_timer);
4599 sd->scr_hold_timer = NULL;
4601 sd->s_iface->hold_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
4602 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
4604 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4605 _decorate_item_realize(it);
4606 if (it->item->group_item)
4607 evas_object_raise(it->item->VIEW(group_item));
4609 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
4610 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4611 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
4613 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
4614 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4618 _decorate_item_unset(Elm_Genlist_Smart_Data *sd)
4620 char buf[1024], buf2[1024];
4623 if (!sd->mode_item) return;
4626 it->item->nocache_once = EINA_TRUE;
4628 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
4629 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
4630 sd->decorate_it_type);
4631 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
4632 edje_object_signal_callback_add
4633 (it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb,
4635 sd->mode_item = NULL;
4639 // FIXME: difference from upstream
4641 _mouse_down_scroller(void *data,
4642 Evas *evas __UNUSED__,
4643 Evas_Object *obj __UNUSED__,
4644 void *event_info __UNUSED__)
4646 Widget_Data *wd = elm_widget_data_get(data);
4649 wd->drag_started = EINA_FALSE;
4653 _mouse_up_scroller(void *data,
4654 Evas *evas __UNUSED__,
4655 Evas_Object *obj __UNUSED__,
4656 void *event_info __UNUSED__)
4658 Widget_Data *wd = elm_widget_data_get(data);
4661 wd->drag_started = EINA_FALSE;
4665 _mouse_move_scroller(void *data,
4666 Evas *evas __UNUSED__,
4667 Evas_Object *obj __UNUSED__,
4670 Widget_Data *wd = elm_widget_data_get(data);
4671 Evas_Event_Mouse_Move *ev = event_info;
4672 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
4675 if (wd->drag_started) return;
4677 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4678 dx = ev->cur.canvas.x - ev->prev.canvas.x;
4679 dy = ev->cur.canvas.y - ev->prev.canvas.y;
4682 if (adx < 0) adx = -dx;
4683 if (ady < 0) ady = -dy;
4684 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
4688 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
4689 wd->drag_started = EINA_TRUE;
4693 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
4694 wd->drag_started = EINA_TRUE;
4701 _elm_genlist_smart_add(Evas_Object *obj)
4703 Evas_Coord minw, minh;
4704 Elm_Genlist_Pan_Smart_Data *pan_data;
4706 EVAS_SMART_DATA_ALLOC(obj, Elm_Genlist_Smart_Data);
4708 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.add(obj);
4710 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
4711 evas_object_smart_member_add(priv->hit_rect, obj);
4712 elm_widget_sub_object_add(obj, priv->hit_rect);
4714 /* common scroller hit rectangle setup */
4715 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
4716 evas_object_show(priv->hit_rect);
4717 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
4719 elm_widget_can_focus_set(obj, EINA_TRUE);
4720 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
4722 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
4724 /* interface's add() routine issued AFTER the object's smart_add() */
4725 priv->s_iface = evas_object_smart_interface_get
4726 (obj, ELM_SCROLLABLE_IFACE_NAME);
4728 priv->s_iface->objects_set
4729 (obj, ELM_WIDGET_DATA(priv)->resize_obj, priv->hit_rect);
4731 priv->s_iface->bounce_allow_set
4732 (obj, EINA_FALSE, _elm_config->thumbscroll_bounce_enable);
4733 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
4735 priv->s_iface->animate_start_cb_set(obj, _scroll_animate_start_cb);
4736 priv->s_iface->animate_stop_cb_set(obj, _scroll_animate_stop_cb);
4737 priv->s_iface->drag_start_cb_set(obj, _scroll_drag_start_cb);
4738 priv->s_iface->drag_stop_cb_set(obj, _scroll_drag_stop_cb);
4739 priv->s_iface->edge_left_cb_set(obj, _edge_left_cb);
4740 priv->s_iface->edge_right_cb_set(obj, _edge_right_cb);
4741 priv->s_iface->edge_top_cb_set(obj, _edge_top_cb);
4742 priv->s_iface->edge_bottom_cb_set(obj, _edge_bottom_cb);
4743 priv->s_iface->vbar_drag_cb_set(obj, _vbar_drag_cb);
4744 priv->s_iface->vbar_press_cb_set(obj, _vbar_press_cb);
4745 priv->s_iface->vbar_unpress_cb_set(obj, _vbar_unpress_cb);
4746 priv->s_iface->hbar_drag_cb_set(obj, _hbar_drag_cb);
4747 priv->s_iface->hbar_press_cb_set(obj, _hbar_press_cb);
4748 priv->s_iface->hbar_unpress_cb_set(obj, _hbar_unpress_cb);
4750 priv->mode = ELM_LIST_SCROLL;
4751 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
4752 priv->item_cache_max = priv->max_items_per_block * 2;
4753 priv->longpress_timeout = _elm_config->longpress_timeout;
4754 priv->highlight = EINA_TRUE;
4756 #if GENLIST_FX_SUPPORT
4757 priv->fx_mode = EINA_FALSE;
4758 priv->rendered = EINA_FALSE;
4759 priv->fx_first_captured = EINA_FALSE;
4760 priv->fx_playing = EINA_FALSE;
4761 priv->fx_items_deleted = EINA_FALSE;
4762 priv->genlist_clearing = EINA_FALSE;
4765 priv->pan_obj = evas_object_smart_add
4766 (evas_object_evas_get(obj), _elm_genlist_pan_smart_class_new());
4767 pan_data = evas_object_smart_data_get(priv->pan_obj);
4768 pan_data->wsd = priv;
4771 // FIXME: difference from upstream
4772 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
4773 _mouse_down_scroller, obj);
4774 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
4775 _mouse_up_scroller, obj);
4776 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
4777 _mouse_move_scroller, obj);
4780 priv->s_iface->extern_pan_set(obj, priv->pan_obj);
4782 edje_object_size_min_calc(ELM_WIDGET_DATA(priv)->resize_obj, &minw, &minh);
4783 evas_object_size_hint_min_set(obj, minw, minh);
4785 _item_cache_all_free(priv);
4786 _mirrored_set(obj, elm_widget_mirrored_get(obj));
4788 elm_layout_sizing_eval(obj);
4792 _elm_genlist_smart_del(Evas_Object *obj)
4794 ELM_GENLIST_DATA_GET(obj, sd);
4796 elm_genlist_clear(obj);
4797 if (sd->calc_job) ecore_job_del(sd->calc_job);
4798 if (sd->update_job) ecore_job_del(sd->update_job);
4799 if (sd->queue_idle_enterer) ecore_idle_enterer_del(sd->queue_idle_enterer);
4800 if (sd->must_recalc_idler) ecore_idler_del(sd->must_recalc_idler);
4801 if (sd->multi_timer) ecore_timer_del(sd->multi_timer);
4802 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
4803 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
4805 evas_object_del(sd->pan_obj);
4806 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.del(obj);
4810 _elm_genlist_smart_move(Evas_Object *obj,
4814 ELM_GENLIST_DATA_GET(obj, sd);
4816 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.move(obj, x, y);
4818 evas_object_move(sd->hit_rect, x, y);
4822 _elm_genlist_smart_resize(Evas_Object *obj,
4826 ELM_GENLIST_DATA_GET(obj, sd);
4828 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.resize(obj, w, h);
4830 evas_object_resize(sd->hit_rect, w, h);
4834 _elm_genlist_smart_member_add(Evas_Object *obj,
4835 Evas_Object *member)
4837 ELM_GENLIST_DATA_GET(obj, sd);
4839 ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->base.member_add(obj, member);
4842 evas_object_raise(sd->hit_rect);
4846 _access_obj_process(Elm_Genlist_Smart_Data *sd, Eina_Bool is_access)
4849 Eina_Bool done = EINA_FALSE;
4851 EINA_INLIST_FOREACH(sd->blocks, itb)
4859 EINA_LIST_FOREACH(itb->items, l, it)
4861 if (!it->realized) continue;
4862 if (is_access) _access_widget_item_register(it);
4864 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
4867 else if (done) break;
4872 _elm_genlist_smart_access(Evas_Object *obj, Eina_Bool is_access)
4874 ELM_GENLIST_CHECK(obj);
4875 ELM_GENLIST_DATA_GET(obj, sd);
4878 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
4879 _elm_genlist_smart_focus_next;
4881 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
4882 _access_obj_process(sd, is_access);
4886 _elm_genlist_smart_set_user(Elm_Genlist_Smart_Class *sc)
4888 ELM_WIDGET_CLASS(sc)->base.add = _elm_genlist_smart_add;
4889 ELM_WIDGET_CLASS(sc)->base.del = _elm_genlist_smart_del;
4890 ELM_WIDGET_CLASS(sc)->base.move = _elm_genlist_smart_move;
4891 ELM_WIDGET_CLASS(sc)->base.resize = _elm_genlist_smart_resize;
4892 ELM_WIDGET_CLASS(sc)->base.member_add = _elm_genlist_smart_member_add;
4894 ELM_WIDGET_CLASS(sc)->sub_object_add = _elm_genlist_smart_sub_object_add;
4895 ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_genlist_smart_sub_object_del;
4896 ELM_WIDGET_CLASS(sc)->on_focus = _elm_genlist_smart_on_focus;
4897 ELM_WIDGET_CLASS(sc)->theme = _elm_genlist_smart_theme;
4898 ELM_WIDGET_CLASS(sc)->event = _elm_genlist_smart_event;
4899 ELM_WIDGET_CLASS(sc)->translate = _elm_genlist_smart_translate;
4901 /* not a 'focus chain manager' */
4902 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
4903 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
4905 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_genlist_smart_sizing_eval;
4908 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
4909 ELM_WIDGET_CLASS(sc)->focus_next = _elm_genlist_smart_focus_next;
4911 ELM_WIDGET_CLASS(sc)->access = _elm_genlist_smart_access;
4914 EAPI const Elm_Genlist_Smart_Class *
4915 elm_genlist_smart_class_get(void)
4917 static Elm_Genlist_Smart_Class _sc =
4918 ELM_GENLIST_SMART_CLASS_INIT_NAME_VERSION(ELM_GENLIST_SMART_NAME);
4919 static const Elm_Genlist_Smart_Class *class = NULL;
4920 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
4925 _elm_genlist_smart_set(&_sc);
4926 esc->callbacks = _smart_callbacks;
4933 elm_genlist_add(Evas_Object *parent)
4937 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
4939 obj = elm_widget_add(_elm_genlist_smart_class_new(), parent);
4940 if (!obj) return NULL;
4942 if (!elm_widget_sub_object_add(parent, obj))
4943 ERR("could not add %p as sub object of %p", obj, parent);
4949 static Evas_Object *
4950 _item_content_get_hook(Elm_Gen_Item *it,
4953 Evas_Object *ret = NULL;
4954 if (it->deco_all_view)
4955 ret = edje_object_part_swallow_get(it->deco_all_view, part);
4956 else if (it->decorate_it_set)
4957 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
4959 ret = edje_object_part_swallow_get(VIEW(it), part);
4964 _item_text_get_hook(Elm_Gen_Item *it,
4967 if (!it->itc->func.text_get) return NULL;
4968 const char *ret = NULL;
4969 if (it->deco_all_view)
4970 ret = edje_object_part_text_get(it->deco_all_view, part);
4971 else if (it->decorate_it_set)
4972 ret = edje_object_part_text_get(it->item->deco_it_view, part);
4974 ret = edje_object_part_text_get(VIEW(it), part);
4979 _item_disable_hook(Elm_Object_Item *item)
4983 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4986 elm_genlist_item_selected_set(item, EINA_FALSE);
4990 if (elm_widget_item_disabled_get(it))
4992 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4993 if (it->deco_all_view)
4994 edje_object_signal_emit
4995 (it->deco_all_view, "elm,state,disabled", "elm");
4999 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
5000 if (it->deco_all_view)
5001 edje_object_signal_emit
5002 (it->deco_all_view, "elm,state,enabled", "elm");
5004 EINA_LIST_FOREACH(it->content_objs, l, obj)
5005 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(it));
5010 _item_free(Elm_Gen_Item *it)
5012 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5014 #if GENLIST_FX_SUPPORT
5015 if (sd->fx_mode) GL_IT(it)->has_proxy_it = EINA_FALSE;
5016 _elm_genlist_proxy_item_del((Elm_Object_Item *)it);
5017 if ((!sd->fx_mode) || (sd->genlist_clearing))
5020 _item_free_common(it);
5022 _item_unrealize(it, EINA_FALSE);
5023 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
5026 if (sd->calc_job) ecore_job_del(sd->calc_job);
5027 sd->calc_job = ecore_job_add(_calc_job, sd);
5030 #if GENLIST_FX_SUPPORT
5032 _item_del_pre_fx_process(Elm_Gen_Item *it)
5034 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
5036 sd->fx_items_deleted = EINA_TRUE;
5037 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5038 if (!eina_list_data_find(sd->pending_del_items, it))
5039 sd->pending_del_items = eina_list_append(sd->pending_del_items, it);
5041 _item_free_common(it);
5047 _item_del_pre_hook(Elm_Object_Item *item)
5049 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5051 #if GENLIST_FX_SUPPORT
5052 if ((GL_IT(it)->wsd->fx_mode) && (!GL_IT(it)->wsd->genlist_clearing))
5054 _item_del_pre_fx_process(it);
5063 _item_signal_emit_hook(Elm_Object_Item *it,
5064 const char *emission,
5067 edje_object_signal_emit(VIEW(it), emission, source);
5070 static Elm_Gen_Item *
5071 _elm_genlist_item_new(Elm_Genlist_Smart_Data *sd,
5072 const Elm_Genlist_Item_Class *itc,
5074 Elm_Gen_Item *parent,
5075 Elm_Genlist_Item_Type type,
5077 const void *func_data)
5079 Elm_Gen_Item *it, *it2;
5082 if (!itc) return NULL;
5084 it = elm_widget_item_new(ELM_WIDGET_DATA(sd)->obj, Elm_Gen_Item);
5085 if (!it) return NULL;
5088 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
5090 it->base.data = data;
5091 it->parent = parent;
5092 it->func.func = func;
5093 it->func.data = func_data;
5095 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
5096 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
5097 elm_widget_item_disable_hook_set(it, _item_disable_hook);
5098 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
5099 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
5101 #if 0 // FIXME: difference from upstream
5102 it->can_focus = EINA_TRUE;
5104 //it->del_cb = (Ecore_Cb)_item_free;
5105 //it->highlight_cb = (Ecore_Cb)_item_highlight;
5106 //it->unhighlight_cb = (Ecore_Cb)_item_unhighlight;
5107 //it->sel_cb = (Ecore_Cb)_item_select;
5108 //it->unsel_cb = (Ecore_Cb)_item_unselect;
5109 //it->unrealize_cb = (Ecore_Cb)_item_unrealize_cb;
5111 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
5112 GL_IT(it)->wsd = sd;
5113 GL_IT(it)->type = type;
5114 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
5118 if (it->parent->group)
5119 GL_IT(it)->group_item = parent;
5120 else if (GL_IT(it->parent)->group_item)
5121 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
5123 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
5125 if (!it2->parent->group) depth += 1;
5127 GL_IT(it)->expanded_depth = depth;
5130 #if GENLIST_FX_SUPPORT
5131 it->item->num = sd->item_count;
5134 sd->fx_items_deleted = EINA_FALSE;
5135 _elm_genlist_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
5142 _elm_genlist_item_compare(const void *data,
5145 const Elm_Gen_Item *it, *item1;
5147 it = ELM_GEN_ITEM_FROM_INLIST(data);
5148 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
5149 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5153 _elm_genlist_item_list_compare(const void *data,
5156 const Elm_Gen_Item *it = data;
5157 const Elm_Gen_Item *item1 = data1;
5159 return GL_IT(it)->wsd->item_compare_cb(it, item1);
5163 elm_genlist_items_count(const Evas_Object *obj)
5165 ELM_GENLIST_CHECK(obj) 0;
5166 ELM_GENLIST_DATA_GET(obj, sd);
5168 return sd->item_count;
5171 EAPI Elm_Object_Item *
5172 elm_genlist_item_append(Evas_Object *obj,
5173 const Elm_Genlist_Item_Class *itc,
5175 Elm_Object_Item *parent,
5176 Elm_Genlist_Item_Type type,
5178 const void *func_data)
5182 ELM_GENLIST_CHECK(obj) NULL;
5183 ELM_GENLIST_DATA_GET(obj, sd);
5185 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(((Elm_Widget_Item *)parent),NULL);
5187 it = _elm_genlist_item_new
5188 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5189 if (!it) return NULL;
5194 sd->group_items = eina_list_append(sd->group_items, it);
5195 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
5196 it->item->rel = NULL;
5200 Elm_Gen_Item *it2 = NULL;
5201 Eina_List *ll = eina_list_last(it->parent->item->items);
5203 if (ll) it2 = ll->data;
5204 it->parent->item->items =
5205 eina_list_append(it->parent->item->items, it);
5206 if (!it2) it2 = it->parent;
5207 sd->items = eina_inlist_append_relative
5208 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5209 it->item->rel = it2;
5210 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5212 it->item->before = EINA_FALSE;
5213 _item_queue(sd, it, NULL);
5215 return (Elm_Object_Item *)it;
5218 EAPI Elm_Object_Item *
5219 elm_genlist_item_prepend(Evas_Object *obj,
5220 const Elm_Genlist_Item_Class *itc,
5222 Elm_Object_Item *parent,
5223 Elm_Genlist_Item_Type type,
5225 const void *func_data)
5229 ELM_GENLIST_CHECK(obj) NULL;
5230 ELM_GENLIST_DATA_GET(obj, sd);
5231 it = _elm_genlist_item_new
5232 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5233 if (!it) return NULL;
5238 sd->group_items = eina_list_prepend(sd->group_items, it);
5239 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
5240 it->item->rel = NULL;
5244 Elm_Gen_Item *it2 = NULL;
5245 Eina_List *ll = it->parent->item->items;
5247 if (ll) it2 = ll->data;
5248 it->parent->item->items =
5249 eina_list_prepend(it->parent->item->items, it);
5250 if (!it2) it2 = it->parent;
5251 sd->items = eina_inlist_prepend_relative
5252 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5253 it->item->rel = it2;
5254 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5256 it->item->before = EINA_TRUE;
5257 _item_queue(sd, it, NULL);
5259 return (Elm_Object_Item *)it;
5262 EAPI Elm_Object_Item *
5263 elm_genlist_item_insert_after(Evas_Object *obj,
5264 const Elm_Genlist_Item_Class *itc,
5266 Elm_Object_Item *parent,
5267 Elm_Object_Item *after_it,
5268 Elm_Genlist_Item_Type type,
5270 const void *func_data)
5272 Elm_Gen_Item *after = (Elm_Gen_Item *)after_it;
5275 ELM_GENLIST_CHECK(obj) NULL;
5276 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
5277 ELM_GENLIST_DATA_GET(obj, sd);
5279 /* It makes no sense to insert after in an empty list with after !=
5280 * NULL, something really bad is happening in your app. */
5281 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5283 it = _elm_genlist_item_new
5284 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5285 if (!it) return NULL;
5289 if ((it->group) && (after->group))
5290 sd->group_items = eina_list_append_relative
5291 (sd->group_items, it, after);
5295 it->parent->item->items =
5296 eina_list_append_relative(it->parent->item->items, it, after);
5298 sd->items = eina_inlist_append_relative
5299 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5301 it->item->rel = after;
5302 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5303 it->item->before = EINA_FALSE;
5304 _item_queue(sd, it, NULL);
5306 return (Elm_Object_Item *)it;
5309 EAPI Elm_Object_Item *
5310 elm_genlist_item_insert_before(Evas_Object *obj,
5311 const Elm_Genlist_Item_Class *itc,
5313 Elm_Object_Item *parent,
5314 Elm_Object_Item *before_it,
5315 Elm_Genlist_Item_Type type,
5317 const void *func_data)
5319 Elm_Gen_Item *before = (Elm_Gen_Item *)before_it;
5322 ELM_GENLIST_CHECK(obj) NULL;
5323 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
5324 ELM_GENLIST_DATA_GET(obj, sd);
5326 /* It makes no sense to insert before in an empty list with before
5327 * != NULL, something really bad is happening in your app. */
5328 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5330 it = _elm_genlist_item_new
5331 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5332 if (!it) return NULL;
5336 if (it->group && before->group)
5338 eina_list_prepend_relative(sd->group_items, it, before);
5342 it->parent->item->items =
5343 eina_list_prepend_relative(it->parent->item->items, it, before);
5345 sd->items = eina_inlist_prepend_relative
5346 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5348 it->item->rel = before;
5349 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5350 it->item->before = EINA_TRUE;
5351 _item_queue(sd, it, NULL);
5353 return (Elm_Object_Item *)it;
5356 EAPI Elm_Object_Item *
5357 elm_genlist_item_sorted_insert(Evas_Object *obj,
5358 const Elm_Genlist_Item_Class *itc,
5360 Elm_Object_Item *parent,
5361 Elm_Genlist_Item_Type type,
5362 Eina_Compare_Cb comp,
5364 const void *func_data)
5366 Elm_Gen_Item *rel = NULL;
5369 ELM_GENLIST_CHECK(obj) NULL;
5370 ELM_GENLIST_DATA_GET(obj, sd);
5372 it = _elm_genlist_item_new
5373 (sd, itc, data, (Elm_Gen_Item *)parent, type, func, func_data);
5374 if (!it) return NULL;
5376 sd->item_compare_cb = comp;
5383 l = eina_list_search_sorted_near_list
5384 (it->parent->item->items, _elm_genlist_item_list_compare, it,
5388 rel = eina_list_data_get(l);
5392 if (cmp_result >= 0)
5394 it->parent->item->items = eina_list_prepend_relative_list
5395 (it->parent->item->items, it, l);
5396 sd->items = eina_inlist_prepend_relative
5397 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5398 it->item->before = EINA_FALSE;
5400 else if (cmp_result < 0)
5402 it->parent->item->items = eina_list_append_relative_list
5403 (it->parent->item->items, it, l);
5404 sd->items = eina_inlist_append_relative
5405 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
5406 it->item->before = EINA_TRUE;
5413 sd->state = eina_inlist_sorted_state_new();
5414 eina_inlist_sorted_state_init(sd->state, sd->items);
5415 sd->requeued = EINA_FALSE;
5419 sd->group_items = eina_list_append(sd->group_items, it);
5421 sd->items = eina_inlist_sorted_state_insert
5422 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
5425 if (EINA_INLIST_GET(it)->next)
5427 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5428 it->item->before = EINA_TRUE;
5430 else if (EINA_INLIST_GET(it)->prev)
5432 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5433 it->item->before = EINA_FALSE;
5439 it->item->rel = rel;
5440 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
5443 _item_queue(sd, it, _elm_genlist_item_list_compare);
5445 return (Elm_Object_Item *)it;
5449 _elm_genlist_fx_clear(Evas_Object *obj, Eina_Bool force)
5451 ELM_GENLIST_DATA_GET(obj, sd);
5453 Elm_Gen_FX_Item *fi;
5457 if ((!force) && (!sd->fx_first_captured)) return;
5459 EINA_LIST_FREE(sd->capture_before_items, pi)
5461 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
5462 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
5463 if (pi->proxy) evas_object_del(pi->proxy);
5466 EINA_LIST_FREE(sd->capture_after_items, pi)
5468 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
5469 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
5470 if (pi->proxy) evas_object_del(pi->proxy);
5474 EINA_LIST_FREE(sd->fx_items, fi)
5476 if (fi->trans) elm_transit_del(fi->trans);
5480 EINA_LIST_FREE (sd->pending_unrealized_items, it)
5481 _item_unrealize(it, EINA_FALSE);
5483 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
5484 _decorate_all_item_unrealize(it);
5486 EINA_LIST_FREE (sd->pending_del_items, it)
5489 _elm_widget_item_free((Elm_Widget_Item *)it);
5491 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5492 sd->alpha_bg = NULL;
5493 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
5494 sd->fx_timer = NULL;
5496 sd->genlist_clearing = EINA_TRUE;
5497 sd->fx_playing = EINA_FALSE;
5498 sd->sorting = EINA_FALSE;
5499 sd->fx_first_captured = EINA_FALSE;
5500 sd->fx_items_deleted = EINA_FALSE;
5504 elm_genlist_clear(Evas_Object *obj)
5506 ELM_GENLIST_CHECK(obj);
5507 ELM_GENLIST_DATA_GET(obj, sd);
5512 eina_inlist_sorted_state_free(sd->state);
5516 #if GENLIST_FX_SUPPORT
5519 _elm_genlist_fx_clear(obj, EINA_TRUE);
5520 sd->genlist_clearing = EINA_TRUE;
5521 sd->rendered = EINA_FALSE;
5524 #if GENLIST_PINCH_ZOOM_SUPPORT
5525 sd->pinch_zoom_h = 0;
5526 sd->realized_top_item = NULL;
5527 sd->pinch_zoom_mode = ELM_GEN_PINCH_ZOOM_NONE;
5530 //evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5532 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
5533 // because sd->items can be modified inside elm_widget_item_del()
5536 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
5537 it->item->nocache_once = EINA_TRUE;
5538 elm_widget_item_del(it);
5542 _item_cache_all_free(sd);
5544 sd->pan_changed = EINA_TRUE;
5545 if (sd->selected) sd->selected = eina_list_free(sd->selected);
5546 sd->selected = NULL;
5548 sd->anchor_item = NULL;
5549 if (sd->multi_timer)
5551 ecore_timer_del(sd->multi_timer);
5552 sd->multi_timer = NULL;
5556 ecore_job_del(sd->update_job);
5557 sd->update_job = NULL;
5561 ecore_job_del(sd->calc_job);
5562 sd->calc_job = NULL;
5564 if (sd->queue_idle_enterer)
5566 ecore_idle_enterer_del(sd->queue_idle_enterer);
5567 sd->queue_idle_enterer = NULL;
5569 if (sd->must_recalc_idler)
5571 ecore_idler_del(sd->must_recalc_idler);
5572 sd->must_recalc_idler = NULL;
5574 if (sd->queue) sd->queue = eina_list_free(sd->queue);
5575 if (sd->reorder_move_animator)
5577 ecore_animator_del(sd->reorder_move_animator);
5578 sd->reorder_move_animator = NULL;
5580 sd->show_item = NULL;
5581 sd->reorder_old_pan_y = 0;
5588 if (sd->alpha_bg) evas_object_del(sd->alpha_bg);
5589 sd->alpha_bg = NULL;
5593 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
5594 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
5596 elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
5597 sd->s_iface->content_region_show(obj, 0, 0, 0, 0);
5599 #if GENLIST_FX_SUPPORT
5600 sd->genlist_clearing = EINA_FALSE;
5602 //evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5603 //evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5607 elm_genlist_multi_select_set(Evas_Object *obj,
5610 ELM_GENLIST_CHECK(obj);
5611 ELM_GENLIST_DATA_GET(obj, sd);
5613 sd->multi = !!multi;
5617 elm_genlist_multi_select_get(const Evas_Object *obj)
5619 ELM_GENLIST_CHECK(obj) EINA_FALSE;
5620 ELM_GENLIST_DATA_GET(obj, sd);
5625 EAPI Elm_Object_Item *
5626 elm_genlist_selected_item_get(const Evas_Object *obj)
5628 ELM_GENLIST_CHECK(obj) NULL;
5629 ELM_GENLIST_DATA_GET(obj, sd);
5632 return sd->selected->data;
5638 elm_genlist_selected_items_get(const Evas_Object *obj)
5640 ELM_GENLIST_CHECK(obj) NULL;
5641 ELM_GENLIST_DATA_GET(obj, sd);
5643 return sd->selected;
5647 elm_genlist_realized_items_get(const Evas_Object *obj)
5650 Eina_List *list = NULL;
5651 Eina_Bool done = EINA_FALSE;
5653 ELM_GENLIST_CHECK(obj) NULL;
5654 ELM_GENLIST_DATA_GET(obj, sd);
5656 EINA_INLIST_FOREACH(sd->blocks, itb)
5664 EINA_LIST_FOREACH(itb->items, l, it)
5666 if (it->realized) list = eina_list_append(list, it);
5677 EAPI Elm_Object_Item *
5678 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5683 Evas_Coord ox, oy, ow, oh;
5687 ELM_GENLIST_CHECK(obj) NULL;
5688 ELM_GENLIST_DATA_GET(obj, sd);
5690 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
5692 EINA_INLIST_FOREACH(sd->blocks, itb)
5697 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
5698 oy + itb->y - itb->sd->pan_y,
5699 itb->w, itb->h, x, y, 1, 1))
5701 EINA_LIST_FOREACH(itb->items, l, it)
5703 Evas_Coord itx, ity;
5705 itx = ox + itb->x + it->x - itb->sd->pan_x;
5706 ity = oy + itb->y + it->y - itb->sd->pan_y;
5707 if (ELM_RECTS_INTERSECT
5708 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5712 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5713 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5718 return (Elm_Object_Item *)it;
5720 lasty = ity + it->item->h;
5725 if (y > lasty) *posret = 1;
5732 EAPI Elm_Object_Item *
5733 elm_genlist_first_item_get(const Evas_Object *obj)
5735 Elm_Gen_Item *tit, *it = NULL;
5737 ELM_GENLIST_CHECK(obj) NULL;
5738 ELM_GENLIST_DATA_GET(obj, sd);
5740 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
5742 return (Elm_Object_Item *)it;
5745 EAPI Elm_Object_Item *
5746 elm_genlist_last_item_get(const Evas_Object *obj)
5750 ELM_GENLIST_CHECK(obj) NULL;
5751 ELM_GENLIST_DATA_GET(obj, sd);
5752 if (!sd->items) return NULL;
5754 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
5755 return (Elm_Object_Item *)it;
5758 EAPI Elm_Object_Item *
5759 elm_genlist_item_next_get(const Elm_Object_Item *item)
5763 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
5765 it = (Elm_Gen_Item *)item;
5768 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5772 return (Elm_Object_Item *)it;
5775 EAPI Elm_Object_Item *
5776 elm_genlist_item_prev_get(const Elm_Object_Item *item)
5780 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
5782 it = (Elm_Gen_Item *)item;
5785 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5789 return (Elm_Object_Item *)it;
5792 EAPI Elm_Object_Item *
5793 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5795 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
5797 return (Elm_Object_Item *)((Elm_Gen_Item *)it)->parent;
5801 elm_genlist_item_subitems_clear(Elm_Object_Item *item)
5803 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5805 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5806 _item_sub_items_clear(it);
5810 elm_genlist_item_selected_set(Elm_Object_Item *item,
5813 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5814 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5816 if (elm_widget_item_disabled_get(it)) return;
5817 selected = !!selected;
5818 if (it->selected == selected) return;
5820 _item_select_unselect(it, selected);
5824 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5826 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5828 return ((Elm_Gen_Item *)it)->selected;
5831 static Elm_Gen_Item *
5832 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5836 if (it->item->expanded)
5838 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
5842 it2 = (Elm_Gen_Item *)elm_genlist_item_next_get((Elm_Object_Item *)it);
5845 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5846 it2 = (Elm_Gen_Item *)
5847 elm_genlist_item_next_get((Elm_Object_Item *)it2);
5853 static Evas_Object *
5854 _tray_alpha_bg_create(const Evas_Object *obj)
5856 Evas_Object *bg = NULL;
5857 Evas_Coord ox, oy, ow, oh;
5859 ELM_GENLIST_CHECK(obj) NULL;
5860 ELM_GENLIST_DATA_GET(obj, sd);
5862 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
5863 bg = evas_object_rectangle_add
5864 (evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
5865 evas_object_color_set(bg, 0, 0, 0, 0);
5866 evas_object_resize(bg, ow, oh);
5867 evas_object_move(bg, ox, oy);
5873 elm_genlist_item_expanded_set(Elm_Object_Item *item,
5876 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5878 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5880 expanded = !!expanded;
5881 if (it->item->expanded == expanded) return;
5882 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
5883 it->item->expanded = expanded;
5884 GL_IT(it)->wsd->expanded_item = it;
5885 GL_IT(it)->wsd->expanded_next_item =
5886 _elm_genlist_expanded_next_item_get(it);
5888 if (it->item->expanded)
5891 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
5892 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
5893 GL_IT(it)->wsd->auto_scroll_enabled = EINA_TRUE;
5898 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
5899 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
5900 GL_IT(it)->wsd->auto_scroll_enabled = EINA_FALSE;
5905 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5907 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5909 return ((Elm_Gen_Item *)it)->item->expanded;
5913 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5915 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
5917 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5921 _elm_genlist_item_coordinates_calc(Elm_Object_Item *item,
5922 Elm_Genlist_Item_Scrollto_Type type,
5929 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5930 Evas_Coord gith = 0;
5932 if (!((GL_IT(it)->wsd->homogeneous) &&
5933 (GL_IT(it)->wsd->mode == ELM_LIST_COMPRESS)))
5935 if ((it->item->queued) || (!it->item->mincalcd))
5937 GL_IT(it)->wsd->show_item = it;
5938 GL_IT(it)->wsd->bring_in = bring_in;
5939 GL_IT(it)->wsd->scroll_to_type = type;
5940 it->item->show_me = EINA_TRUE;
5944 if (GL_IT(it)->wsd->show_item)
5946 GL_IT(it)->wsd->show_item->item->show_me = EINA_FALSE;
5947 GL_IT(it)->wsd->show_item = NULL;
5950 evas_object_geometry_get(GL_IT(it)->wsd->pan_obj, NULL, NULL, w, h);
5953 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5954 if ((it->item->group_item) &&
5955 (GL_IT(it)->wsd->pan_y > (it->y + it->item->block->y)))
5956 gith = it->item->group_item->item->h;
5958 *y = it->y + it->item->block->y - gith;
5961 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5962 if (it->item->group_item) gith = it->item->group_item->item->h;
5963 *y = it->y + it->item->block->y - gith;
5966 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5967 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
5974 *x = it->x + it->item->block->x;
5975 *w = it->item->block->w;
5981 elm_genlist_item_promote(Elm_Object_Item *item)
5983 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5984 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5986 (it, (Elm_Gen_Item *)elm_genlist_first_item_get(WIDGET(it)));
5990 elm_genlist_item_demote(Elm_Object_Item *item)
5992 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
5993 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
5994 _item_move_after(it, (Elm_Gen_Item *)elm_genlist_last_item_get(WIDGET(it)));
5998 elm_genlist_item_show(Elm_Object_Item *item,
5999 Elm_Genlist_Item_Scrollto_Type type)
6001 Evas_Coord x, y, w, h;
6002 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6003 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6005 if (_elm_genlist_item_coordinates_calc
6006 (item, type, EINA_FALSE, &x, &y, &w, &h))
6007 GL_IT(it)->wsd->s_iface->content_region_show(WIDGET(item), x, y, w, h);
6011 elm_genlist_item_bring_in(Elm_Object_Item *item,
6012 Elm_Genlist_Item_Scrollto_Type type)
6014 Evas_Coord x, y, w, h;
6015 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6016 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6018 if (_elm_genlist_item_coordinates_calc
6019 (item, type, EINA_TRUE, &x, &y, &w, &h))
6020 GL_IT(it)->wsd->s_iface->region_bring_in(WIDGET(item), x, y, w, h);
6024 elm_genlist_item_all_contents_unset(Elm_Object_Item *item,
6027 Evas_Object *content;
6029 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6030 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6032 EINA_LIST_FREE (it->content_objs, content)
6034 evas_object_smart_member_del(content);
6035 evas_object_hide(content);
6036 if (l) *l = eina_list_append(*l, content);
6041 elm_genlist_item_update(Elm_Object_Item *item)
6043 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6044 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6046 if (!it->item->block) return;
6047 it->item->mincalcd = EINA_FALSE;
6048 it->item->updateme = EINA_TRUE;
6049 it->item->block->updateme = EINA_TRUE;
6050 #if GENLIST_ENTRY_SUPPORT
6051 it->item->unrealize_disabled = EINA_FALSE;
6054 #if GENLIST_FX_SUPPORT
6055 _elm_genlist_fx_clear(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj, EINA_FALSE);
6058 if (GL_IT(it)->wsd->update_job) ecore_job_del(GL_IT(it)->wsd->update_job);
6059 GL_IT(it)->wsd->update_job = ecore_job_add(_update_job, GL_IT(it)->wsd);
6063 elm_genlist_item_fields_update(Elm_Object_Item *item,
6065 Elm_Genlist_Item_Field_Type itf)
6067 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6068 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6070 if (!it->item->block) return;
6072 #if GENLIST_ENTRY_SUPPORT
6073 it->item->unrealize_disabled = EINA_FALSE;
6075 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
6077 _item_text_realize(it, VIEW(it), &it->texts, parts);
6079 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
6081 it->content_objs = _item_content_unrealize(it, VIEW(it),
6082 &it->contents, parts);
6083 it->content_objs = _item_content_realize(it, VIEW(it),
6084 &it->contents, parts);
6088 it->item->flip_content_objs =
6089 _item_mode_content_unrealize(it, VIEW(it),
6090 &it->item->flip_contents, parts,
6091 &it->item->flip_content_objs);
6092 it->item->flip_content_objs =
6093 _item_mode_content_realize(it, VIEW(it),
6094 &it->item->flip_contents, parts,
6095 &it->item->flip_content_objs);
6097 if (it->item->deco_it_view)
6099 it->item->deco_it_content_objs =
6100 _item_mode_content_unrealize(it, it->item->deco_it_view,
6101 &it->item->deco_it_contents, parts,
6102 &it->item->deco_it_content_objs);
6103 it->item->deco_it_content_objs =
6104 _item_mode_content_realize(it, it->item->deco_it_view,
6105 &it->item->deco_it_contents, parts,
6106 &it->item->deco_it_content_objs);
6108 if (GL_IT(it)->wsd->decorate_all_mode)
6110 it->item->deco_all_content_objs =
6111 _item_mode_content_unrealize
6112 (it, it->deco_all_view, &it->item->deco_all_contents, parts,
6113 &it->item->deco_all_content_objs);
6114 it->item->deco_all_content_objs =
6115 _item_mode_content_realize(it, it->deco_all_view,
6116 &it->item->deco_all_contents, parts,
6117 &it->item->deco_all_content_objs);
6121 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
6122 _item_state_realize(it, VIEW(it), &it->states, parts);
6126 elm_genlist_item_item_class_update(Elm_Object_Item *item,
6127 const Elm_Genlist_Item_Class *itc)
6129 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6130 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6132 if (!it->item->block) return;
6133 EINA_SAFETY_ON_NULL_RETURN(itc);
6135 it->item->nocache_once = EINA_TRUE;
6137 elm_widget_stringlist_free(it->texts);
6139 elm_widget_stringlist_free(it->contents);
6140 it->contents = NULL;
6141 elm_widget_stringlist_free(it->states);
6146 elm_widget_stringlist_free(it->item->flip_contents);
6147 it->item->flip_contents = NULL;
6149 if (it->item->deco_it_view)
6151 elm_widget_stringlist_free(it->item->deco_it_texts);
6152 it->item->deco_it_texts = NULL;
6153 elm_widget_stringlist_free(it->item->deco_it_contents);
6154 it->item->deco_it_contents = NULL;
6156 if (GL_IT(it)->wsd->decorate_all_mode)
6158 elm_widget_stringlist_free(it->item->deco_all_texts);
6159 it->item->deco_all_texts = NULL;
6160 elm_widget_stringlist_free(it->item->deco_all_contents);
6161 it->item->deco_all_contents = NULL;
6164 elm_genlist_item_update(item);
6167 EAPI const Elm_Genlist_Item_Class *
6168 elm_genlist_item_item_class_get(const Elm_Object_Item *item)
6170 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6171 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6175 static Evas_Object *
6176 _elm_genlist_item_label_create(void *data,
6177 Evas_Object *obj __UNUSED__,
6178 Evas_Object *tooltip,
6179 void *it __UNUSED__)
6181 Evas_Object *label = elm_label_add(tooltip);
6186 elm_object_style_set(label, "tooltip");
6187 elm_object_text_set(label, data);
6193 _elm_genlist_item_label_del_cb(void *data,
6194 Evas_Object *obj __UNUSED__,
6195 void *event_info __UNUSED__)
6197 eina_stringshare_del(data);
6201 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
6204 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6206 text = eina_stringshare_add(text);
6207 elm_genlist_item_tooltip_content_cb_set
6208 (it, _elm_genlist_item_label_create, text,
6209 _elm_genlist_item_label_del_cb);
6213 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
6214 Elm_Tooltip_Item_Content_Cb func,
6216 Evas_Smart_Cb del_cb)
6218 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6220 ELM_GENLIST_ITEM_CHECK_OR_GOTO(item, error);
6222 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
6225 if (it->tooltip.del_cb)
6226 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6228 it->tooltip.content_cb = func;
6229 it->tooltip.data = data;
6230 it->tooltip.del_cb = del_cb;
6234 elm_widget_item_tooltip_content_cb_set
6235 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
6236 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
6237 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
6243 if (del_cb) del_cb((void *)data, NULL, NULL);
6247 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
6249 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6251 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6253 if ((VIEW(it)) && (it->tooltip.content_cb))
6254 elm_widget_item_tooltip_unset(it);
6256 if (it->tooltip.del_cb)
6257 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6258 it->tooltip.del_cb = NULL;
6259 it->tooltip.content_cb = NULL;
6260 it->tooltip.data = NULL;
6261 it->tooltip.free_size = EINA_FALSE;
6262 if (it->tooltip.style)
6263 elm_genlist_item_tooltip_style_set(item, NULL);
6267 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
6270 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6272 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6274 eina_stringshare_replace(&it->tooltip.style, style);
6275 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
6279 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
6281 return elm_object_item_tooltip_style_get(it);
6285 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
6288 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6290 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
6292 it->tooltip.free_size = disable;
6293 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
6299 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
6301 return elm_object_tooltip_window_mode_get(VIEW(it));
6305 elm_genlist_item_cursor_set(Elm_Object_Item *item,
6308 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6310 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6311 eina_stringshare_replace(&it->mouse_cursor, cursor);
6312 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
6316 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
6318 return elm_widget_item_cursor_get(it);
6322 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
6324 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6326 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6328 if (!it->mouse_cursor) return;
6330 if (VIEW(it)) elm_widget_item_cursor_unset(it);
6332 eina_stringshare_del(it->mouse_cursor);
6333 it->mouse_cursor = NULL;
6337 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
6340 elm_widget_item_cursor_style_set(it, style);
6344 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
6346 return elm_widget_item_cursor_style_get(it);
6350 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
6351 Eina_Bool engine_only)
6353 elm_widget_item_cursor_engine_only_set(it, engine_only);
6357 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
6359 return elm_widget_item_cursor_engine_only_get(it);
6363 elm_genlist_item_index_get(const Elm_Object_Item *item)
6367 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6369 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, -1);
6371 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
6373 if (tmp == it) break;
6380 elm_genlist_mode_set(Evas_Object *obj,
6383 ELM_GENLIST_CHECK(obj);
6384 ELM_GENLIST_DATA_GET(obj, sd);
6386 if (sd->mode == mode) return;
6388 elm_layout_sizing_eval(obj);
6392 elm_genlist_mode_get(const Evas_Object *obj)
6394 ELM_GENLIST_CHECK(obj) ELM_LIST_LAST;
6395 ELM_GENLIST_DATA_GET(obj, sd);
6401 elm_genlist_bounce_set(Evas_Object *obj,
6405 ELM_GENLIST_CHECK(obj);
6406 ELM_GENLIST_DATA_GET(obj, sd);
6408 sd->h_bounce = !!h_bounce;
6409 sd->v_bounce = !!v_bounce;
6410 sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
6414 elm_genlist_bounce_get(const Evas_Object *obj,
6415 Eina_Bool *h_bounce,
6416 Eina_Bool *v_bounce)
6418 ELM_GENLIST_CHECK(obj);
6419 ELM_GENLIST_DATA_GET(obj, sd);
6421 if (h_bounce) *h_bounce = sd->h_bounce;
6422 if (v_bounce) *v_bounce = sd->v_bounce;
6426 elm_genlist_homogeneous_set(Evas_Object *obj,
6427 Eina_Bool homogeneous)
6429 ELM_GENLIST_CHECK(obj);
6430 ELM_GENLIST_DATA_GET(obj, sd);
6432 sd->homogeneous = !!homogeneous;
6436 elm_genlist_homogeneous_get(const Evas_Object *obj)
6438 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6439 ELM_GENLIST_DATA_GET(obj, sd);
6441 return sd->homogeneous;
6445 elm_genlist_block_count_set(Evas_Object *obj,
6448 ELM_GENLIST_CHECK(obj);
6449 ELM_GENLIST_DATA_GET(obj, sd);
6450 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
6452 sd->max_items_per_block = count;
6453 sd->item_cache_max = sd->max_items_per_block * 2;
6454 _item_cache_all_free(sd);
6458 elm_genlist_block_count_get(const Evas_Object *obj)
6460 ELM_GENLIST_CHECK(obj) 0;
6461 ELM_GENLIST_DATA_GET(obj, sd);
6463 return sd->max_items_per_block;
6467 elm_genlist_longpress_timeout_set(Evas_Object *obj,
6470 ELM_GENLIST_CHECK(obj);
6471 ELM_GENLIST_DATA_GET(obj, sd);
6473 sd->longpress_timeout = timeout;
6477 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
6479 ELM_GENLIST_CHECK(obj) 0;
6480 ELM_GENLIST_DATA_GET(obj, sd);
6482 return sd->longpress_timeout;
6486 elm_genlist_scroller_policy_set(Evas_Object *obj,
6487 Elm_Scroller_Policy policy_h,
6488 Elm_Scroller_Policy policy_v)
6490 ELM_GENLIST_CHECK(obj);
6491 ELM_GENLIST_DATA_GET(obj, sd);
6493 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
6494 (policy_v >= ELM_SCROLLER_POLICY_LAST))
6497 sd->s_iface->policy_set(obj, policy_h, policy_v);
6501 elm_genlist_scroller_policy_get(const Evas_Object *obj,
6502 Elm_Scroller_Policy *policy_h,
6503 Elm_Scroller_Policy *policy_v)
6505 Elm_Scroller_Policy s_policy_h, s_policy_v;
6507 ELM_GENLIST_CHECK(obj);
6508 ELM_GENLIST_DATA_GET(obj, sd);
6510 sd->s_iface->policy_get(obj, &s_policy_h, &s_policy_v);
6511 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
6512 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
6516 elm_genlist_realized_items_update(Evas_Object *obj)
6518 Eina_List *list, *l;
6519 Elm_Object_Item *it;
6521 ELM_GENLIST_CHECK(obj);
6523 list = elm_genlist_realized_items_get(obj);
6524 EINA_LIST_FOREACH(list, l, it)
6525 elm_genlist_item_update(it);
6529 elm_genlist_item_decorate_mode_set(Elm_Object_Item *item,
6530 const char *decorate_it_type,
6531 Eina_Bool decorate_it_set)
6533 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6534 Elm_Genlist_Smart_Data *sd;
6536 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6537 sd = GL_IT(it)->wsd;
6539 if (elm_widget_item_disabled_get(it)) return;
6540 if (!decorate_it_type) return;
6541 if (sd->decorate_all_mode) return;
6543 if ((sd->mode_item == it) &&
6544 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
6547 if (!it->itc->decorate_item_style) return;
6548 it->decorate_it_set = decorate_it_set;
6551 if (((sd->decorate_it_type)
6552 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
6553 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
6554 _decorate_item_unset(sd);
6556 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
6557 if (decorate_it_set) _decorate_item_set(it);
6561 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *item)
6563 Elm_Gen_Item *i = (Elm_Gen_Item *)item;
6565 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6566 return GL_IT(i)->wsd->decorate_it_type;
6569 EAPI Elm_Object_Item *
6570 elm_genlist_decorated_item_get(const Evas_Object *obj)
6572 ELM_GENLIST_CHECK(obj) NULL;
6573 ELM_GENLIST_DATA_GET(obj, sd);
6575 return (Elm_Object_Item *)sd->mode_item;
6579 elm_genlist_decorate_mode_get(const Evas_Object *obj)
6581 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6582 ELM_GENLIST_DATA_GET(obj, sd);
6584 return sd->decorate_all_mode;
6588 elm_genlist_decorate_mode_set(Evas_Object *obj,
6589 Eina_Bool decorated)
6592 Eina_List *list, *l;
6594 ELM_GENLIST_CHECK(obj);
6595 ELM_GENLIST_DATA_GET(obj, sd);
6597 decorated = !!decorated;
6598 if (sd->decorate_all_mode == decorated) return;
6599 // decorate_all_mode should be set first
6600 // because content_get func. will be called after this
6601 // and user can check whether deocrate_all_mode is enabeld.
6602 sd->decorate_all_mode = decorated;
6604 list = elm_genlist_realized_items_get(obj);
6605 if (!sd->decorate_all_mode)
6607 EINA_LIST_FOREACH(list, l, it)
6609 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6610 _decorate_all_item_unrealize(it);
6612 _item_cache_all_free(sd);
6616 EINA_LIST_FOREACH(list, l, it)
6618 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6620 if (it->itc->decorate_all_item_style)
6621 _decorate_all_item_realize(it, EINA_TRUE);
6625 #if GENLIST_FX_SUPPORT
6626 _elm_genlist_fx_clear(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
6628 if (sd->calc_job) ecore_job_del(sd->calc_job);
6629 sd->calc_job = ecore_job_add(_calc_job, sd);
6633 elm_genlist_reorder_mode_set(Evas_Object *obj,
6634 Eina_Bool reorder_mode)
6636 #if 1 // FIXME: difference from upstream
6637 Eina_List *list, *l;
6640 ELM_GENLIST_CHECK(obj);
6641 ELM_GENLIST_DATA_GET(obj, sd);
6643 if (sd->reorder_mode == !!reorder_mode) return;
6644 sd->reorder_mode = !!reorder_mode;
6645 #if 1 // FIXME: difference from upstream
6646 list = elm_genlist_realized_items_get(obj);
6647 EINA_LIST_FOREACH(list, l, it)
6649 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6651 if (sd->reorder_mode)
6652 edje_object_signal_emit
6653 (VIEW(it), "elm,state,reorder,mode_set", "elm");
6655 edje_object_signal_emit
6656 (VIEW(it), "elm,state,reorder,mode_unset", "elm");
6658 if (sd->decorate_all_mode)
6660 if (sd->reorder_mode)
6661 edje_object_signal_emit
6662 (it->deco_all_view, "elm,state,reorder,mode_set", "elm");
6664 edje_object_signal_emit
6665 (it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
6668 eina_list_free(list);
6673 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6675 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6676 ELM_GENLIST_DATA_GET(obj, sd);
6678 return sd->reorder_mode;
6681 EAPI Elm_Genlist_Item_Type
6682 elm_genlist_item_type_get(const Elm_Object_Item *item)
6684 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6686 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_GENLIST_ITEM_MAX);
6688 return it->item->type;
6691 EAPI Elm_Genlist_Item_Class *
6692 elm_genlist_item_class_new(void)
6694 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
6695 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6697 itc->version = CLASS_ALLOCATED;
6699 itc->delete_me = EINA_FALSE;
6705 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6707 if (itc && (itc->version == CLASS_ALLOCATED))
6709 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6710 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6720 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6722 if (itc && (itc->version == CLASS_ALLOCATED))
6725 if (itc->refcount == 0) itc->refcount--;
6730 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6732 if (itc && (itc->version == CLASS_ALLOCATED))
6734 if (itc->refcount > 0) itc->refcount--;
6735 if (itc->delete_me && (!itc->refcount))
6736 elm_genlist_item_class_free(itc);
6741 elm_genlist_item_flip_set(Elm_Object_Item *item,
6744 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6745 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6746 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
6749 if (it->flipped == flip) return;
6751 it->item->unrealize_disabled = EINA_FALSE;
6755 _item_unrealize(it, EINA_FALSE);
6756 it->flipped = EINA_TRUE;
6757 it->item->nocache = EINA_TRUE;
6761 _item_unrealize(it, EINA_FALSE);
6762 it->flipped = EINA_FALSE;
6763 it->item->nocache = EINA_FALSE;
6765 if (sd->calc_job) ecore_job_del(sd->calc_job);
6766 sd->calc_job = ecore_job_add(_calc_job, sd);
6770 elm_genlist_item_flip_get(const Elm_Object_Item *item)
6772 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6774 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
6780 elm_genlist_select_mode_set(Evas_Object *obj,
6781 Elm_Object_Select_Mode mode)
6783 ELM_GENLIST_CHECK(obj);
6784 ELM_GENLIST_DATA_GET(obj, sd);
6786 if (mode >= ELM_OBJECT_SELECT_MODE_MAX || (sd->select_mode == mode))
6789 sd->select_mode = mode;
6790 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
6791 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
6795 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it)
6800 EAPI Elm_Object_Select_Mode
6801 elm_genlist_select_mode_get(const Evas_Object *obj)
6803 ELM_GENLIST_CHECK(obj) ELM_OBJECT_SELECT_MODE_MAX;
6804 ELM_GENLIST_DATA_GET(obj, sd);
6806 return sd->select_mode;
6810 elm_genlist_highlight_mode_set(Evas_Object *obj,
6811 Eina_Bool highlight)
6813 ELM_GENLIST_CHECK(obj);
6814 ELM_GENLIST_DATA_GET(obj, sd);
6816 sd->highlight = !!highlight;
6820 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6822 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6823 ELM_GENLIST_DATA_GET(obj, sd);
6825 return sd->highlight;
6829 elm_genlist_item_select_mode_set(Elm_Object_Item *item,
6830 Elm_Object_Select_Mode mode)
6832 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6834 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6836 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6838 if (it->select_mode != mode)
6839 it->select_mode = mode;
6841 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
6842 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
6845 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6847 it->item->mincalcd = EINA_FALSE;
6848 it->item->updateme = EINA_TRUE;
6849 if (it->item->block) it->item->block->updateme = EINA_TRUE;
6850 if (GL_IT(it)->wsd->update_job)
6851 ecore_job_del(GL_IT(it)->wsd->update_job);
6852 GL_IT(it)->wsd->update_job =
6853 ecore_job_add(_update_job, GL_IT(it)->wsd);
6855 // reset homogeneous item size
6856 if (GL_IT(it)->wsd->homogeneous)
6859 GL_IT(it)->wsd->group_item_width =
6860 GL_IT(it)->wsd->group_item_height = 0;
6862 GL_IT(it)->wsd->item_width = GL_IT(it)->wsd->item_height = 0;
6867 EAPI Elm_Object_Select_Mode
6868 elm_genlist_item_select_mode_get(const Elm_Object_Item *item)
6870 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6872 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, ELM_OBJECT_SELECT_MODE_MAX);
6874 if (!it) return ELM_OBJECT_SELECT_MODE_MAX;
6876 return it->select_mode;
6879 // will be deprecated
6881 elm_genlist_tree_effect_enabled_set(Evas_Object *obj __UNUSED__,
6882 Eina_Bool enabled __UNUSED__)
6884 ELM_GENLIST_CHECK(obj);
6887 // will be deprecated
6889 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj __UNUSED__)
6891 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6896 EAPI Elm_Object_Item *
6897 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
6899 Elm_Gen_Item *it = NULL;
6903 ELM_GENLIST_CHECK(obj) NULL;
6904 ELM_GENLIST_DATA_GET(obj, sd);
6906 if (!sd->items) return NULL;
6908 a = eina_inlist_accessor_new(sd->items);
6909 if (!a) return NULL;
6910 if (eina_accessor_data_get(a, nth, &data))
6911 it = ELM_GEN_ITEM_FROM_INLIST(data);
6912 eina_accessor_free(a);
6913 return (Elm_Object_Item *)it;
6916 #if GENLIST_FX_SUPPORT
6918 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
6920 ELM_GENLIST_CHECK(obj);
6921 ELM_GENLIST_DATA_GET(obj, sd);
6927 elm_genlist_fx_mode_get(const Evas_Object *obj)
6929 ELM_GENLIST_CHECK(obj) EINA_FALSE;
6930 ELM_GENLIST_DATA_GET(obj, sd);
6936 _elm_genlist_proxy_item_del(const Elm_Object_Item *item)
6938 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6939 if ((!it) || (!it->item)) return;
6941 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
6945 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
6946 if (pi->it == it) pi->it = NULL;
6948 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
6949 if (pi->it == it) pi->it = NULL;
6953 _elm_genlist_proxy_item_new(const Elm_Object_Item *item)
6955 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
6956 if ((!it) || (!it->item)) return EINA_FALSE;
6959 Proxy_Item *pi = NULL;
6960 pi = calloc(1, sizeof(Proxy_Item));
6961 if (!pi) return NULL;
6963 pi->proxy = evas_object_image_filled_add
6964 (evas_object_evas_get(ELM_WIDGET_DATA(GL_IT(it)->wsd)->obj));
6965 if (!pi->proxy) return EINA_FALSE;
6966 evas_object_clip_set(pi->proxy, evas_object_clip_get(GL_IT(it)->wsd->pan_obj));
6967 evas_object_smart_member_add(pi->proxy, GL_IT(it)->wsd->pan_obj);
6968 evas_object_hide(pi->proxy);
6970 if ((GL_IT(it)->wsd->decorate_all_mode) && (it->deco_all_view))
6971 evas_object_image_source_set(pi->proxy, it->deco_all_view);
6973 evas_object_image_source_set(pi->proxy, VIEW(it));
6975 GL_IT(it)->has_proxy_it = EINA_TRUE;
6977 pi->num = it->item->num;
6978 pi->x = it->item->scrl_x;
6979 pi->y = it->item->scrl_y;
6980 pi->w = it->item->w;
6981 pi->h = it->item->h;
6983 evas_object_geometry_get(VIEW(it), NULL, NULL, &w, &h);
6985 if (w <= 0 || h <= 0)
6987 evas_object_size_hint_min_get(VIEW(it), &w, &h);
6988 evas_object_size_hint_min_set(pi->proxy, w, h);
6990 else evas_object_resize(pi->proxy, w, h);
6996 _elm_genlist_fx_capture(Evas_Object *obj, int level)
6998 ELM_GENLIST_DATA_GET(obj, sd);
7002 Eina_Bool done = EINA_FALSE;
7005 Evas_Coord ox, oy, ow, oh;
7009 if ((!sd->rendered) || (sd->fx_playing)) return EINA_FALSE;
7010 if ((!level) && (sd->fx_first_captured)) return EINA_FALSE;
7011 if ((level) && (!sd->fx_first_captured)) return EINA_FALSE;
7013 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7017 sd->fx_first_captured = EINA_TRUE;
7018 EINA_LIST_FREE(sd->capture_before_items, pi)
7020 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
7021 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
7022 if (pi->proxy) evas_object_del(pi->proxy);
7028 EINA_LIST_FREE(sd->capture_after_items, pi)
7030 if ((pi->it) && (GL_IT(pi->it))) GL_IT(pi->it)->has_proxy_it = EINA_FALSE;
7031 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
7032 if (pi->proxy) evas_object_del(pi->proxy);
7036 EINA_INLIST_FOREACH(sd->blocks, itb)
7040 EINA_LIST_FOREACH(itb->items, l, it)
7042 if (it->realized && it->item->scrl_y >= oy)
7044 sd->realized_top_item = it;
7049 if (sd->realized_top_item) break;
7053 #if GENLIST_PINCH_ZOOM_SUPPORT
7054 if (sd->pinch_zoom_mode)
7056 EINA_INLIST_FOREACH(sd->blocks, itb)
7058 EINA_LIST_FOREACH(itb->items, l, it)
7061 if (IS_ROOT_PARENT_IT(it) && it->realized
7062 && (GL_IT(it)->scrl_y + GL_IT(it)->h >= oy && GL_IT(it)->scrl_y <= oy + oh))
7064 pi = _elm_genlist_proxy_item_new((Elm_Object_Item *)it);
7065 if (!level) sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
7066 else sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
7070 if ((sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT) && (level)) return EINA_TRUE;
7071 if ((sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_EXPAND) && (!level)) return EINA_TRUE;
7075 EINA_INLIST_FOREACH(sd->blocks, itb)
7080 EINA_LIST_FOREACH(itb->items, l, it)
7082 #if GENLIST_PINCH_ZOOM_SUPPORT
7083 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7087 pi = _elm_genlist_proxy_item_new((Elm_Object_Item *)it);
7090 sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
7092 sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
7096 else if (done) break;
7101 static Elm_Gen_FX_Item *
7102 _elm_genlist_fx_item_find(const Elm_Object_Item *item)
7104 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
7105 if (!it) return EINA_FALSE;
7107 Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
7108 if (!sd) return NULL;
7110 Elm_Gen_FX_Item *fi = NULL;
7113 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7115 if (fi->it == it) return fi;
7120 static Elm_Gen_FX_Item *
7121 _elm_genlist_fx_item_new(const Proxy_Item *pi)
7123 if ((!pi) || (!pi->it)) return NULL;
7125 Elm_Gen_FX_Item *fi = NULL;
7126 fi = calloc(1, sizeof(Elm_Gen_FX_Item));
7127 if (!fi) return NULL;
7130 GL_IT(fi->it)->fi = fi;
7131 fi->proxy = pi->proxy;
7133 fi->from.x = fi->to.x = pi->x;
7134 fi->from.y = fi->to.y = pi->y;
7135 fi->from.w = fi->to.w = pi->w;
7136 fi->from.h = fi->to.h = pi->h;
7137 fi->update = EINA_FALSE;
7142 static Elm_Object_Item *
7143 _elm_genlist_fx_item_prev_get(const Elm_Object_Item *item)
7146 it = (Elm_Gen_Item *)item;
7147 if (!it) return NULL;
7148 if (GL_IT(it)->wsd->pinch_zoom_mode) return NULL;
7152 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7156 return (Elm_Object_Item *)it;
7160 _elm_genlist_fx_items_make(Evas_Object *obj)
7162 ELM_GENLIST_CHECK(obj) EINA_FALSE;
7163 ELM_GENLIST_DATA_GET(obj, sd);
7165 Elm_Gen_FX_Item *fi;
7168 Elm_Gen_Item *prev = NULL;
7169 Evas_Coord ox, oy, ow, oh, mv_dist, max_mv_dist = 0;
7171 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7173 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7175 fi = _elm_genlist_fx_item_new(pi);
7176 if (fi) sd->fx_items = eina_list_append(sd->fx_items, fi);
7179 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
7181 fi = _elm_genlist_fx_item_find((Elm_Object_Item *)pi->it);
7183 if (fi) // pi exists in both before and after capture items
7185 fi->type = ELM_GEN_ITEM_FX_TYPE_SAME;
7186 fi->update = EINA_TRUE;
7192 // find the max distance between before and after capture items
7193 mv_dist = abs(fi->to.y - fi->from.y);
7194 if (max_mv_dist < mv_dist) max_mv_dist = mv_dist;
7196 else // pi only exists in after capture items
7198 fi = _elm_genlist_fx_item_new(pi);
7201 fi->type = ELM_GEN_ITEM_FX_TYPE_ADD;
7202 fi->update = EINA_TRUE;
7203 sd->fx_items = eina_list_append(sd->fx_items, fi);
7208 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7210 // find deleted items
7211 if (!fi->update) // pi only exists in before capture items
7213 fi->type = ELM_GEN_ITEM_FX_TYPE_DEL;
7214 fi->update = EINA_TRUE;
7216 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7217 if ((prev) && (GL_IT(prev)->fi))
7219 fi->to.y = GL_IT(prev)->fi->to.y + GL_IT(prev)->fi->to.h;
7222 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7224 prev = (Elm_Gen_Item *)_elm_genlist_fx_item_prev_get((Elm_Object_Item *)fi->it);
7225 if ((prev) && (prev->realized) && (GL_IT(prev)->fi))
7227 fi->from.y = GL_IT(prev)->fi->from.y + GL_IT(prev)->fi->from.h;
7231 if (sd->realized_top_item)
7234 if (fi->num <= sd->realized_top_item->item->num)
7235 fi->from.y -= max_mv_dist;
7237 fi->from.y += max_mv_dist;
7243 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7245 if ((GL_IT(fi->it)->items) && (GL_IT(fi->it)->expanded_depth == 0))
7247 #if GENLIST_PINCH_ZOOM_SUPPORT
7248 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7250 fi->from.y = oy + GL_IT(fi->it)->pan_scrl_y - sd->pinch_pan_y;
7253 if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7255 if (sd->realized_top_item)
7257 if (fi->num <= sd->realized_top_item->item->num)
7258 fi->to.y = oy - fi->from.h;
7269 static Elm_Gen_FX_Item *
7270 _fx_cover_item_get(const Elm_Gen_FX_Item *fi)
7272 Elm_Gen_FX_Item *cover_fi;
7274 if (!fi) return NULL;
7276 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7277 Evas_Coord ox, oy, ow, oh;
7278 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7280 EINA_LIST_FOREACH(sd->fx_items, l, cover_fi)
7282 if (fi == cover_fi) continue;
7283 if (sd->fx_items_deleted)
7285 if ((cover_fi->from.y >= oy+oh || cover_fi->from.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y > 0))
7290 if ((cover_fi->to.y > fi->to.y) && (cover_fi->from.y - cover_fi->to.y < 0))
7298 _item_fx_op(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__, double progress __UNUSED__)
7300 Elm_Gen_FX_Item *fi = data, *cover_it;
7301 Elm_Genlist_Smart_Data *sd = GL_IT(fi->it)->wsd;
7302 Evas_Coord fi_ox, fi_oy, cover_it_ox, cover_it_oy, ox, oy, ow, oh;
7304 evas_object_show(VIEW(fi->it));
7305 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7306 evas_object_geometry_get(fi->proxy, &fi_ox, &fi_oy, NULL, NULL);
7307 evas_object_move(fi->proxy, ox, fi_oy);
7308 evas_object_show(fi->proxy);
7309 #if GENLIST_PINCH_ZOOM_SUPPORT
7310 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(fi->it))) evas_object_raise(fi->proxy);
7313 if ((!sd->expanded_next_item) || (sd->expanded_next_item == fi->it)) goto raise_event_block;
7314 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME) goto raise_event_block;
7316 // find the closest item that cover current item when deleting
7317 cover_it = _fx_cover_item_get(fi);
7320 evas_object_geometry_get(cover_it->proxy, &cover_it_ox, &cover_it_oy, NULL, NULL);
7322 if (sd->fx_items_deleted)
7325 && (fi_oy + fi->to.h >= cover_it_oy + cover_it->to.h ) && (fi->from.y < cover_it->from.y))
7326 evas_object_hide(fi->proxy);
7328 else if (cover_it_oy && (fi_oy >= cover_it_oy))
7329 evas_object_hide(fi->proxy);
7331 evas_object_show(fi->proxy);
7335 evas_object_raise(sd->alpha_bg);
7342 _item_fx_done(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__)
7344 Elm_Gen_FX_Item *fx_done_it = data;
7345 Elm_Genlist_Smart_Data *sd = GL_IT(fx_done_it->it)->wsd;
7347 if ((!fx_done_it) || (!fx_done_it->it) || (!sd)) return;
7349 evas_object_image_source_visible_set(fx_done_it->proxy, EINA_TRUE);
7350 evas_object_lower(fx_done_it->proxy);
7352 if ((sd->decorate_all_mode) && (fx_done_it->it->deco_all_view))
7353 evas_object_move(fx_done_it->it->deco_all_view, fx_done_it->to.x, fx_done_it->to.y);
7355 evas_object_move(VIEW(fx_done_it->it), fx_done_it->to.x, fx_done_it->to.y);
7356 GL_IT(fx_done_it->it)->has_proxy_it = EINA_FALSE;
7358 evas_object_clip_unset(fx_done_it->proxy);
7362 _item_fx_del_cb(void *data, Elm_Transit *transit __UNUSED__)
7364 Elm_Gen_FX_Item *fx_done_it = data;
7365 Elm_Gen_Item *it = NULL;
7366 Proxy_Item *pi = NULL;
7368 Elm_Genlist_Smart_Data *sd = GL_IT(fx_done_it->it)->wsd;
7370 if ((!fx_done_it) || (!fx_done_it->it) || (!sd)) return;
7372 sd->fx_items = eina_list_remove(sd->fx_items, fx_done_it);
7373 GL_IT(fx_done_it->it)->fi = NULL;
7376 if (!eina_list_count(sd->fx_items))
7378 EINA_LIST_FREE (sd->pending_unrealized_items, it)
7380 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7381 #if GENLIST_PINCH_ZOOM_SUPPORT
7382 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7384 _item_unrealize(it, EINA_FALSE);
7386 EINA_LIST_FREE (sd->pending_unrealized_decorate_all_items, it)
7388 if (GL_IT(it)) GL_IT(it)->has_proxy_it = EINA_FALSE;
7389 #if GENLIST_PINCH_ZOOM_SUPPORT
7390 if ((sd->pinch_zoom_mode) && (IS_ROOT_PARENT_IT(it))) continue;
7392 _decorate_all_item_unrealize(it);
7395 EINA_LIST_FREE (sd->pending_del_items, it)
7398 _elm_widget_item_free((Elm_Widget_Item *)it);
7401 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
7402 evas_object_hide(pi->proxy);
7403 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
7404 evas_object_hide(pi->proxy);
7406 sd->fx_playing = EINA_FALSE;
7407 sd->sorting = EINA_FALSE;
7408 sd->fx_first_captured = EINA_FALSE;
7409 evas_object_hide(sd->alpha_bg);
7411 sd->realized_top_item = NULL;
7412 sd->pan_changed = EINA_TRUE;
7413 evas_object_smart_changed(sd->pan_obj);
7418 _sorting_effect_animator_cb(void *data)
7420 Elm_Genlist_Smart_Data *sd = data;
7421 Elm_Gen_FX_Item *fi;
7424 Evas_Coord ox, oy, ow, oh;
7425 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7427 sd->fx_timer = NULL;
7428 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7432 fi->changed = EINA_TRUE;
7433 evas_object_resize(fi->proxy, ow, fi->to.h);
7435 fi->trans = elm_transit_add();
7436 elm_transit_object_add(fi->trans, fi->proxy);
7437 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7438 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7440 elm_transit_effect_translation_add(fi->trans, fi->to.x, fi->to.y - 30 * elm_config_scale_get(), fi->to.x, fi->to.y);
7441 elm_transit_effect_color_add(fi->trans,0, 0, 0, 0, 255,255,255,255);
7443 elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
7444 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7445 elm_transit_duration_set(fi->trans,0.3);
7446 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7447 elm_transit_go(fi->trans);
7449 return ECORE_CALLBACK_RENEW;
7452 return ECORE_CALLBACK_CANCEL;
7456 _elm_genlist_fx_play(Evas_Object *obj)
7458 ELM_GENLIST_CHECK(obj);
7459 ELM_GENLIST_DATA_GET(obj, sd);
7461 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
7462 Elm_Gen_FX_Item *fi;
7465 if (!sd->fx_mode) return;
7467 EINA_LIST_FREE(sd->fx_items, fi)
7469 if (fi->trans) elm_transit_del(fi->trans);
7472 _item_cache_all_free(sd);
7474 _elm_genlist_fx_items_make(obj);
7475 if (!eina_list_count(sd->fx_items) || (sd->queue))
7477 _elm_genlist_fx_clear(obj, EINA_TRUE);
7481 sd->fx_playing = EINA_TRUE;
7483 if (!sd->alpha_bg) sd->alpha_bg = _tray_alpha_bg_create(obj);
7484 evas_object_show(sd->alpha_bg);
7486 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7487 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
7491 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7492 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7493 if (sd->fx_timer) ecore_timer_del(sd->fx_timer);
7494 sd->fx_timer = ecore_timer_add(0.05, _sorting_effect_animator_cb, sd);
7498 EINA_LIST_FOREACH(sd->fx_items, l, fi)
7500 if (!fi->proxy) continue;
7502 if ((fi->from.y <= oy) || (fi->from.y + fi->from.h >= oy + oh))
7504 if ((sd->decorate_all_mode) && (fi->it->deco_all_view))
7505 evas_object_move(fi->it->deco_all_view, cvx, fi->to.y);
7507 evas_object_move(VIEW(fi->it), cvx, fi->to.y);
7509 else if ((fi->to.y <= oy) || (fi->to.y + fi->to.h >= oy + oh))
7511 if ((sd->decorate_all_mode) && (fi->it->deco_all_view))
7512 evas_object_move(fi->it->deco_all_view, cvx, fi->from.y);
7514 evas_object_move(VIEW(fi->it), cvx, fi->from.y);
7517 evas_object_resize(fi->proxy, ow, fi->to.h);
7518 evas_object_show(fi->proxy);
7520 fi->trans = elm_transit_add();
7521 elm_transit_object_add(fi->trans, fi->proxy);
7523 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
7524 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
7526 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME)
7528 evas_object_raise(fi->proxy);
7529 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7532 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
7534 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7535 elm_transit_effect_color_add(fi->trans, 0, 0, 0, 0, 255, 255, 255, 255);
7536 if ((!sd->pinch_zoom_mode) && (!sd->expanded_item))
7537 elm_transit_effect_zoom_add(fi->trans, 0.8, 1.0);
7539 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
7541 _item_unhighlight(fi->it);
7542 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
7543 elm_transit_effect_color_add(fi->trans, 255, 255, 255, 255, 0, 0, 0, 0);
7544 if ((!sd->pinch_zoom_mode) && (!sd->expanded_item))
7545 elm_transit_effect_zoom_add(fi->trans, 1.0, 0.8);
7547 elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
7548 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
7550 elm_transit_duration_set(fi->trans, FX_MOVE_TIME);
7551 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
7552 elm_transit_go(fi->trans);
7557 #if GENLIST_PINCH_ZOOM_SUPPORT
7559 elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Elm_Gen_Pinch_Zoom_Mode mode)
7561 ELM_GENLIST_DATA_GET(obj, sd);
7566 Eina_Bool done = EINA_FALSE;
7568 if ((sd->queue) || (!sd->rendered) || (sd->queue_idle_enterer)) return EINA_FALSE;
7570 EINA_INLIST_FOREACH(sd->blocks, itb)
7572 EINA_LIST_FOREACH(itb->items, l, it)
7575 if (IS_ROOT_PARENT_IT(it))
7583 if (!done) return EINA_FALSE;
7585 sd->pinch_zoom_mode = mode;
7587 _item_cache_all_free(sd);
7588 _elm_genlist_fx_capture(obj, 0);
7590 sd->pinch_pan_y = sd->pan_y;
7592 if (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)
7593 sd->s_iface->content_region_show(obj, 0,0,0,0);
7595 sd->pan_changed = EINA_TRUE;
7596 evas_object_smart_changed(sd->pan_obj);
7603 eina_list_sort_merge(Eina_List *a, Eina_List *b, Eina_Compare_Cb func)
7605 Eina_List *first, *last;
7607 if (func(a->data, b->data) > 0)
7609 _item_move_after(a->data, b->data);
7610 a = (last = first = a)->next;
7614 b = (last = first = b)->next;
7617 if (func(a->data, b->data) > 0)
7619 _item_move_after(a->data, b->data);
7620 a = (last = last->next = a)->next;
7623 b = (last = last->next = b)->next;
7625 last->next = a ? a : b;
7631 elm_genlist_sort(Evas_Object *obj, Eina_Compare_Cb func)
7633 ELM_GENLIST_CHECK(obj) NULL;
7634 ELM_GENLIST_DATA_GET(obj, sd);
7635 Eina_List *list = NULL;
7636 Elm_Gen_Item *it, *next;
7637 unsigned int limit = 0, i = 0, n = 0;
7638 Eina_List *tail = NULL, *unsort = NULL, *stack[32], *prev = NULL;
7640 sd->sorting = EINA_TRUE;
7642 it = (Elm_Gen_Item*)elm_genlist_first_item_get(obj);
7645 list = eina_list_append(list, it);
7646 next = (Elm_Gen_Item*)elm_genlist_item_next_get((Elm_Object_Item *)it);
7654 limit = eina_list_count(list);
7658 (limit > list->accounting->count))
7659 limit = list->accounting->count;
7661 if (limit != list->accounting->count)
7663 unsort = eina_list_nth_list(list, limit);
7665 unsort->prev->next = NULL;
7670 unsigned int idx, tmp;
7672 Eina_List *a = tail;
7673 Eina_List *b = tail->next;
7683 if (func(a->data, b->data) > 0)
7684 ((stack[i++] = a)->next = b)->next = 0;
7686 ((stack[i++] = b)->next = a)->next = 0;
7689 for (idx = n ^ tmp; idx &= idx - 1; i--)
7690 stack[i - 2] = eina_list_sort_merge(stack[i - 2], stack[i - 1], func);
7694 stack[i - 1] = eina_list_sort_merge(stack[i - 1], stack[i], func);
7698 for (; stack[0]; stack[0] = stack[0]->next)
7700 stack[0]->prev = prev;
7707 tail->next = unsort;
7708 unsort->prev = tail;
7711 list->accounting->last = tail;
7713 if (!sd->fx_mode) sd->sorting = EINA_FALSE;
7714 if (sd->decorate_all_mode) sd->sorting = EINA_FALSE;
7715 sd->s_iface->content_region_show(obj, 0,0,0,0);
7716 sd->pan_changed = EINA_TRUE;
7717 evas_object_smart_changed(sd->pan_obj);