3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.h"
9 // internally allocated
10 #define CLASS_ALLOCATED 0x3a70f11f
12 #define MAX_ITEMS_PER_BLOCK 32
13 #define REORDER_EFFECT_TIME 0.5
15 #define ELM_GEN_SETUP(wd) \
16 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
17 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
18 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
32 ERR("Genlist_Item_Class(itc) is NULL"); \
35 if ((itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) && \
36 (itc->version != CLASS_ALLOCATED)) \
38 ERR("Genlist_Item_Class version mismatched! current = (%d), required = (%d) or (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION, CLASS_ALLOCATED); \
44 typedef struct _Item_Block Item_Block;
45 typedef struct _Item_Cache Item_Cache;
47 struct Elm_Gen_Item_Type
52 Evas_Coord w, h, minw, minh;
53 Elm_Gen_Item *group_item;
54 Elm_Genlist_Item_Type type;
55 Eina_List *deco_it_texts, *deco_it_contents, *deco_it_states, *deco_it_content_objs;
56 Eina_List *deco_all_texts, *deco_all_contents, *deco_all_states, *deco_all_content_objs;
57 Eina_List *flip_contents, *flip_content_objs;
58 Ecore_Timer *swipe_timer;
59 Evas_Coord scrl_x, scrl_y, old_scrl_y;
62 Evas_Object *deco_it_view;
68 Eina_Bool want_realize : 1;
69 Eina_Bool expanded : 1;
70 Eina_Bool mincalcd : 1;
73 Eina_Bool updateme : 1;
74 Eina_Bool nocache : 1; /* do not use cache for this item */
75 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
76 Eina_Bool stacking_even : 1;
77 Eina_Bool nostacking : 1;
78 Eina_Bool move_effect_enabled : 1;
79 Eina_Bool decorate_all_item_realized : 1;
80 Eina_Bool tree_effect_finished : 1; /* tree effect */
81 Eina_Bool tree_effect_hideme : 1; /* item hide for tree effect */
92 Evas_Coord x, y, w, h, minw, minh;
94 int item_position_stamp;
96 Eina_Bool position_update : 1;
97 Eina_Bool want_unrealize : 1;
98 Eina_Bool realized : 1;
99 Eina_Bool changed : 1;
100 Eina_Bool updateme : 1;
101 Eina_Bool showme : 1;
102 Eina_Bool must_recalc : 1;
109 Evas_Object *base_view, *spacer;
111 const char *item_style; // it->itc->item_style
112 Eina_Bool tree : 1; // it->group
114 Eina_Bool selected : 1; // it->selected
115 Eina_Bool disabled : 1; // it->disabled
116 Eina_Bool expanded : 1; // it->item->expanded
119 static const char *widtype = NULL;
120 static void _item_cache_zero(Widget_Data *wd);
121 static void _del_hook(Evas_Object *obj);
122 static void _mirrored_set(Evas_Object *obj,
124 static void _theme_hook(Evas_Object *obj);
125 static void _show_region_hook(void *data,
127 static void _sizing_eval(Evas_Object *obj);
128 static void _item_realize(Elm_Gen_Item *it,
131 static void _item_unrealize_cb(Elm_Gen_Item *it);
132 static void _item_block_unrealize(Item_Block *itb);
133 static void _calc_job(void *data);
134 static void _on_focus_hook(void *data,
136 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
137 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
138 static Eina_Bool _item_single_select_up(Widget_Data *wd);
139 static Eina_Bool _item_single_select_down(Widget_Data *wd);
140 static Eina_Bool _event_hook(Evas_Object *obj,
142 Evas_Callback_Type type,
144 static void _signal_emit_hook(Evas_Object *obj,
145 const char *emission,
147 static Eina_Bool _deselect_all_items(Widget_Data *wd);
148 static void _pan_calculate(Evas_Object *obj);
149 static void _pan_max_get(Evas_Object *obj,
152 static void _item_position(Elm_Gen_Item *it,
156 static void _decorate_item_realize(Elm_Gen_Item *it);
157 static void _decorate_item_unrealize(Elm_Gen_Item *it);
158 static void _decorate_item_set(Elm_Gen_Item *it);
159 static void _decorate_item_unset(Widget_Data *wd);
160 static void _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity);
161 static void _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
162 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
163 static void _group_items_recalc(void *data);
164 static void _item_move_after(Elm_Gen_Item *it,
165 Elm_Gen_Item *after);
166 static void _item_move_before(Elm_Gen_Item *it,
167 Elm_Gen_Item *before);
168 static void _item_auto_scroll(Widget_Data *wd);
169 static void _elm_genlist_clear(Evas_Object *obj,
171 static void _pan_child_size_get(Evas_Object *obj,
174 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
175 static void _item_contract_emit(Elm_Gen_Item *it);
176 static int _item_tree_effect_before(Elm_Gen_Item *it);
177 static void _item_tree_effect(Widget_Data *wd, int y);
178 static void _item_tree_effect_finish(Widget_Data *wd);
179 static Eina_Bool _tree_effect_animator_cb(void *data);
181 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
183 static const char SIG_ACTIVATED[] = "activated";
184 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
185 static const char SIG_SELECTED[] = "selected";
186 static const char SIG_UNSELECTED[] = "unselected";
187 static const char SIG_EXPANDED[] = "expanded";
188 static const char SIG_CONTRACTED[] = "contracted";
189 static const char SIG_EXPAND_REQUEST[] = "expand,request";
190 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
191 static const char SIG_REALIZED[] = "realized";
192 static const char SIG_UNREALIZED[] = "unrealized";
193 static const char SIG_DRAG_START_UP[] = "drag,start,up";
194 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
195 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
196 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
197 static const char SIG_DRAG_STOP[] = "drag,stop";
198 static const char SIG_DRAG[] = "drag";
199 static const char SIG_LONGPRESSED[] = "longpressed";
200 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
201 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
202 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
203 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
204 static const char SIG_EDGE_TOP[] = "edge,top";
205 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
206 static const char SIG_EDGE_LEFT[] = "edge,left";
207 static const char SIG_EDGE_RIGHT[] = "edge,right";
208 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
209 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
210 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
211 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
212 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
213 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
214 static const char SIG_SWIPE[] = "swipe";
215 static const char SIG_MOVED[] = "moved";
216 static const char SIG_MOVED_AFTER[] = "moved,after";
217 static const char SIG_MOVED_BEFORE[] = "moved,before";
218 static const char SIG_INDEX_UPDATE[] = "index,update";
219 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
221 static const Evas_Smart_Cb_Description _signals[] = {
222 {SIG_CLICKED_DOUBLE, ""},
225 {SIG_UNSELECTED, ""},
227 {SIG_CONTRACTED, ""},
228 {SIG_EXPAND_REQUEST, ""},
229 {SIG_CONTRACT_REQUEST, ""},
231 {SIG_UNREALIZED, ""},
232 {SIG_DRAG_START_UP, ""},
233 {SIG_DRAG_START_DOWN, ""},
234 {SIG_DRAG_START_LEFT, ""},
235 {SIG_DRAG_START_RIGHT, ""},
238 {SIG_LONGPRESSED, ""},
239 {SIG_SCROLL_ANIM_START, ""},
240 {SIG_SCROLL_ANIM_STOP, ""},
241 {SIG_SCROLL_DRAG_START, ""},
242 {SIG_SCROLL_DRAG_STOP, ""},
244 {SIG_EDGE_BOTTOM, ""},
246 {SIG_EDGE_RIGHT, ""},
247 {SIG_MULTI_SWIPE_LEFT, ""},
248 {SIG_MULTI_SWIPE_RIGHT, ""},
249 {SIG_MULTI_SWIPE_UP, ""},
250 {SIG_MULTI_SWIPE_DOWN, ""},
251 {SIG_MULTI_PINCH_OUT, ""},
252 {SIG_MULTI_PINCH_IN, ""},
255 {SIG_MOVED_AFTER, ""},
256 {SIG_MOVED_BEFORE, ""},
257 {SIG_TREE_EFFECT_FINISHED, ""},
262 #undef ELM_CHECK_WIDTYPE
263 #define ELM_CHECK_WIDTYPE(obj, widtype) \
264 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
265 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
266 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
267 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
268 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
270 static const char *_gengrid = NULL;
271 static const char *_genlist = NULL;
273 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
275 elm_genlist_type_check(const Evas_Object *obj,
278 const char *provided, *expected = "(unknown)";
279 static int abort_on_warn = -1;
280 provided = elm_widget_type_get(obj);
281 if (!_genlist) _genlist = eina_stringshare_add("genlist");
282 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
283 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
285 if ((!provided) || (!provided[0]))
287 provided = evas_object_type_get(obj);
288 if ((!provided) || (!provided[0]))
289 provided = "(unknown)";
291 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
292 if (abort_on_warn == -1)
294 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
295 else abort_on_warn = 0;
297 if (abort_on_warn == 1) abort();
302 _event_hook(Evas_Object *obj,
303 Evas_Object *src __UNUSED__,
304 Evas_Callback_Type type,
307 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
308 Evas_Event_Key_Down *ev = event_info;
309 Widget_Data *wd = elm_widget_data_get(obj);
310 Evas_Coord pan_max_x = 0, pan_max_y = 0;
311 if (!wd) return EINA_FALSE;
312 if (!wd->items) return EINA_FALSE;
313 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
314 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
316 Elm_Object_Item *it = NULL;
319 Evas_Coord step_x = 0;
320 Evas_Coord step_y = 0;
323 Evas_Coord page_x = 0;
324 Evas_Coord page_y = 0;
326 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
327 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
328 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
329 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
331 if ((!strcmp(ev->keyname, "Left")) ||
332 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
336 else if ((!strcmp(ev->keyname, "Right")) ||
337 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
341 else if ((!strcmp(ev->keyname, "Up")) ||
342 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
344 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
345 (_item_multi_select_up(wd)))
346 || (_item_single_select_up(wd)))
348 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
354 else if ((!strcmp(ev->keyname, "Down")) ||
355 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
357 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
358 (_item_multi_select_down(wd)))
359 || (_item_single_select_down(wd)))
361 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
367 else if ((!strcmp(ev->keyname, "Home")) ||
368 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
370 it = elm_genlist_first_item_get(obj);
371 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
372 elm_genlist_item_selected_set(it, EINA_TRUE);
373 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
376 else if ((!strcmp(ev->keyname, "End")) ||
377 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
379 it = elm_genlist_last_item_get(obj);
380 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
381 elm_genlist_item_selected_set(it, EINA_TRUE);
382 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
385 else if ((!strcmp(ev->keyname, "Prior")) ||
386 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
389 y -= -(page_y * v_h) / 100;
393 else if ((!strcmp(ev->keyname, "Next")) ||
394 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
397 y += -(page_y * v_h) / 100;
401 else if (!strcmp(ev->keyname, "Escape"))
403 if (!_deselect_all_items(wd)) return EINA_FALSE;
404 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
407 else if (((!strcmp(ev->keyname, "Return")) ||
408 (!strcmp(ev->keyname, "KP_Enter")) ||
409 (!strcmp(ev->keyname, "space")))
410 && (!wd->multi) && (wd->selected))
412 it = elm_genlist_selected_item_get(obj);
413 elm_genlist_item_expanded_set(it,
414 !elm_genlist_item_expanded_get(it));
415 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
417 else return EINA_FALSE;
419 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
420 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
422 if (x > pan_max_x) x = pan_max_x;
424 if (y > pan_max_y) y = pan_max_y;
425 elm_smart_scroller_child_pos_set(wd->scr, x, y);
430 _deselect_all_items(Widget_Data *wd)
432 if (!wd->selected) return EINA_FALSE;
434 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
440 _item_multi_select_up(Widget_Data *wd)
442 if (!wd->selected) return EINA_FALSE;
443 if (!wd->multi) return EINA_FALSE;
445 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
446 if (!prev) return EINA_TRUE;
448 if (elm_genlist_item_selected_get(prev))
450 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
451 wd->last_selected_item = prev;
452 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
456 elm_genlist_item_selected_set(prev, EINA_TRUE);
457 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
463 _item_multi_select_down(Widget_Data *wd)
465 if (!wd->selected) return EINA_FALSE;
466 if (!wd->multi) return EINA_FALSE;
468 Elm_Object_Item *next;
469 next = elm_genlist_item_next_get(wd->last_selected_item);
470 if (!next) return EINA_TRUE;
472 if (elm_genlist_item_selected_get(next))
474 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
475 wd->last_selected_item = next;
476 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
480 elm_genlist_item_selected_set(next, EINA_TRUE);
481 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
487 _item_single_select_up(Widget_Data *wd)
492 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
493 while ((prev) && (prev->generation < wd->generation))
494 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
496 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
498 if (!prev) return EINA_FALSE;
500 _deselect_all_items(wd);
502 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
503 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
508 _item_single_select_down(Widget_Data *wd)
513 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
514 while ((next) && (next->generation < wd->generation))
515 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
517 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
519 if (!next) return EINA_FALSE;
521 _deselect_all_items(wd);
523 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
524 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
529 _on_focus_hook(void *data __UNUSED__,
532 Widget_Data *wd = elm_widget_data_get(obj);
534 if (elm_widget_focus_get(obj))
536 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
537 evas_object_focus_set(wd->obj, EINA_TRUE);
538 if ((wd->selected) && (!wd->last_selected_item))
539 wd->last_selected_item = eina_list_data_get(wd->selected);
543 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
544 evas_object_focus_set(wd->obj, EINA_FALSE);
549 _del_hook(Evas_Object *obj)
551 Widget_Data *wd = elm_widget_data_get(obj);
553 _item_cache_zero(wd);
554 if (wd->calc_job) ecore_job_del(wd->calc_job);
555 if (wd->update_job) ecore_job_del(wd->update_job);
556 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
557 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
558 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
559 if (wd->decorate_it_type) eina_stringshare_del(wd->decorate_it_type);
560 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
561 if (wd->tree_effect_animator) ecore_animator_del(wd->tree_effect_animator);
566 _del_pre_hook(Evas_Object *obj)
568 Widget_Data *wd = elm_widget_data_get(obj);
570 if (wd->decorate_all_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
571 elm_genlist_clear(obj);
572 evas_object_del(wd->pan_smart);
573 wd->pan_smart = NULL;
577 _mirrored_set(Evas_Object *obj,
580 Widget_Data *wd = elm_widget_data_get(obj);
582 _item_cache_zero(wd);
583 elm_smart_scroller_mirrored_set(wd->scr, rtl);
587 _theme_hook(Evas_Object *obj)
589 Widget_Data *wd = elm_widget_data_get(obj);
592 evas_event_freeze(evas_object_evas_get(wd->obj));
593 _item_cache_zero(wd);
594 _elm_widget_mirrored_reload(obj);
595 _mirrored_set(obj, elm_widget_mirrored_get(obj));
596 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
597 elm_widget_style_get(obj));
598 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
599 wd->item_width = wd->item_height = 0;
600 wd->group_item_width = wd->group_item_height = 0;
601 wd->minw = wd->minh = wd->realminw = 0;
602 EINA_INLIST_FOREACH(wd->blocks, itb)
607 if (itb->realized) _item_block_unrealize(itb);
608 EINA_LIST_FOREACH(itb->items, l, it)
609 it->item->mincalcd = EINA_FALSE;
611 itb->changed = EINA_TRUE;
613 if (wd->calc_job) ecore_job_del(wd->calc_job);
614 wd->calc_job = ecore_job_add(_calc_job, wd);
616 evas_event_thaw(evas_object_evas_get(wd->obj));
617 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
621 _show_region_hook(void *data,
624 Widget_Data *wd = elm_widget_data_get(data);
625 Evas_Coord x, y, w, h;
627 elm_widget_show_region_get(obj, &x, &y, &w, &h);
628 //x & y are screen coordinates, Add with pan coordinates
631 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
635 _translate_hook(Evas_Object *obj)
637 evas_object_smart_callback_call(obj, "language,changed", NULL);
641 _sizing_eval(Evas_Object *obj)
643 Widget_Data *wd = elm_widget_data_get(obj);
644 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
645 Evas_Coord vmw = 0, vmh = 0;
648 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
649 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
651 edje_object_size_min_calc
652 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
654 if (wd->mode == ELM_LIST_COMPRESS)
658 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
659 if ((vw != 0) && (vw != wd->prev_viewport_w))
663 wd->prev_viewport_w = vw;
664 EINA_INLIST_FOREACH(wd->blocks, itb)
666 itb->must_recalc = EINA_TRUE;
668 if (wd->calc_job) ecore_job_del(wd->calc_job);
669 wd->calc_job = ecore_job_add(_calc_job, wd);
674 else if (wd->mode == ELM_LIST_LIMIT)
685 evas_object_size_hint_min_set(obj, minw, minh);
686 evas_object_size_hint_max_set(obj, maxw, maxh);
690 _signal_emit_hook(Evas_Object *obj,
691 const char *emission,
694 Widget_Data *wd = elm_widget_data_get(obj);
695 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
700 _item_highlight(Elm_Gen_Item *it)
702 const char *selectraise;
703 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
704 (!it->wd->highlight) ||
705 (it->generation < it->wd->generation) ||
706 (it->highlighted) || elm_widget_item_disabled_get(it) ||
707 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->deco_it_view) ||
708 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
710 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
711 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
712 selectraise = edje_object_data_get(VIEW(it), "selectraise");
713 if ((selectraise) && (!strcmp(selectraise, "on")))
715 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
716 else evas_object_raise(VIEW(it));
717 if ((it->item->group_item) && (it->item->group_item->realized))
718 evas_object_raise(it->item->VIEW(group_item));
720 it->highlighted = EINA_TRUE;
724 _item_unhighlight(Elm_Gen_Item *it)
726 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
727 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
728 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
729 if (!it->item->nostacking)
731 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
733 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
734 else evas_object_lower(VIEW(it));
738 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
739 else evas_object_raise(VIEW(it));
742 it->highlighted = EINA_FALSE;
746 _item_block_position_update(Eina_Inlist *list, int idx)
750 EINA_INLIST_FOREACH(list, tmp)
752 tmp->position = idx++;
753 tmp->position_update = EINA_TRUE;
758 _item_position_update(Eina_List *list, int idx)
763 EINA_LIST_FOREACH(list, l, it)
765 it->position = idx++;
766 it->position_update = EINA_TRUE;
771 _item_block_del(Elm_Gen_Item *it)
774 Item_Block *itb = it->item->block;
776 itb->items = eina_list_remove(itb->items, it);
778 itb->changed = EINA_TRUE;
779 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
780 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
783 il = EINA_INLIST_GET(itb);
784 Item_Block *itbn = (Item_Block *)(il->next);
786 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
789 _item_block_position_update(il->next, itb->position);
790 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
793 if (itbn) itbn->changed = EINA_TRUE;
797 if (itb->count < itb->wd->max_items_per_block/2)
799 il = EINA_INLIST_GET(itb);
800 Item_Block *itbp = (Item_Block *)(il->prev);
801 Item_Block *itbn = (Item_Block *)(il->next);
802 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
806 EINA_LIST_FREE(itb->items, it2)
808 it2->item->block = itbp;
809 itbp->items = eina_list_append(itbp->items, it2);
811 itbp->changed = EINA_TRUE;
813 _item_block_position_update(EINA_INLIST_GET(itb)->next,
815 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
816 EINA_INLIST_GET(itb));
819 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
823 Eina_List *last = eina_list_last(itb->items);
824 Elm_Gen_Item *it2 = last->data;
826 it2->item->block = itbn;
827 itb->items = eina_list_remove_list(itb->items, last);
828 itbn->items = eina_list_prepend(itbn->items, it2);
830 itbn->changed = EINA_TRUE;
832 _item_block_position_update(EINA_INLIST_GET(itb)->next,
835 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
843 _item_subitems_clear(Elm_Gen_Item *it)
845 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
846 Eina_List *tl = NULL, *l;
847 Elm_Object_Item *it2;
849 EINA_LIST_FOREACH(it->item->items, l, it2)
850 tl = eina_list_append(tl, it2);
851 EINA_LIST_FREE(tl, it2)
852 elm_object_item_del(it2);
856 _item_del(Elm_Gen_Item *it)
858 Evas_Object *obj = WIDGET(it);
859 Widget_Data *wd = it->wd;
861 evas_event_freeze(evas_object_evas_get(obj));
862 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
863 if (wd->show_item == it) wd->show_item = NULL;
864 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
865 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
866 if (it->item->block) _item_block_del(it);
867 if (it->item->queued)
868 wd->queue = eina_list_remove(wd->queue, it);
869 if (wd->anchor_item == it)
871 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
872 if (!wd->anchor_item)
873 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
875 if (wd->expanded_item == it)
877 wd->expanded_item = NULL;
878 if (wd->tree_effect_animator)
880 ecore_animator_del(wd->tree_effect_animator);
881 wd->tree_effect_animator = NULL;
883 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
885 if (wd->expanded_next_item == it) wd->expanded_next_item = NULL;
886 if (wd->move_items) wd->move_items = eina_list_remove(wd->move_items, it);
888 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
889 if (it->item->swipe_timer)
891 ecore_timer_del(it->item->swipe_timer);
892 it->item->swipe_timer = NULL;
894 _elm_genlist_item_del_serious(it);
895 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
896 evas_event_thaw(evas_object_evas_get(obj));
897 evas_event_thaw_eval(evas_object_evas_get(obj));
901 _clear_cb(Widget_Data *wd)
903 wd->anchor_item = NULL;
904 if (wd->queue_idle_enterer)
906 ecore_idle_enterer_del(wd->queue_idle_enterer);
907 wd->queue_idle_enterer = NULL;
909 if (wd->must_recalc_idler)
911 ecore_idler_del(wd->must_recalc_idler);
912 wd->must_recalc_idler = NULL;
914 if (wd->queue) wd->queue = eina_list_free(wd->queue);
915 if (wd->reorder_move_animator)
917 ecore_animator_del(wd->reorder_move_animator);
918 wd->reorder_move_animator = NULL;
920 wd->show_item = NULL;
921 wd->reorder_old_pan_y = 0;
925 _item_unselect(Elm_Gen_Item *it)
927 if ((it->generation < it->wd->generation) || (!it->selected)) return;
928 it->selected = EINA_FALSE;
929 it->wd->selected = eina_list_remove(it->wd->selected, it);
930 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
934 _mouse_move(void *data,
935 Evas *evas __UNUSED__,
939 Elm_Gen_Item *it = data;
940 Evas_Event_Mouse_Move *ev = event_info;
941 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
942 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
944 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
946 if (!it->wd->on_hold)
948 it->wd->on_hold = EINA_TRUE;
949 if ((!it->wd->wasselected) && (!it->flipped))
951 _item_unhighlight(it);
956 if (it->wd->multitouched)
958 it->wd->cur_x = ev->cur.canvas.x;
959 it->wd->cur_y = ev->cur.canvas.y;
962 if ((it->dragging) && (it->down))
964 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
967 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
968 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
969 if (abs((it->wd->history[it->wd->movements].x -
970 it->wd->history[0].x)) > 40)
971 it->wd->swipe = EINA_TRUE;
977 ecore_timer_del(it->long_timer);
978 it->long_timer = NULL;
980 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
983 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
987 ecore_timer_del(it->long_timer);
988 it->long_timer = NULL;
990 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
992 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
993 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
995 if (!it->wd->reorder_start_y)
996 it->wd->reorder_start_y = it->item->block->y + it->y;
1000 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
1001 y_pos = oy + oh - it->wd->reorder_it->item->h;
1005 if (it->deco_all_view)
1006 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
1008 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1010 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1011 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1015 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1016 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1017 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1018 x = ev->cur.canvas.x - x;
1019 y = ev->cur.canvas.y - y;
1022 if (adx < 0) adx = -dx;
1025 if (ady < 0) ady = -dy;
1028 if ((adx > minw) || (ady > minh))
1030 it->dragging = EINA_TRUE;
1033 ecore_timer_del(it->long_timer);
1034 it->long_timer = NULL;
1036 if (!it->wd->wasselected)
1038 _item_unhighlight(it);
1044 evas_object_smart_callback_call(WIDGET(it),
1045 SIG_DRAG_START_UP, it);
1049 evas_object_smart_callback_call(WIDGET(it),
1050 SIG_DRAG_START_LEFT, it);
1052 evas_object_smart_callback_call(WIDGET(it),
1053 SIG_DRAG_START_RIGHT, it);
1059 evas_object_smart_callback_call(WIDGET(it),
1060 SIG_DRAG_START_DOWN, it);
1064 evas_object_smart_callback_call(WIDGET(it),
1065 SIG_DRAG_START_LEFT, it);
1067 evas_object_smart_callback_call(WIDGET(it),
1068 SIG_DRAG_START_RIGHT, it);
1075 _long_press(void *data)
1077 Elm_Gen_Item *it = data, *it_tmp;
1078 Eina_List *list, *l;
1080 it->long_timer = NULL;
1081 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1082 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1083 return ECORE_CALLBACK_CANCEL;
1084 it->wd->longpressed = EINA_TRUE;
1085 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1086 if ((it->wd->reorder_mode) && (!it->group))
1088 it->wd->reorder_it = it;
1089 it->wd->reorder_start_y = 0;
1090 if (it->deco_all_view)
1091 evas_object_raise(it->deco_all_view);
1093 evas_object_raise(VIEW(it));
1095 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1096 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1098 list = elm_genlist_realized_items_get(it->wd->obj);
1099 EINA_LIST_FOREACH(list, l, it_tmp)
1101 if (it != it_tmp) _item_unselect(it_tmp);
1103 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1105 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1106 return ECORE_CALLBACK_RENEW;
1109 if (!it->wd->decorate_all_mode)
1110 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1112 return ECORE_CALLBACK_CANCEL;
1116 _swipe(Elm_Gen_Item *it)
1121 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1122 elm_widget_item_disabled_get(it)) return;
1123 it->wd->swipe = EINA_FALSE;
1124 for (i = 0; i < it->wd->movements; i++)
1126 sum += it->wd->history[i].x;
1127 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1130 sum /= it->wd->movements;
1131 if (abs(sum - it->wd->history[0].x) <= 10) return;
1132 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1136 _swipe_cancel(void *data)
1138 Elm_Gen_Item *it = data;
1140 if (!it) return ECORE_CALLBACK_CANCEL;
1141 it->wd->swipe = EINA_FALSE;
1142 it->wd->movements = 0;
1143 return ECORE_CALLBACK_RENEW;
1147 _multi_cancel(void *data)
1149 Widget_Data *wd = data;
1151 if (!wd) return ECORE_CALLBACK_CANCEL;
1152 wd->multi_timeout = EINA_TRUE;
1153 return ECORE_CALLBACK_RENEW;
1157 _multi_touch_gesture_eval(void *data)
1159 Elm_Gen_Item *it = data;
1161 it->wd->multitouched = EINA_FALSE;
1162 if (it->wd->multi_timer)
1164 ecore_timer_del(it->wd->multi_timer);
1165 it->wd->multi_timer = NULL;
1167 if (it->wd->multi_timeout)
1169 it->wd->multi_timeout = EINA_FALSE;
1173 Evas_Coord minw = 0, minh = 0;
1174 Evas_Coord off_x, off_y, off_mx, off_my;
1176 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1177 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1178 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1179 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1180 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1182 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1184 if ((off_x + off_mx) > (off_y + off_my))
1186 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1187 evas_object_smart_callback_call(WIDGET(it),
1188 SIG_MULTI_SWIPE_RIGHT, it);
1189 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1190 evas_object_smart_callback_call(WIDGET(it),
1191 SIG_MULTI_SWIPE_LEFT, it);
1192 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1193 evas_object_smart_callback_call(WIDGET(it),
1194 SIG_MULTI_PINCH_OUT, it);
1196 evas_object_smart_callback_call(WIDGET(it),
1197 SIG_MULTI_PINCH_IN, it);
1201 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1202 evas_object_smart_callback_call(WIDGET(it),
1203 SIG_MULTI_SWIPE_DOWN, it);
1204 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1205 evas_object_smart_callback_call(WIDGET(it),
1206 SIG_MULTI_SWIPE_UP, it);
1207 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1208 evas_object_smart_callback_call(WIDGET(it),
1209 SIG_MULTI_PINCH_OUT, it);
1211 evas_object_smart_callback_call(WIDGET(it),
1212 SIG_MULTI_PINCH_IN, it);
1215 it->wd->multi_timeout = EINA_FALSE;
1219 _multi_down(void *data,
1220 Evas *evas __UNUSED__,
1221 Evas_Object *obj __UNUSED__,
1224 Elm_Gen_Item *it = data;
1225 Evas_Event_Multi_Down *ev = event_info;
1227 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1228 it->wd->multi_device = ev->device;
1229 it->wd->multi_down = EINA_TRUE;
1230 it->wd->multitouched = EINA_TRUE;
1231 it->wd->prev_mx = ev->canvas.x;
1232 it->wd->prev_my = ev->canvas.y;
1233 if (!it->wd->wasselected)
1235 _item_unhighlight(it);
1238 it->wd->wasselected = EINA_FALSE;
1239 it->wd->longpressed = EINA_FALSE;
1242 ecore_timer_del(it->long_timer);
1243 it->long_timer = NULL;
1247 it->dragging = EINA_FALSE;
1248 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1250 if (it->item->swipe_timer)
1252 ecore_timer_del(it->item->swipe_timer);
1253 it->item->swipe_timer = NULL;
1255 if (it->wd->on_hold)
1257 it->wd->swipe = EINA_FALSE;
1258 it->wd->movements = 0;
1259 it->wd->on_hold = EINA_FALSE;
1264 _multi_up(void *data,
1265 Evas *evas __UNUSED__,
1266 Evas_Object *obj __UNUSED__,
1269 Elm_Gen_Item *it = data;
1270 Evas_Event_Multi_Up *ev = event_info;
1272 if (it->wd->multi_device != ev->device) return;
1273 it->wd->multi_device = 0;
1274 it->wd->multi_down = EINA_FALSE;
1275 if (it->wd->mouse_down) return;
1276 _multi_touch_gesture_eval(data);
1280 _multi_move(void *data,
1281 Evas *evas __UNUSED__,
1282 Evas_Object *obj __UNUSED__,
1285 Elm_Gen_Item *it = data;
1286 Evas_Event_Multi_Move *ev = event_info;
1288 if (it->wd->multi_device != ev->device) return;
1289 it->wd->cur_mx = ev->cur.canvas.x;
1290 it->wd->cur_my = ev->cur.canvas.y;
1294 _mouse_down(void *data,
1295 Evas *evas __UNUSED__,
1299 Elm_Gen_Item *it = data;
1300 Evas_Event_Mouse_Down *ev = event_info;
1303 if (ev->button != 1) return;
1304 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1306 it->wd->on_hold = EINA_TRUE;
1309 it->down = EINA_TRUE;
1310 it->dragging = EINA_FALSE;
1311 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1312 it->dx = ev->canvas.x - x;
1313 it->dy = ev->canvas.y - y;
1314 it->wd->mouse_down = EINA_TRUE;
1315 if (!it->wd->multitouched)
1317 it->wd->prev_x = ev->canvas.x;
1318 it->wd->prev_y = ev->canvas.y;
1319 it->wd->multi_timeout = EINA_FALSE;
1320 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1321 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1323 it->wd->longpressed = EINA_FALSE;
1324 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1325 else it->wd->on_hold = EINA_FALSE;
1326 if (it->wd->on_hold) return;
1327 it->wd->wasselected = it->selected;
1328 _item_highlight(it);
1329 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1330 if ((!elm_widget_item_disabled_get(it)) &&
1331 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1333 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1334 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1336 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1337 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1338 if (it->long_timer) ecore_timer_del(it->long_timer);
1340 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1343 it->long_timer = NULL;
1344 it->wd->swipe = EINA_FALSE;
1345 it->wd->movements = 0;
1349 _mouse_up(void *data,
1350 Evas *evas __UNUSED__,
1351 Evas_Object *obj __UNUSED__,
1354 Elm_Gen_Item *it = data;
1355 Evas_Event_Mouse_Up *ev = event_info;
1356 Eina_Bool dragged = EINA_FALSE;
1358 if (ev->button != 1) return;
1359 it->down = EINA_FALSE;
1360 it->wd->mouse_down = EINA_FALSE;
1361 if (it->wd->multitouched)
1363 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1364 if (it->wd->multi_down) return;
1365 _multi_touch_gesture_eval(data);
1368 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1369 else it->wd->on_hold = EINA_FALSE;
1372 ecore_timer_del(it->long_timer);
1373 it->long_timer = NULL;
1377 it->dragging = EINA_FALSE;
1378 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1381 if (it->item->swipe_timer)
1383 ecore_timer_del(it->item->swipe_timer);
1384 it->item->swipe_timer = NULL;
1386 if (it->wd->multi_timer)
1388 ecore_timer_del(it->wd->multi_timer);
1389 it->wd->multi_timer = NULL;
1390 it->wd->multi_timeout = EINA_FALSE;
1392 if (it->wd->on_hold)
1394 if (it->wd->swipe) _swipe(data);
1395 it->wd->longpressed = EINA_FALSE;
1396 it->wd->on_hold = EINA_FALSE;
1399 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1401 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1403 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1405 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1406 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1408 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1409 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1413 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1414 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1416 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1417 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1418 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1419 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1421 if (it->wd->longpressed)
1423 it->wd->longpressed = EINA_FALSE;
1424 if ((!it->wd->wasselected) && (!it->flipped))
1426 _item_unhighlight(it);
1429 it->wd->wasselected = EINA_FALSE;
1434 if (it->want_unrealize)
1436 _elm_genlist_item_unrealize(it, EINA_FALSE);
1437 if (it->item->block->want_unrealize)
1438 _item_block_unrealize(it->item->block);
1441 if (elm_widget_item_disabled_get(it) || (dragged) ||
1442 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1444 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1449 _item_highlight(it);
1454 _item_unhighlight(it);
1462 Widget_Data *wd = it->wd;
1465 while (wd->selected)
1467 _item_unhighlight(wd->selected->data);
1468 _item_unselect(wd->selected->data);
1474 const Eina_List *l, *l_next;
1477 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1480 _item_unhighlight(it2);
1481 _item_unselect(it2);
1483 //_item_highlight(it);
1486 _item_highlight(it);
1492 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1494 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1496 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1498 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1500 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1502 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1504 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1509 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1511 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1513 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1515 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1517 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1519 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1521 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1526 _signal_expand_toggle(void *data,
1527 Evas_Object *obj __UNUSED__,
1528 const char *emission __UNUSED__,
1529 const char *source __UNUSED__)
1531 Elm_Gen_Item *it = data;
1533 if (it->item->expanded)
1534 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1536 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1540 _signal_expand(void *data,
1541 Evas_Object *obj __UNUSED__,
1542 const char *emission __UNUSED__,
1543 const char *source __UNUSED__)
1545 Elm_Gen_Item *it = data;
1547 if (!it->item->expanded)
1548 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1552 _signal_contract(void *data,
1553 Evas_Object *obj __UNUSED__,
1554 const char *emission __UNUSED__,
1555 const char *source __UNUSED__)
1557 Elm_Gen_Item *it = data;
1559 if (it->item->expanded)
1560 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1564 _scr_hold_timer_cb(void *data)
1566 if (!data) return ECORE_CALLBACK_CANCEL;
1567 Widget_Data *wd = data;
1568 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1569 wd->scr_hold_timer = NULL;
1570 return ECORE_CALLBACK_CANCEL;
1574 _decorate_item_finished_signal_cb(void *data,
1576 const char *emission __UNUSED__,
1577 const char *source __UNUSED__)
1581 Elm_Gen_Item *it = data;
1582 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1584 Evas *te = evas_object_evas_get(obj);
1586 evas_event_freeze(te);
1587 it->item->nocache_once = EINA_FALSE;
1588 _decorate_item_unrealize(it);
1589 if (it->item->group_item)
1590 evas_object_raise(it->item->VIEW(group_item));
1591 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1592 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1593 evas_event_thaw(te);
1594 evas_event_thaw_eval(te);
1598 _item_cache_clean(Widget_Data *wd)
1600 evas_event_freeze(evas_object_evas_get(wd->obj));
1601 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1605 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1606 wd->item_cache = eina_inlist_remove(wd->item_cache,
1607 wd->item_cache->last);
1608 wd->item_cache_count--;
1609 if (itc->spacer) evas_object_del(itc->spacer);
1610 if (itc->base_view) evas_object_del(itc->base_view);
1611 eina_stringshare_del(itc->item_style);
1614 evas_event_thaw(evas_object_evas_get(wd->obj));
1615 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1619 _item_cache_zero(Widget_Data *wd)
1621 int pmax = wd->item_cache_max;
1622 wd->item_cache_max = 0;
1623 _item_cache_clean(wd);
1624 wd->item_cache_max = pmax;
1628 _item_cache_add(Elm_Gen_Item *it)
1632 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1633 if (it->wd->item_cache_max <= 0)
1635 evas_object_del(VIEW(it));
1639 evas_object_del(it->spacer);
1642 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1643 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1647 it->wd->item_cache_count++;
1648 itc = calloc(1, sizeof(Item_Cache));
1651 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1652 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1655 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1656 EINA_INLIST_GET(itc));
1657 itc->spacer = it->spacer;
1659 itc->base_view = VIEW(it);
1661 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1662 evas_object_hide(itc->base_view);
1663 evas_object_move(itc->base_view, -9999, -9999);
1664 itc->item_style = eina_stringshare_add(it->itc->item_style);
1665 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1666 itc->selected = it->selected;
1667 itc->disabled = elm_widget_item_disabled_get(it);
1668 itc->expanded = it->item->expanded;
1671 ecore_timer_del(it->long_timer);
1672 it->long_timer = NULL;
1674 if (it->item->swipe_timer)
1676 ecore_timer_del(it->item->swipe_timer);
1677 it->item->swipe_timer = NULL;
1679 // FIXME: other callbacks?
1680 edje_object_signal_callback_del_full(itc->base_view,
1681 "elm,action,expand,toggle",
1682 "elm", _signal_expand_toggle, it);
1683 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1685 _signal_expand, it);
1686 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1687 "elm", _signal_contract, it);
1688 _item_mouse_callbacks_del(it, itc->base_view);
1689 _item_cache_clean(it->wd);
1690 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1691 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1695 _item_cache_find(Elm_Gen_Item *it)
1700 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1701 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1703 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1705 if ((itc->tree == tree) &&
1706 (((!it->itc->item_style) && (!itc->item_style)) ||
1707 (it->itc->item_style && itc->item_style &&
1708 (!strcmp(it->itc->item_style, itc->item_style)))))
1710 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1711 EINA_INLIST_GET(itc));
1712 it->wd->item_cache_count--;
1720 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1722 if (it->position_update || it->item->block->position_update)
1724 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1725 it->position_update = EINA_FALSE;
1730 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1732 if (!it->item->nostacking)
1734 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1736 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1737 else evas_object_lower(VIEW(it));
1741 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1742 else evas_object_raise(VIEW(it));
1746 if (it->item->order_num_in & 0x1)
1748 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1749 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1753 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1754 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1759 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1763 if (it->selected != itc->selected)
1767 edje_object_signal_emit(VIEW(it),
1768 "elm,state,selected", "elm");
1769 if (it->deco_all_view)
1770 edje_object_signal_emit(it->deco_all_view,
1771 "elm,state,selected", "elm");
1774 if (elm_widget_item_disabled_get(it) != itc->disabled)
1776 if (elm_widget_item_disabled_get(it))
1777 edje_object_signal_emit(VIEW(it),
1778 "elm,state,disabled", "elm");
1779 if (it->deco_all_view)
1780 edje_object_signal_emit(it->deco_all_view,
1781 "elm,state,disabled", "elm");
1783 if (it->item->expanded != itc->expanded)
1785 if (it->item->expanded)
1786 edje_object_signal_emit(VIEW(it),
1787 "elm,state,expanded", "elm");
1788 if (it->deco_all_view)
1789 edje_object_signal_emit(it->deco_all_view,
1790 "elm,state,expanded", "elm");
1797 edje_object_signal_emit(VIEW(it),
1798 "elm,state,selected", "elm");
1799 if (it->deco_all_view)
1800 edje_object_signal_emit(it->deco_all_view,
1801 "elm,state,selected", "elm");
1803 if (elm_widget_item_disabled_get(it))
1805 edje_object_signal_emit(VIEW(it),
1806 "elm,state,disabled", "elm");
1807 if (it->deco_all_view)
1808 edje_object_signal_emit(it->deco_all_view,
1809 "elm,state,disabled", "elm");
1811 if (it->item->expanded)
1813 edje_object_signal_emit(VIEW(it),
1814 "elm,state,expanded", "elm");
1815 if (it->deco_all_view)
1816 edje_object_signal_emit(it->deco_all_view,
1817 "elm,state,expanded", "elm");
1823 _item_mode_content_realize(Elm_Gen_Item *it,
1824 Evas_Object *target,
1827 Eina_List **contents_list)
1829 Eina_List *res = *contents_list;
1831 if (it->itc->func.content_get)
1836 EINA_LIST_FOREACH(*source, l, key)
1838 if (parts && fnmatch(parts, key, FNM_PERIOD))
1841 Evas_Object *ic = it->itc->func.content_get
1842 ((void *)it->base.data, WIDGET(it), l->data);
1846 res = eina_list_append(res, ic);
1847 edje_object_part_swallow(target, key, ic);
1848 evas_object_show(ic);
1849 elm_widget_sub_object_add(WIDGET(it), ic);
1850 if (it->item->deco_it_view || it->wd->decorate_all_mode)
1852 if (elm_widget_item_disabled_get(it))
1853 elm_widget_disabled_set(ic, EINA_TRUE);
1863 _item_mode_content_unrealize(Elm_Gen_Item *it,
1864 Evas_Object *target,
1867 Eina_List **contents_list)
1869 Eina_List *res = *contents_list;
1871 if (it->itc->func.content_get)
1875 Evas_Object *ic = NULL;
1877 EINA_LIST_FOREACH(*source, l, key)
1879 if (parts && fnmatch(parts, key, FNM_PERIOD))
1882 ic = edje_object_part_swallow_get(target, key);
1885 res = eina_list_remove(res, ic);
1886 edje_object_part_unswallow(target, ic);
1887 evas_object_del(ic);
1896 _item_cache_free(Item_Cache *itc)
1898 if (itc->spacer) evas_object_del(itc->spacer);
1899 if (itc->base_view) evas_object_del(itc->base_view);
1900 eina_stringshare_del(itc->item_style);
1905 _item_text_realize(Elm_Gen_Item *it,
1906 Evas_Object *target,
1910 if (it->itc->func.text_get)
1916 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1917 EINA_LIST_FOREACH(*source, l, key)
1919 if (parts && fnmatch(parts, key, FNM_PERIOD))
1922 char *s = it->itc->func.text_get
1923 ((void *)it->base.data, WIDGET(it), key);
1927 edje_object_part_text_escaped_set(target, key, s);
1932 edje_object_part_text_set(target, key, "");
1939 _item_content_unrealize(Elm_Gen_Item *it,
1940 Evas_Object *target,
1944 Eina_List *res = it->content_objs;
1946 if (it->itc->func.content_get)
1950 Evas_Object *ic = NULL;
1952 EINA_LIST_FOREACH(*source, l, key)
1954 if (parts && fnmatch(parts, key, FNM_PERIOD))
1957 ic = edje_object_part_swallow_get(target, key);
1960 res = eina_list_remove(res, ic);
1961 edje_object_part_unswallow(target, ic);
1962 evas_object_del(ic);
1971 _item_content_realize(Elm_Gen_Item *it,
1972 Evas_Object *target,
1976 Eina_List *res = it->content_objs;
1978 if (it->itc->func.content_get)
1982 Evas_Object *ic = NULL;
1985 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1987 EINA_LIST_FOREACH(*source, l, key)
1989 if (parts && fnmatch(parts, key, FNM_PERIOD))
1992 if (it->itc->func.content_get)
1993 ic = it->itc->func.content_get
1994 ((void *)it->base.data, WIDGET(it), key);
1997 res = eina_list_append(res, ic);
1998 edje_object_part_swallow(target, key, ic);
1999 evas_object_show(ic);
2000 elm_widget_sub_object_add(WIDGET(it), ic);
2001 if (elm_widget_item_disabled_get(it))
2002 elm_widget_disabled_set(ic, EINA_TRUE);
2011 _item_state_realize(Elm_Gen_Item *it,
2012 Evas_Object *target,
2016 if (it->itc->func.state_get)
2023 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2024 EINA_LIST_FOREACH(*source, l, key)
2026 if (parts && fnmatch(parts, key, FNM_PERIOD))
2029 Eina_Bool on = it->itc->func.state_get
2030 ((void *)it->base.data, WIDGET(it), key);
2034 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2035 edje_object_signal_emit(target, buf, "elm");
2039 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2040 edje_object_signal_emit(target, buf, "elm");
2047 _item_realize(Elm_Gen_Item *it,
2051 const char *treesize;
2054 Item_Cache *itc = NULL;
2056 if (it->generation < it->wd->generation) return;
2057 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2060 if (it->item->order_num_in != in)
2062 it->item->order_num_in = in;
2063 _elm_genlist_item_odd_even_update(it);
2064 _elm_genlist_item_state_update(it, NULL);
2065 _elm_genlist_item_index_update(it);
2067 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2068 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2071 it->item->order_num_in = in;
2073 if (it->item->nocache_once)
2074 it->item->nocache_once = EINA_FALSE;
2075 else if (!it->item->nocache)
2076 itc = _item_cache_find(it);
2077 if (itc && (!it->wd->tree_effect_enabled))
2079 VIEW(it) = itc->base_view;
2080 itc->base_view = NULL;
2081 it->spacer = itc->spacer;
2086 const char *stacking_even;
2087 const char *stacking;
2089 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2090 edje_object_scale_set(VIEW(it),
2091 elm_widget_scale_get(WIDGET(it)) *
2092 _elm_config->scale);
2093 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2094 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2096 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2097 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2099 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2101 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2102 elm_widget_style_get(WIDGET(it)));
2104 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2105 if (!stacking_even) stacking_even = "above";
2106 it->item->stacking_even = !!strcmp("above", stacking_even);
2108 stacking = edje_object_data_get(VIEW(it), "stacking");
2109 if (!stacking) stacking = "yes";
2110 it->item->nostacking = !!strcmp("yes", stacking);
2112 edje_object_mirrored_set(VIEW(it),
2113 elm_widget_mirrored_get(WIDGET(it)));
2116 _elm_genlist_item_odd_even_update(it);
2118 treesize = edje_object_data_get(VIEW(it), "treesize");
2119 if (treesize) tsize = atoi(treesize);
2120 if (!it->spacer && treesize)
2123 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2124 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2125 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2129 evas_object_size_hint_min_set(it->spacer,
2130 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2131 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2135 edje_object_signal_callback_add(VIEW(it),
2136 "elm,action,expand,toggle",
2137 "elm", _signal_expand_toggle, it);
2138 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2139 "elm", _signal_expand, it);
2140 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2141 "elm", _signal_contract, it);
2142 _item_mouse_callbacks_add(it, VIEW(it));
2144 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2145 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2146 _decorate_all_item_realize(it, EINA_FALSE);
2148 _elm_genlist_item_state_update(it, itc);
2149 _elm_genlist_item_index_update(it);
2152 if ((calc) && (it->wd->homogeneous) &&
2153 ((it->wd->item_width) ||
2154 ((it->wd->item_width) && (it->wd->group_item_width))))
2156 /* homogenous genlist shortcut */
2157 if (!it->item->mincalcd)
2161 it->item->w = it->item->minw = it->wd->group_item_width;
2162 it->item->h = it->item->minh = it->wd->group_item_height;
2166 it->item->w = it->item->minw = it->wd->item_width;
2167 it->item->h = it->item->minh = it->wd->item_height;
2169 it->item->mincalcd = EINA_TRUE;
2174 /* FIXME: If you see that assert, please notify us and we
2175 will clean our mess */
2176 assert(eina_list_count(it->content_objs) == 0);
2178 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2179 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2180 _item_state_realize(it, VIEW(it), &it->states, NULL);
2183 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2184 if (!(it->item->flip_contents))
2185 it->item->flip_contents =
2186 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2187 it->item->flip_content_objs =
2188 _item_mode_content_realize(it, VIEW(it),
2189 &it->item->flip_contents, NULL,
2190 &it->item->flip_content_objs);
2193 if (!it->item->mincalcd)
2195 Evas_Coord mw = -1, mh = -1;
2197 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2198 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2199 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2200 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2202 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2203 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2204 it->item->w = it->item->minw = mw;
2205 it->item->h = it->item->minh = mh;
2206 it->item->mincalcd = EINA_TRUE;
2208 if ((!it->wd->group_item_width) && (it->group))
2210 it->wd->group_item_width = mw;
2211 it->wd->group_item_height = mh;
2213 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2215 it->wd->item_width = mw;
2216 it->wd->item_height = mh;
2219 if (!calc) evas_object_show(VIEW(it));
2222 if (it->tooltip.content_cb)
2224 elm_widget_item_tooltip_content_cb_set(it,
2225 it->tooltip.content_cb,
2226 it->tooltip.data, NULL);
2227 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2228 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2231 if (it->mouse_cursor)
2232 elm_widget_item_cursor_set(it, it->mouse_cursor);
2234 it->realized = EINA_TRUE;
2235 it->want_unrealize = EINA_FALSE;
2237 if (itc) _item_cache_free(itc);
2238 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2239 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2242 if (it->item->tree_effect_hideme)
2244 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2245 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2246 it->item->tree_effect_hideme = EINA_FALSE;
2248 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2251 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2253 if (it->itc->decorate_all_item_style)
2255 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2256 edje_object_message_signal_process(it->deco_all_view);
2259 edje_object_message_signal_process(VIEW(it));
2263 _item_unrealize_cb(Elm_Gen_Item *it)
2265 Evas_Object *content;
2266 elm_widget_stringlist_free(it->item->flip_contents);
2267 it->item->flip_contents = NULL;
2268 EINA_LIST_FREE(it->item->flip_content_objs, content)
2269 evas_object_del(content);
2271 if (it->item->nocache_once || it->item->nocache)
2273 evas_object_del(VIEW(it));
2277 evas_object_del(it->spacer);
2283 edje_object_mirrored_set(VIEW(it),
2284 elm_widget_mirrored_get(WIDGET(it)));
2285 edje_object_scale_set(VIEW(it),
2286 elm_widget_scale_get(WIDGET(it))
2287 * _elm_config->scale);
2288 _item_cache_add(it);
2291 _decorate_item_unrealize(it);
2293 it->realized = EINA_FALSE;
2294 it->want_unrealize = EINA_FALSE;
2295 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2299 _item_block_recalc(Item_Block *itb,
2305 Evas_Coord minw = 0, minh = 0;
2306 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2309 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2311 EINA_LIST_FOREACH(itb->items, l, it)
2313 if (it->generation < it->wd->generation) continue;
2314 showme |= it->item->showme;
2319 if (!it->item->mincalcd) changed = EINA_TRUE;
2322 _item_realize(it, in, EINA_TRUE);
2323 _elm_genlist_item_unrealize(it, EINA_TRUE);
2328 _item_realize(it, in, EINA_TRUE);
2329 _elm_genlist_item_unrealize(it, EINA_TRUE);
2334 if (!it->item->mincalcd) changed = EINA_TRUE;
2335 _item_realize(it, in, EINA_FALSE);
2337 minh += it->item->minh;
2338 if (minw < it->item->minw) minw = it->item->minw;
2344 if (changed) itb->wd->pan_changed = changed;
2347 itb->changed = EINA_FALSE;
2348 itb->position_update = EINA_FALSE;
2349 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2350 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2355 _item_block_realize(Item_Block *itb)
2357 if (itb->realized) return;
2358 itb->realized = EINA_TRUE;
2359 itb->want_unrealize = EINA_FALSE;
2363 _item_block_unrealize(Item_Block *itb)
2367 Eina_Bool dragging = EINA_FALSE;
2369 if (!itb->realized) return;
2370 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2371 EINA_LIST_FOREACH(itb->items, l, it)
2373 if (itb->must_recalc || !it->group)
2377 dragging = EINA_TRUE;
2378 it->want_unrealize = EINA_TRUE;
2381 _elm_genlist_item_unrealize(it, EINA_FALSE);
2386 itb->realized = EINA_FALSE;
2387 itb->want_unrealize = EINA_TRUE;
2390 itb->want_unrealize = EINA_FALSE;
2391 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2392 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2396 _get_space_for_reorder_item(Elm_Gen_Item *it)
2398 Evas_Coord rox, roy, row, roh, oy, oh;
2399 Eina_Bool top = EINA_FALSE;
2400 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2401 if (!reorder_it) return 0;
2403 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2404 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2406 if ((it->wd->reorder_start_y < it->item->block->y) &&
2407 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2409 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2410 if (it->item->block->count == 1)
2411 it->wd->reorder_rel = it;
2413 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2414 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2416 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2419 it->item->block->reorder_offset = 0;
2421 it->item->scrl_y += it->item->block->reorder_offset;
2423 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2424 rox, roy + (roh / 2), row, 1));
2427 it->wd->reorder_rel = it;
2428 it->item->scrl_y += it->wd->reorder_it->item->h;
2429 return it->wd->reorder_it->item->h;
2436 _reorder_move_animator_cb(void *data)
2438 Elm_Gen_Item *it = data;
2439 Eina_Bool down = EINA_FALSE;
2441 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2443 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2445 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2448 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2449 if (diff > it->item->h) y = diff / 2;
2451 if (it->item->old_scrl_y < it->item->scrl_y)
2453 it->item->old_scrl_y += y;
2456 else if (it->item->old_scrl_y > it->item->scrl_y)
2458 it->item->old_scrl_y -= y;
2462 if (it->deco_all_view)
2463 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2465 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2466 _group_items_recalc(it->wd);
2468 if ((it->wd->reorder_pan_move) ||
2469 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2470 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2472 it->item->old_scrl_y = it->item->scrl_y;
2473 it->item->move_effect_enabled = EINA_FALSE;
2474 it->wd->reorder_move_animator = NULL;
2475 return ECORE_CALLBACK_CANCEL;
2477 return ECORE_CALLBACK_RENEW;
2481 _item_position(Elm_Gen_Item *it,
2489 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2490 evas_object_resize(view, it->item->w, it->item->h);
2491 evas_object_move(view, it_x, it_y);
2492 evas_object_show(view);
2493 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2494 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2498 _item_block_position(Item_Block *itb,
2504 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2505 Eina_Bool vis = EINA_FALSE;
2507 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2508 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2509 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2511 EINA_LIST_FOREACH(itb->items, l, it)
2513 if (it->generation < it->wd->generation) continue;
2514 else if (it->wd->reorder_it == it) continue;
2517 it->item->w = itb->w;
2518 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2519 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2521 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2522 cvx, cvy, cvw, cvh));
2525 if ((itb->realized) && (!it->realized))
2527 if (vis) _item_realize(it, in, EINA_FALSE);
2531 if (vis || it->dragging)
2533 if (it->wd->reorder_mode)
2534 y += _get_space_for_reorder_item(it);
2535 git = it->item->group_item;
2538 if (git->item->scrl_y < oy)
2539 git->item->scrl_y = oy;
2540 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2541 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2542 git->item->want_realize = EINA_TRUE;
2544 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2546 if (!it->item->move_effect_enabled)
2548 it->item->move_effect_enabled = EINA_TRUE;
2549 it->wd->reorder_move_animator =
2551 _reorder_move_animator_cb, it);
2554 if (!it->item->move_effect_enabled)
2556 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2557 _decorate_all_item_position(it, it->item->scrl_x,
2561 if (!it->wd->tree_effect_enabled ||
2562 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2563 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2564 (it->item->old_scrl_y == it->item->scrl_y)))
2566 if (it->item->deco_it_view)
2567 _item_position(it, it->item->deco_it_view,
2571 _item_position(it, VIEW(it), it->item->scrl_x,
2575 it->item->old_scrl_y = it->item->scrl_y;
2580 if (!it->wd->tree_effect_animator)
2581 _elm_genlist_item_unrealize(it, EINA_FALSE);
2588 if (vis) it->item->want_realize = EINA_TRUE;
2592 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2593 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2597 _group_items_recalc(void *data)
2599 Widget_Data *wd = data;
2603 evas_event_freeze(evas_object_evas_get(wd->obj));
2604 EINA_LIST_FOREACH(wd->group_items, l, git)
2606 if (git->item->want_realize)
2609 _item_realize(git, 0, EINA_FALSE);
2610 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2611 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2612 evas_object_show(VIEW(git));
2613 evas_object_raise(VIEW(git));
2615 else if (!git->item->want_realize && git->realized)
2618 _elm_genlist_item_unrealize(git, EINA_FALSE);
2621 evas_event_thaw(evas_object_evas_get(wd->obj));
2622 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2626 _must_recalc_idler(void *data)
2628 Widget_Data *wd = data;
2629 if (wd->calc_job) ecore_job_del(wd->calc_job);
2630 wd->calc_job = ecore_job_add(_calc_job, wd);
2631 wd->must_recalc_idler = NULL;
2632 return ECORE_CALLBACK_CANCEL;
2636 _scroll_item(Widget_Data *wd)
2638 Elm_Gen_Item *it = NULL;
2639 Evas_Coord gith = 0;
2640 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2641 if (!wd->show_item) return;
2643 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2645 dx = it->x + it->item->block->x;
2646 dy = it->y + it->item->block->y;
2647 dw = it->item->block->w;
2649 switch (wd->scrollto_type)
2651 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2652 if (it->item->group_item) gith = it->item->group_item->item->h;
2655 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2656 dy += ((it->item->h / 2) - (oh / 2));
2658 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2660 if ((wd->expanded_item) &&
2661 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2662 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2664 it = wd->expanded_item;
2665 if (it->item->group_item) gith = it->item->group_item->item->h;
2666 dx = it->x + it->item->block->x;
2667 dy = it->y + it->item->block->y - gith;
2668 dw = it->item->block->w;
2672 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2673 gith = it->item->group_item->item->h;
2680 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2682 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2684 it->item->showme = EINA_FALSE;
2685 wd->show_item = NULL;
2686 wd->auto_scroll_enabled = EINA_FALSE;
2687 wd->check_scroll = EINA_FALSE;
2691 _calc_job(void *data)
2693 Widget_Data *wd = data;
2694 Item_Block *itb, *chb = NULL;
2695 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2696 Evas_Coord pan_w = 0, pan_h = 0;
2698 Eina_Bool minw_change = EINA_FALSE;
2699 Eina_Bool did_must_recalc = EINA_FALSE;
2702 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2703 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2708 evas_event_freeze(evas_object_evas_get(wd->obj));
2709 EINA_INLIST_FOREACH(wd->blocks, itb)
2711 Eina_Bool showme = EINA_FALSE;
2714 showme = itb->showme;
2715 itb->showme = EINA_FALSE;
2718 if (itb->realized) _item_block_unrealize(itb);
2720 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2722 if (itb->must_recalc)
2726 EINA_LIST_FOREACH(itb->items, l, it)
2727 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2728 itb->changed = EINA_TRUE;
2729 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2730 if (itb->realized) _item_block_unrealize(itb);
2731 itb->must_recalc = EINA_FALSE;
2733 showme = _item_block_recalc(itb, in, EINA_FALSE);
2739 if (minw == -1) minw = itb->minw;
2740 else if ((!itb->must_recalc) && (minw < itb->minw))
2743 minw_change = EINA_TRUE;
2748 minw_change = EINA_TRUE;
2754 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2755 wd->check_scroll = EINA_TRUE;
2759 EINA_INLIST_FOREACH(wd->blocks, itb)
2765 if ((chb) && (EINA_INLIST_GET(chb)->next))
2767 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2769 if (itb->realized) _item_block_unrealize(itb);
2772 wd->realminw = minw;
2773 if (minw < wd->w) minw = wd->w;
2774 if ((minw != wd->minw) || (minh != wd->minh))
2778 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2779 _sizing_eval(wd->obj);
2780 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2785 it = wd->anchor_item;
2786 it_y = wd->anchor_y;
2787 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2788 it->item->block->y + it->y + it_y);
2789 wd->anchor_item = it;
2790 wd->anchor_y = it_y;
2793 if (did_must_recalc)
2795 if (!wd->must_recalc_idler)
2796 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2798 if (wd->check_scroll)
2800 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2801 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2802 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2803 switch (wd->scrollto_type)
2805 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2808 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2811 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2816 if ((wd->show_item) && (wd->show_item->item->block))
2818 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2819 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2825 wd->calc_job = NULL;
2826 evas_object_smart_changed(wd->pan_smart);
2827 evas_event_thaw(evas_object_evas_get(wd->obj));
2828 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2832 _update_job(void *data)
2834 Widget_Data *wd = data;
2838 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2840 wd->update_job = NULL;
2843 evas_event_freeze(evas_object_evas_get(wd->obj));
2844 EINA_INLIST_FOREACH(wd->blocks, itb)
2846 Evas_Coord itminw, itminh;
2853 _item_block_position(itb, num);
2857 recalc = EINA_FALSE;
2858 EINA_LIST_FOREACH(itb->items, l2, it)
2860 if (it->item->updateme)
2862 itminw = it->item->minw;
2863 itminh = it->item->minh;
2865 it->item->updateme = EINA_FALSE;
2868 _elm_genlist_item_unrealize(it, EINA_FALSE);
2869 _item_realize(it, num, EINA_FALSE);
2870 position = EINA_TRUE;
2874 _item_realize(it, num, EINA_TRUE);
2875 _elm_genlist_item_unrealize(it, EINA_TRUE);
2877 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2882 itb->updateme = EINA_FALSE;
2885 position = EINA_TRUE;
2886 itb->changed = EINA_TRUE;
2887 _item_block_recalc(itb, num0, EINA_FALSE);
2888 _item_block_position(itb, num0);
2893 if (wd->calc_job) ecore_job_del(wd->calc_job);
2894 wd->calc_job = ecore_job_add(_calc_job, wd);
2896 evas_event_thaw(evas_object_evas_get(wd->obj));
2897 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2901 _pan_set(Evas_Object *obj,
2905 Pan *sd = evas_object_smart_data_get(obj);
2909 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2913 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2915 if ((itb->y + itb->h) > y)
2920 EINA_LIST_FOREACH(itb->items, l2, it)
2922 if ((itb->y + it->y) >= y)
2924 sd->wd->anchor_item = it;
2925 sd->wd->anchor_y = -(itb->y + it->y - y);
2932 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2936 _pan_get(Evas_Object *obj,
2940 Pan *sd = evas_object_smart_data_get(obj);
2943 if (x) *x = sd->wd->pan_x;
2944 if (y) *y = sd->wd->pan_y;
2948 _pan_max_get(Evas_Object *obj,
2952 Pan *sd = evas_object_smart_data_get(obj);
2956 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2957 ow = sd->wd->minw - ow;
2959 oh = sd->wd->minh - oh;
2966 _pan_min_get(Evas_Object *obj __UNUSED__,
2975 _pan_child_size_get(Evas_Object *obj,
2979 Pan *sd = evas_object_smart_data_get(obj);
2982 if (w) *w = sd->wd->minw;
2983 if (h) *h = sd->wd->minh;
2987 _pan_add(Evas_Object *obj)
2990 Evas_Object_Smart_Clipped_Data *cd;
2993 cd = evas_object_smart_data_get(obj);
2996 sd->__clipped_data = *cd;
2998 evas_object_smart_data_set(obj, sd);
3002 _pan_del(Evas_Object *obj)
3004 Pan *sd = evas_object_smart_data_get(obj);
3009 ecore_job_del(sd->resize_job);
3010 sd->resize_job = NULL;
3016 _pan_resize_job(void *data)
3020 _sizing_eval(sd->wd->obj);
3021 sd->resize_job = NULL;
3025 _pan_resize(Evas_Object *obj,
3029 Pan *sd = evas_object_smart_data_get(obj);
3033 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3034 if ((ow == w) && (oh == h)) return;
3035 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3038 if (sd->resize_job) ecore_job_del(sd->resize_job);
3039 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3041 sd->wd->pan_changed = EINA_TRUE;
3042 evas_object_smart_changed(obj);
3043 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3044 sd->wd->calc_job = NULL;
3048 _pan_calculate(Evas_Object *obj)
3050 Pan *sd = evas_object_smart_data_get(obj);
3052 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3058 evas_event_freeze(evas_object_evas_get(obj));
3060 if (sd->wd->pan_changed)
3063 sd->wd->pan_changed = EINA_FALSE;
3066 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3067 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3068 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3070 git->item->want_realize = EINA_FALSE;
3073 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3075 if (!sd->wd->tree_effect_animator)
3077 _item_tree_effect_before(sd->wd->expanded_item);
3078 evas_object_raise(sd->wd->alpha_bg);
3079 evas_object_show(sd->wd->alpha_bg);
3080 sd->wd->start_time = ecore_time_get();
3081 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3085 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3087 itb->w = sd->wd->minw;
3088 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3089 itb->y - sd->wd->pan_y + oy,
3091 cvx, cvy, cvw, cvh))
3093 if ((!itb->realized) || (itb->changed))
3094 _item_block_realize(itb);
3095 _item_block_position(itb, in);
3099 if (itb->realized) _item_block_unrealize(itb);
3103 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3104 _group_items_recalc(sd->wd);
3105 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3107 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3108 sd->wd->reorder_pan_move = EINA_TRUE;
3109 else sd->wd->reorder_pan_move = EINA_FALSE;
3110 evas_object_raise(sd->wd->VIEW(reorder_it));
3111 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3112 sd->wd->start_time = ecore_loop_time_get();
3115 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3116 _item_auto_scroll(sd->wd);
3118 evas_event_thaw(evas_object_evas_get(obj));
3119 evas_event_thaw_eval(evas_object_evas_get(obj));
3123 _pan_move(Evas_Object *obj,
3124 Evas_Coord x __UNUSED__,
3125 Evas_Coord y __UNUSED__)
3127 Pan *sd = evas_object_smart_data_get(obj);
3131 sd->wd->pan_changed = EINA_TRUE;
3132 evas_object_smart_changed(obj);
3133 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3134 sd->wd->calc_job = NULL;
3138 _hold_on(void *data __UNUSED__,
3140 void *event_info __UNUSED__)
3142 Widget_Data *wd = elm_widget_data_get(obj);
3144 elm_smart_scroller_hold_set(wd->scr, 1);
3148 _hold_off(void *data __UNUSED__,
3150 void *event_info __UNUSED__)
3152 Widget_Data *wd = elm_widget_data_get(obj);
3154 elm_smart_scroller_hold_set(wd->scr, 0);
3158 _freeze_on(void *data __UNUSED__,
3160 void *event_info __UNUSED__)
3162 Widget_Data *wd = elm_widget_data_get(obj);
3164 elm_smart_scroller_freeze_set(wd->scr, 1);
3168 _freeze_off(void *data __UNUSED__,
3170 void *event_info __UNUSED__)
3172 Widget_Data *wd = elm_widget_data_get(obj);
3174 elm_smart_scroller_freeze_set(wd->scr, 0);
3178 _scr_anim_start(void *data,
3179 Evas_Object *obj __UNUSED__,
3180 void *event_info __UNUSED__)
3182 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3186 _scr_anim_stop(void *data,
3187 Evas_Object *obj __UNUSED__,
3188 void *event_info __UNUSED__)
3190 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3194 _scr_drag_start(void *data,
3195 Evas_Object *obj __UNUSED__,
3196 void *event_info __UNUSED__)
3198 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3202 _scr_drag_stop(void *data,
3203 Evas_Object *obj __UNUSED__,
3204 void *event_info __UNUSED__)
3206 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3210 _edge_left(void *data,
3211 Evas_Object *scr __UNUSED__,
3212 void *event_info __UNUSED__)
3214 Evas_Object *obj = data;
3215 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3219 _edge_right(void *data,
3220 Evas_Object *scr __UNUSED__,
3221 void *event_info __UNUSED__)
3223 Evas_Object *obj = data;
3224 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3228 _edge_top(void *data,
3229 Evas_Object *scr __UNUSED__,
3230 void *event_info __UNUSED__)
3232 Evas_Object *obj = data;
3233 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3237 _edge_bottom(void *data,
3238 Evas_Object *scr __UNUSED__,
3239 void *event_info __UNUSED__)
3241 Evas_Object *obj = data;
3242 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3246 _decorate_item_realize(Elm_Gen_Item *it)
3250 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3252 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3253 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3254 edje_object_scale_set(it->item->deco_it_view,
3255 elm_widget_scale_get(WIDGET(it)) *
3256 _elm_config->scale);
3257 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3258 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3260 strncpy(buf, "item", sizeof(buf));
3261 if (it->wd->mode == ELM_LIST_COMPRESS)
3262 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3264 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3265 strncat(buf, "/", sizeof(buf) - strlen(buf));
3266 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3268 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3269 elm_widget_style_get(WIDGET(it)));
3270 edje_object_mirrored_set(it->item->deco_it_view,
3271 elm_widget_mirrored_get(WIDGET(it)));
3273 /* signal callback add */
3274 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3276 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3278 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3281 /* text_get, content_get, state_get */
3282 /* FIXME: If you see that assert, please notify us and we
3283 will clean our mess */
3284 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3286 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3287 if (!it->item->deco_it_contents)
3288 it->item->deco_it_contents =
3289 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3290 it->item->deco_it_content_objs =
3291 _item_mode_content_realize(it, it->item->deco_it_view,
3292 &it->item->deco_it_contents, NULL,
3293 &it->item->deco_it_content_objs);
3294 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3295 edje_object_part_swallow(it->item->deco_it_view,
3296 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3299 it->want_unrealize = EINA_FALSE;
3300 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3301 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3305 _decorate_item_unrealize(Elm_Gen_Item *it)
3307 Widget_Data *wd = it->wd;
3308 Evas_Object *content;
3309 if (!it->item->deco_it_view) return;
3311 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3312 elm_widget_stringlist_free(it->item->deco_it_texts);
3313 it->item->deco_it_texts = NULL;
3314 elm_widget_stringlist_free(it->item->deco_it_contents);
3315 it->item->deco_it_contents = NULL;
3316 elm_widget_stringlist_free(it->item->deco_it_states);
3318 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3319 evas_object_del(content);
3321 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3322 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3323 evas_object_del(it->item->deco_it_view);
3324 it->item->deco_it_view = NULL;
3326 if (wd->mode_item == it)
3327 wd->mode_item = NULL;
3328 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3329 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3333 _decorate_item_set(Elm_Gen_Item *it)
3336 Widget_Data *wd = it->wd;
3341 it->item->nocache_once = EINA_TRUE;
3343 if (wd->scr_hold_timer)
3345 ecore_timer_del(wd->scr_hold_timer);
3346 wd->scr_hold_timer = NULL;
3348 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3349 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3351 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3352 _decorate_item_realize(it);
3353 if (it->item->group_item)
3354 evas_object_raise(it->item->VIEW(group_item));
3355 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3356 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3357 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3359 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3360 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3364 _decorate_item_unset(Widget_Data *wd)
3367 if (!wd->mode_item) return;
3368 char buf[1024], buf2[1024];
3372 it->item->nocache_once = EINA_TRUE;
3374 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3375 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3377 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3378 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3380 wd->mode_item = NULL;
3384 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3386 if ((!it) || (!it->wd->decorate_all_mode)) return;
3387 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3388 evas_object_move(it->deco_all_view, itx, ity);
3392 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3395 const char *stacking_even;
3396 const char *stacking;
3398 if ((!it) || (it->item->decorate_all_item_realized) ||
3399 (it->generation < it->wd->generation))
3402 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3403 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3404 _elm_config->scale);
3405 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3406 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3408 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3409 strncpy(buf, "tree", sizeof(buf));
3410 else strncpy(buf, "item", sizeof(buf));
3411 if (it->wd->mode == ELM_LIST_COMPRESS)
3412 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3414 strncat(buf, "/", sizeof(buf) - strlen(buf));
3415 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3417 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3418 elm_widget_style_get(WIDGET(it)));
3420 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3421 if (!stacking_even) stacking_even = "above";
3422 it->item->stacking_even = !!strcmp("above", stacking_even);
3424 stacking = edje_object_data_get(VIEW(it), "stacking");
3425 if (!stacking) stacking = "yes";
3426 it->item->nostacking = !!strcmp("yes", stacking);
3428 edje_object_mirrored_set(it->deco_all_view,
3429 elm_widget_mirrored_get(WIDGET(it)));
3431 _elm_genlist_item_odd_even_update(it);
3432 _elm_genlist_item_state_update(it, NULL);
3434 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3435 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3437 _item_mouse_callbacks_del(it, VIEW(it));
3438 _item_mouse_callbacks_add(it, it->deco_all_view);
3440 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3441 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3442 if (!it->item->deco_all_contents)
3443 it->item->deco_all_contents =
3444 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "contents"));
3445 it->item->deco_all_content_objs =
3446 _item_mode_content_realize(it, it->deco_all_view,
3447 &it->item->deco_all_contents, NULL,
3448 &it->item->deco_all_content_objs);
3449 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3450 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3452 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3453 evas_object_show(it->deco_all_view);
3455 if (it->selected) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
3457 it->item->decorate_all_item_realized = EINA_TRUE;
3458 it->want_unrealize = EINA_FALSE;
3462 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3465 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3467 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3468 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3469 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3470 _elm_genlist_item_odd_even_update(it);
3471 _elm_genlist_item_state_update(it, NULL);
3473 evas_object_del(it->deco_all_view);
3474 it->deco_all_view = NULL;
3475 elm_widget_stringlist_free(it->item->deco_all_texts);
3476 it->item->deco_all_texts = NULL;
3477 elm_widget_stringlist_free(it->item->deco_all_contents);
3478 it->item->deco_all_contents = NULL;
3479 elm_widget_stringlist_free(it->item->deco_all_states);
3480 it->item->deco_all_states = NULL;
3481 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3482 evas_object_del(icon);
3483 edje_object_message_signal_process(it->deco_all_view);
3484 _item_mouse_callbacks_del(it, it->deco_all_view);
3485 _item_mouse_callbacks_add(it, VIEW(it));
3487 it->item->decorate_all_item_realized = EINA_FALSE;
3491 _item_auto_scroll(Widget_Data *wd)
3494 Elm_Gen_Item *tmp_item = NULL;
3496 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3498 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3499 if (!tmp_item) return;
3500 wd->show_item = tmp_item;
3501 wd->bring_in = EINA_TRUE;
3502 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3503 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3505 wd->show_item->item->showme = EINA_TRUE;
3506 wd->auto_scroll_enabled = EINA_FALSE;
3514 elm_genlist_add(Evas_Object *parent)
3519 Evas_Coord minw, minh;
3520 static Evas_Smart *smart = NULL;
3524 static Evas_Smart_Class sc;
3526 evas_object_smart_clipped_smart_set(&_pan_sc);
3528 sc.name = "elm_genlist_pan";
3529 sc.version = EVAS_SMART_CLASS_VERSION;
3532 sc.resize = _pan_resize;
3533 sc.move = _pan_move;
3534 sc.calculate = _pan_calculate;
3535 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3538 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3540 ELM_SET_WIDTYPE(widtype, "genlist");
3542 elm_widget_type_set(obj, "genlist");
3543 elm_widget_sub_object_add(parent, obj);
3544 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3545 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3546 elm_widget_data_set(obj, wd);
3547 elm_widget_del_hook_set(obj, _del_hook);
3548 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3549 elm_widget_theme_hook_set(obj, _theme_hook);
3550 elm_widget_can_focus_set(obj, EINA_TRUE);
3551 elm_widget_event_hook_set(obj, _event_hook);
3552 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3553 elm_widget_translate_hook_set(obj, _translate_hook);
3556 wd->scr = elm_smart_scroller_add(e);
3557 elm_smart_scroller_widget_set(wd->scr, obj);
3558 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3559 elm_widget_style_get(obj));
3560 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3561 _elm_config->thumbscroll_bounce_enable);
3562 elm_widget_resize_object_set(obj, wd->scr);
3564 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3565 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3566 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3567 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3568 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3569 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3570 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3571 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3574 wd->mode = ELM_LIST_SCROLL;
3575 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3576 wd->item_cache_max = wd->max_items_per_block * 2;
3577 wd->longpress_timeout = _elm_config->longpress_timeout;
3578 wd->highlight = EINA_TRUE;
3580 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3581 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3582 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3583 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3585 wd->pan_smart = evas_object_smart_add(e, smart);
3586 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3589 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3590 _pan_set, _pan_get, _pan_max_get,
3591 _pan_min_get, _pan_child_size_get);
3593 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3595 evas_object_size_hint_min_set(obj, minw, minh);
3597 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3599 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3605 _item_select(Elm_Gen_Item *it)
3607 Evas_Object *obj = WIDGET(it);
3609 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3610 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3611 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3615 it->selected = EINA_TRUE;
3616 it->wd->selected = eina_list_append(it->wd->selected, it);
3618 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3620 evas_object_ref(obj);
3623 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3624 if (it->generation == it->wd->generation)
3625 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3628 if ((it->wd->clear_me) && (!it->wd->walking))
3629 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3632 if ((!it->walking) && (it->generation < it->wd->generation))
3637 elm_widget_item_free(it);
3641 it->wd->last_selected_item = (Elm_Object_Item *)it;
3643 evas_object_unref(obj);
3646 static Evas_Object *
3647 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3649 return edje_object_part_swallow_get(VIEW(it), part);
3653 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
3655 if (!it->itc->func.text_get) return NULL;
3656 return edje_object_part_text_get(VIEW(it), part);
3660 _item_disable_hook(Elm_Object_Item *it)
3664 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3666 if (_it->generation < _it->wd->generation) return;
3669 elm_genlist_item_selected_set(it, EINA_FALSE);
3673 if (elm_widget_item_disabled_get(it))
3675 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
3676 if (_it->deco_all_view)
3677 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
3681 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
3682 if (_it->deco_all_view)
3683 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
3685 EINA_LIST_FOREACH(_it->content_objs, l, obj)
3686 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
3691 _item_del_pre_hook(Elm_Object_Item *it)
3693 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3695 if ((_it->relcount > 0) || (_it->walking > 0))
3697 elm_genlist_item_subitems_clear(it);
3698 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
3699 _elm_genlist_item_del_notserious(_it);
3700 if (_it->item->block)
3702 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
3703 _it->item->block->changed = EINA_TRUE;
3704 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
3705 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
3709 _it->parent->item->items =
3710 eina_list_remove(_it->parent->item->items, it);
3720 _item_signal_emit_hook(Elm_Object_Item *it,
3721 const char *emission,
3724 edje_object_signal_emit(VIEW(it), emission, source);
3728 _elm_genlist_item_new(Widget_Data *wd,
3729 const Elm_Gen_Item_Class *itc,
3731 Elm_Gen_Item *parent,
3733 const void *func_data)
3737 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3738 if (!it) return NULL;
3740 it->generation = wd->generation;
3742 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
3743 it->base.data = data;
3744 it->parent = parent;
3745 it->func.func = func;
3746 it->func.data = func_data;
3747 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3748 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
3749 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3750 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3751 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
3754 it->sel_cb = (Ecore_Cb)_item_select;
3759 static Elm_Gen_Item *
3760 _item_new(Widget_Data *wd,
3761 const Elm_Genlist_Item_Class *itc,
3763 Elm_Gen_Item *parent,
3764 Elm_Genlist_Item_Type type,
3766 const void *func_data)
3768 Elm_Gen_Item *it, *it2;
3771 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3772 if (!it) return NULL;
3773 it->item = ELM_NEW(Elm_Gen_Item_Type);
3774 it->item->type = type;
3775 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
3776 it->item->expanded_depth = 0;
3777 ELM_GEN_ITEM_SETUP(it);
3780 if (it->parent->group)
3781 it->item->group_item = parent;
3782 else if (it->parent->item->group_item)
3783 it->item->group_item = it->parent->item->group_item;
3785 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3787 if (!it2->parent->group) depth += 1;
3789 it->item->expanded_depth = depth;
3795 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3799 itb = calloc(1, sizeof(Item_Block));
3800 if (!itb) return NULL;
3804 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3805 _item_block_position_update(wd->blocks, 0);
3809 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3810 itb->position_update = EINA_TRUE;
3811 if (wd->blocks != EINA_INLIST_GET(itb))
3813 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3824 _item_block_add(Widget_Data *wd,
3827 Item_Block *itb = NULL;
3834 itb = calloc(1, sizeof(Item_Block));
3835 if (!itb) return EINA_FALSE;
3837 if (!it->item->rel->item->block)
3840 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3841 itb->items = eina_list_append(itb->items, it);
3842 itb->position_update = EINA_TRUE;
3843 it->position = eina_list_count(itb->items);
3844 it->position_update = EINA_TRUE;
3846 if (wd->blocks != EINA_INLIST_GET(itb))
3848 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3859 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3860 if (it->item->before)
3862 wd->blocks = eina_inlist_prepend_relative
3863 (wd->blocks, EINA_INLIST_GET(itb),
3864 EINA_INLIST_GET(it->item->rel->item->block));
3866 eina_list_prepend_relative_list(itb->items, it, tmp);
3868 /* Update index from where we prepended */
3869 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3870 _item_block_position_update(EINA_INLIST_GET(itb),
3871 it->item->rel->item->block->position);
3875 wd->blocks = eina_inlist_append_relative
3876 (wd->blocks, EINA_INLIST_GET(itb),
3877 EINA_INLIST_GET(it->item->rel->item->block));
3879 eina_list_append_relative_list(itb->items, it, tmp);
3881 /* Update block index from where we appended */
3882 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3883 _item_block_position_update(EINA_INLIST_GET(itb),
3884 it->item->rel->item->block->position + 1);
3890 if (it->item->before)
3894 itb = (Item_Block *)(wd->blocks);
3895 if (itb->count >= wd->max_items_per_block)
3897 itb = _item_block_new(wd, EINA_TRUE);
3898 if (!itb) return EINA_FALSE;
3903 itb = _item_block_new(wd, EINA_TRUE);
3904 if (!itb) return EINA_FALSE;
3906 itb->items = eina_list_prepend(itb->items, it);
3908 _item_position_update(itb->items, 0);
3914 itb = (Item_Block *)(wd->blocks->last);
3915 if (itb->count >= wd->max_items_per_block)
3917 itb = _item_block_new(wd, EINA_FALSE);
3918 if (!itb) return EINA_FALSE;
3923 itb = _item_block_new(wd, EINA_FALSE);
3924 if (!itb) return EINA_FALSE;
3926 itb->items = eina_list_append(itb->items, it);
3927 it->position = eina_list_count(itb->items);
3935 if (it->item->rel->item->queued)
3937 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3938 on sorted insertion order, so the queue is not always ordered like the item list.
3939 This lead to issue where we depend on an item that is not yet created. As a quick
3940 work around, we reschedule the calc of the item and stop reordering the list to
3941 prevent any nasty issue to show up here.
3943 wd->queue = eina_list_append(wd->queue, it);
3944 wd->requeued = EINA_TRUE;
3945 it->item->queued = EINA_TRUE;
3948 itb = it->item->rel->item->block;
3949 if (!itb) goto newblock;
3950 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3951 if (it->item->before)
3953 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3954 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3958 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3959 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3963 itb->changed = EINA_TRUE;
3964 it->item->block = itb;
3965 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3966 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3969 it->item->rel->relcount--;
3970 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3972 _item_del(it->item->rel);
3973 elm_widget_item_free(it->item->rel);
3975 it->item->rel = NULL;
3977 if (itb->count > itb->wd->max_items_per_block)
3982 Eina_Bool done = EINA_FALSE;
3984 newc = itb->count / 2;
3986 if (EINA_INLIST_GET(itb)->prev)
3988 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3990 if (itbp->count + newc < wd->max_items_per_block / 2)
3992 /* moving items to previous block */
3993 while ((itb->count > newc) && (itb->items))
3995 it2 = eina_list_data_get(itb->items);
3996 itb->items = eina_list_remove_list(itb->items, itb->items);
3999 itbp->items = eina_list_append(itbp->items, it2);
4000 it2->item->block = itbp;
4008 if (!done && EINA_INLIST_GET(itb)->next)
4010 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4012 if (itbn->count + newc < wd->max_items_per_block / 2)
4014 /* moving items to next block */
4015 while ((itb->count > newc) && (itb->items))
4019 l = eina_list_last(itb->items);
4020 it2 = eina_list_data_get(l);
4021 itb->items = eina_list_remove_list(itb->items, l);
4024 itbn->items = eina_list_prepend(itbn->items, it2);
4025 it2->item->block = itbn;
4035 /* moving items to new block */
4036 itb2 = calloc(1, sizeof(Item_Block));
4037 if (!itb2) return EINA_FALSE;
4040 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4041 EINA_INLIST_GET(itb));
4042 itb2->changed = EINA_TRUE;
4043 while ((itb->count > newc) && (itb->items))
4047 l = eina_list_last(itb->items);
4049 itb->items = eina_list_remove_list(itb->items, l);
4052 itb2->items = eina_list_prepend(itb2->items, it2);
4053 it2->item->block = itb2;
4063 _queue_process(Widget_Data *wd)
4066 Eina_Bool showme = EINA_FALSE;
4069 t0 = ecore_loop_time_get();
4070 //evas_event_freeze(evas_object_evas_get(wd->obj));
4071 for (n = 0; (wd->queue) && (n < 128); n++)
4075 it = eina_list_data_get(wd->queue);
4076 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4077 it->item->queued = EINA_FALSE;
4078 if (!_item_block_add(wd, it)) continue;
4080 _item_block_realize(it->item->block);
4081 t = ecore_time_get();
4082 if (it->item->block->changed)
4084 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4085 it->item->block->changed = 0;
4086 if (wd->pan_changed)
4088 if (wd->calc_job) ecore_job_del(wd->calc_job);
4089 wd->calc_job = NULL;
4091 wd->pan_changed = EINA_FALSE;
4094 if (showme) it->item->block->showme = EINA_TRUE;
4095 /* same as eina_inlist_count > 1 */
4096 if (wd->blocks && wd->blocks->next)
4098 if ((t - t0) > (ecore_animator_frametime_get())) break;
4101 //evas_event_thaw(evas_object_evas_get(wd->obj));
4102 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4107 _idle_process(void *data, Eina_Bool *wakeup)
4109 Widget_Data *wd = data;
4112 //static double q_start = 0.0;
4113 //if (q_start == 0.0) q_start = ecore_time_get();
4115 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4119 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4121 return ECORE_CALLBACK_CANCEL;
4123 return ECORE_CALLBACK_RENEW;
4127 _item_idle_enterer(void *data)
4129 Widget_Data *wd = data;
4130 Eina_Bool wakeup = EINA_FALSE;
4131 Eina_Bool ok = _idle_process(data, &wakeup);
4136 if (wd->calc_job) ecore_job_del(wd->calc_job);
4137 wd->calc_job = ecore_job_add(_calc_job, wd);
4139 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4144 _item_queue(Widget_Data *wd,
4148 if (it->item->queued) return;
4149 it->item->queued = EINA_TRUE;
4150 if (cb && !wd->requeued)
4151 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4153 wd->queue = eina_list_append(wd->queue, it);
4154 // FIXME: why does a freeze then thaw here cause some genlist
4155 // elm_genlist_item_append() to be much much slower?
4156 // evas_event_freeze(evas_object_evas_get(wd->obj));
4157 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4159 if (wd->queue_idle_enterer)
4161 ecore_idle_enterer_del(wd->queue_idle_enterer);
4162 wd->queue_idle_enterer = NULL;
4166 // evas_event_thaw(evas_object_evas_get(wd->obj));
4167 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4168 if (!wd->queue_idle_enterer)
4169 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4173 _elm_genlist_item_compare(const void *data, const void *data1)
4175 const Elm_Gen_Item *it, *item1;
4176 it = ELM_GEN_ITEM_FROM_INLIST(data);
4177 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4178 return it->wd->item_compare_cb(it, item1);
4182 _elm_genlist_item_list_compare(const void *data, const void *data1)
4184 const Elm_Gen_Item *it = data;
4185 const Elm_Gen_Item *item1 = data1;
4186 return it->wd->item_compare_cb(it, item1);
4189 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4191 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4196 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4197 _item_block_del(it);
4199 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4200 it->item->rel = after;
4201 it->item->rel->relcount++;
4202 it->item->before = EINA_FALSE;
4203 if (after->item->group_item) it->item->group_item = after->item->group_item;
4204 _item_queue(it->wd, it, NULL);
4206 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4209 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4211 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4214 if (!before) return;
4216 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4217 _item_block_del(it);
4218 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4219 it->item->rel = before;
4220 it->item->rel->relcount++;
4221 it->item->before = EINA_TRUE;
4222 if (before->item->group_item) it->item->group_item = before->item->group_item;
4223 _item_queue(it->wd, it, NULL);
4225 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4229 elm_genlist_items_count(const Evas_Object *obj)
4231 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4232 Widget_Data *wd = elm_widget_data_get(obj);
4234 return wd->item_count;
4237 EAPI Elm_Object_Item *
4238 elm_genlist_item_append(Evas_Object *obj,
4239 const Elm_Genlist_Item_Class *itc,
4241 Elm_Object_Item *parent,
4242 Elm_Genlist_Item_Type type,
4244 const void *func_data)
4246 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4247 Widget_Data *wd = elm_widget_data_get(obj);
4248 if (!wd) return NULL;
4249 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4251 if (!it) return NULL;
4255 wd->group_items = eina_list_append(wd->group_items, it);
4256 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4257 it->item->rel = NULL;
4261 Elm_Gen_Item *it2 = NULL;
4262 Eina_List *ll = eina_list_last(it->parent->item->items);
4263 if (ll) it2 = ll->data;
4264 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4265 if (!it2) it2 = it->parent;
4267 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4268 EINA_INLIST_GET(it2));
4269 it->item->rel = it2;
4270 it->item->rel->relcount++;
4272 it->item->before = EINA_FALSE;
4273 _item_queue(wd, it, NULL);
4274 return (Elm_Object_Item *)it;
4277 EAPI Elm_Object_Item *
4278 elm_genlist_item_prepend(Evas_Object *obj,
4279 const Elm_Genlist_Item_Class *itc,
4281 Elm_Object_Item *parent,
4282 Elm_Genlist_Item_Type type,
4284 const void *func_data)
4286 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4287 Widget_Data *wd = elm_widget_data_get(obj);
4288 if (!wd) return NULL;
4289 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4291 if (!it) return NULL;
4295 wd->group_items = eina_list_prepend(wd->group_items, it);
4296 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4297 it->item->rel = NULL;
4301 Elm_Gen_Item *it2 = NULL;
4302 Eina_List *ll = it->parent->item->items;
4303 if (ll) it2 = ll->data;
4304 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4305 if (!it2) it2 = it->parent;
4307 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4308 EINA_INLIST_GET(it2));
4309 it->item->rel = it2;
4310 it->item->rel->relcount++;
4312 it->item->before = EINA_TRUE;
4313 _item_queue(wd, it, NULL);
4314 return (Elm_Object_Item *)it;
4317 EAPI Elm_Object_Item *
4318 elm_genlist_item_insert_after(Evas_Object *obj,
4319 const Elm_Genlist_Item_Class *itc,
4321 Elm_Object_Item *parent,
4322 Elm_Object_Item *after,
4323 Elm_Genlist_Item_Type type,
4325 const void *func_data)
4327 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4328 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4329 Widget_Data *wd = elm_widget_data_get(obj);
4330 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4331 if (!wd) return NULL;
4332 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4333 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4335 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4337 if (!it) return NULL;
4340 if ((it->group) && (_after->group))
4341 wd->group_items = eina_list_append_relative(wd->group_items, it,
4346 it->parent->item->items =
4347 eina_list_append_relative(it->parent->item->items, it, _after);
4349 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4350 EINA_INLIST_GET(_after));
4351 it->item->rel = _after;
4352 it->item->rel->relcount++;
4353 it->item->before = EINA_FALSE;
4354 _item_queue(wd, it, NULL);
4355 return (Elm_Object_Item *)it;
4358 EAPI Elm_Object_Item *
4359 elm_genlist_item_insert_before(Evas_Object *obj,
4360 const Elm_Genlist_Item_Class *itc,
4362 Elm_Object_Item *parent,
4363 Elm_Object_Item *before,
4364 Elm_Genlist_Item_Type type,
4366 const void *func_data)
4368 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4369 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4370 Widget_Data *wd = elm_widget_data_get(obj);
4371 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4372 if (!wd) return NULL;
4373 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4374 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4376 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4378 if (!it) return NULL;
4381 if (it->group && _before->group)
4382 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4387 it->parent->item->items =
4388 eina_list_prepend_relative(it->parent->item->items, it, _before);
4390 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4391 EINA_INLIST_GET(_before));
4392 it->item->rel = _before;
4393 it->item->rel->relcount++;
4394 it->item->before = EINA_TRUE;
4395 _item_queue(wd, it, NULL);
4396 return (Elm_Object_Item *)it;
4399 EAPI Elm_Object_Item *
4400 elm_genlist_item_sorted_insert(Evas_Object *obj,
4401 const Elm_Genlist_Item_Class *itc,
4403 Elm_Object_Item *parent,
4404 Elm_Genlist_Item_Type type,
4405 Eina_Compare_Cb comp,
4407 const void *func_data)
4409 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4410 Widget_Data *wd = elm_widget_data_get(obj);
4411 if (!wd) return NULL;
4412 Elm_Gen_Item *rel = NULL;
4413 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4415 if (!it) return NULL;
4417 wd->item_compare_cb = comp;
4424 l = eina_list_search_sorted_near_list(it->parent->item->items,
4425 _elm_genlist_item_list_compare,
4429 rel = eina_list_data_get(l);
4433 if (cmp_result >= 0)
4435 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4436 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4437 it->item->before = EINA_FALSE;
4439 else if (cmp_result < 0)
4441 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4442 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4443 it->item->before = EINA_TRUE;
4450 wd->state = eina_inlist_sorted_state_new();
4451 eina_inlist_sorted_state_init(wd->state, wd->items);
4452 wd->requeued = EINA_FALSE;
4456 wd->group_items = eina_list_append(wd->group_items, it);
4458 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4459 _elm_genlist_item_compare, wd->state);
4461 if (EINA_INLIST_GET(it)->next)
4463 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4464 it->item->before = EINA_TRUE;
4466 else if (EINA_INLIST_GET(it)->prev)
4468 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4469 it->item->before = EINA_FALSE;
4475 it->item->rel = rel;
4476 it->item->rel->relcount++;
4479 _item_queue(wd, it, _elm_genlist_item_list_compare);
4481 return (Elm_Object_Item *)it;
4485 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4487 Eina_Inlist *next, *l;
4488 Widget_Data *wd = elm_widget_data_get(obj);
4491 if (!standby) wd->generation++;
4495 eina_inlist_sorted_state_free(wd->state);
4499 if (wd->walking > 0)
4501 wd->clear_me = EINA_TRUE;
4504 evas_event_freeze(evas_object_evas_get(wd->obj));
4505 for (l = wd->items, next = l ? l->next : NULL;
4507 l = next, next = next ? next->next : NULL)
4509 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4511 if (it->generation < wd->generation)
4513 Elm_Gen_Item *itn = NULL;
4515 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4516 if (itn) itn->walking++; /* prevent early death of subitem */
4518 elm_widget_item_free(it);
4519 if (itn) itn->walking--;
4522 wd->clear_me = EINA_FALSE;
4523 wd->pan_changed = EINA_TRUE;
4526 ecore_job_del(wd->calc_job);
4527 wd->calc_job = NULL;
4529 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4530 if (wd->clear_cb) wd->clear_cb(wd);
4536 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4537 wd->alpha_bg = NULL;
4541 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4542 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4544 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4545 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4546 evas_event_thaw(evas_object_evas_get(wd->obj));
4547 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4551 elm_genlist_clear(Evas_Object *obj)
4553 ELM_CHECK_WIDTYPE(obj, widtype);
4554 _elm_genlist_clear(obj, EINA_FALSE);
4558 elm_genlist_multi_select_set(Evas_Object *obj,
4561 ELM_CHECK_WIDTYPE(obj, widtype);
4562 Widget_Data *wd = elm_widget_data_get(obj);
4564 wd->multi = !!multi;
4568 elm_genlist_multi_select_get(const Evas_Object *obj)
4570 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4571 Widget_Data *wd = elm_widget_data_get(obj);
4572 if (!wd) return EINA_FALSE;
4576 EAPI Elm_Object_Item *
4577 elm_genlist_selected_item_get(const Evas_Object *obj)
4579 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4580 Widget_Data *wd = elm_widget_data_get(obj);
4581 if (!wd) return NULL;
4582 if (wd->selected) return wd->selected->data;
4586 EAPI const Eina_List *
4587 elm_genlist_selected_items_get(const Evas_Object *obj)
4589 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4590 Widget_Data *wd = elm_widget_data_get(obj);
4591 if (!wd) return NULL;
4592 return wd->selected;
4596 elm_genlist_realized_items_get(const Evas_Object *obj)
4598 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4599 Widget_Data *wd = elm_widget_data_get(obj);
4600 Eina_List *list = NULL;
4602 Eina_Bool done = EINA_FALSE;
4603 if (!wd) return NULL;
4604 EINA_INLIST_FOREACH(wd->blocks, itb)
4612 EINA_LIST_FOREACH(itb->items, l, it)
4614 if (it->realized) list = eina_list_append(list, it);
4625 EAPI Elm_Object_Item *
4626 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4631 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4632 Widget_Data *wd = elm_widget_data_get(obj);
4633 Evas_Coord ox, oy, ow, oh;
4636 if (!wd) return NULL;
4637 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4639 EINA_INLIST_FOREACH(wd->blocks, itb)
4644 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4645 oy + itb->y - itb->wd->pan_y,
4646 itb->w, itb->h, x, y, 1, 1))
4648 EINA_LIST_FOREACH(itb->items, l, it)
4650 Evas_Coord itx, ity;
4652 itx = ox + itb->x + it->x - itb->wd->pan_x;
4653 ity = oy + itb->y + it->y - itb->wd->pan_y;
4654 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4658 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4659 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4663 return (Elm_Object_Item *)it;
4665 lasty = ity + it->item->h;
4670 if (y > lasty) *posret = 1;
4676 EAPI Elm_Object_Item *
4677 elm_genlist_first_item_get(const Evas_Object *obj)
4679 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4680 Widget_Data *wd = elm_widget_data_get(obj);
4681 if (!wd) return NULL;
4682 if (!wd->items) return NULL;
4683 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4684 while ((it) && (it->generation < wd->generation))
4685 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4686 return (Elm_Object_Item *)it;
4689 EAPI Elm_Object_Item *
4690 elm_genlist_last_item_get(const Evas_Object *obj)
4692 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4693 Widget_Data *wd = elm_widget_data_get(obj);
4694 if (!wd) return NULL;
4695 if (!wd->items) return NULL;
4696 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4697 while ((it) && (it->generation < wd->generation))
4698 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4699 return (Elm_Object_Item *)it;
4702 EAPI Elm_Object_Item *
4703 elm_genlist_item_next_get(const Elm_Object_Item *it)
4705 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4706 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4709 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
4710 if ((_it) && (_it->generation == _it->wd->generation)) break;
4712 return (Elm_Object_Item *) _it;
4715 EAPI Elm_Object_Item *
4716 elm_genlist_item_prev_get(const Elm_Object_Item *it)
4718 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4719 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4722 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
4723 if ((_it) && (_it->generation == _it->wd->generation)) break;
4725 return (Elm_Object_Item *) _it;
4728 EAPI Elm_Object_Item *
4729 elm_genlist_item_parent_get(const Elm_Object_Item *it)
4731 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4732 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
4736 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
4738 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4739 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
4741 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4743 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
4744 _item_subitems_clear(_it);
4747 if (!wd->tree_effect_animator)
4749 wd->expanded_item = _it;
4750 _item_tree_effect_before(_it);
4751 evas_object_raise(wd->alpha_bg);
4752 evas_object_show(wd->alpha_bg);
4753 wd->start_time = ecore_time_get();
4754 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
4757 _item_subitems_clear(_it);
4762 elm_genlist_item_selected_set(Elm_Object_Item *it,
4765 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4766 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4767 Widget_Data *wd = _it->wd;
4769 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
4771 selected = !!selected;
4772 if (_it->selected == selected) return;
4778 while (wd->selected)
4780 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
4781 _it->unsel_cb(wd->selected->data);
4784 _it->highlight_cb(_it);
4788 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
4793 elm_genlist_item_selected_get(const Elm_Object_Item *it)
4795 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4796 return ((Elm_Gen_Item *)it)->selected;
4800 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
4803 if (it->item->expanded)
4805 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4809 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4812 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
4813 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4820 _elm_genlist_move_items_set(Elm_Gen_Item *it)
4823 Elm_Gen_Item *it2 = NULL;
4824 Evas_Coord ox, oy, ow, oh, dh = 0;
4826 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
4828 if (it->item->expanded)
4830 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
4831 EINA_LIST_FOREACH_SAFE(it->wd->move_items, l, ll, it2)
4833 if (it2 == it->wd->expanded_next_item) break;
4834 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
4839 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
4840 it2 = it->wd->expanded_next_item;
4841 while (it2 && (dh < oy + oh))
4844 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
4845 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4851 elm_genlist_item_expanded_set(Elm_Object_Item *it,
4854 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4855 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4856 expanded = !!expanded;
4857 if (_it->item->expanded == expanded) return;
4858 _it->item->expanded = expanded;
4859 _it->wd->expanded_item = _it;
4860 _elm_genlist_move_items_set(_it);
4862 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
4863 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
4865 if (_it->item->expanded)
4867 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
4869 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
4870 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
4871 _it->wd->auto_scroll_enabled = EINA_TRUE;
4875 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
4877 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
4878 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
4879 _it->wd->auto_scroll_enabled = EINA_FALSE;
4884 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
4886 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4887 return ((Elm_Gen_Item *)it)->item->expanded;
4891 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
4893 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
4894 return ((Elm_Gen_Item *)it)->item->expanded_depth;
4898 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
4899 Elm_Genlist_Item_Scrollto_Type type,
4906 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4907 Evas_Coord gith = 0;
4908 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4909 if ((_it->item->queued) || (!_it->item->mincalcd))
4911 _it->wd->show_item = _it;
4912 _it->wd->bring_in = bring_in;
4913 _it->wd->scrollto_type = type;
4914 _it->item->showme = EINA_TRUE;
4917 if (_it->wd->show_item)
4919 _it->wd->show_item->item->showme = EINA_FALSE;
4920 _it->wd->show_item = NULL;
4923 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
4926 case ELM_GENLIST_ITEM_SCROLLTO_IN:
4927 if ((_it->item->group_item) &&
4928 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4929 gith = _it->item->group_item->item->h;
4931 *y = _it->y + _it->item->block->y - gith;
4933 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
4934 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4935 *y = _it->y + _it->item->block->y - gith;
4937 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
4938 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
4944 *x = _it->x + _it->item->block->x;
4945 *w = _it->item->block->w;
4950 elm_genlist_item_promote(Elm_Object_Item *it)
4952 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4953 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4954 if (_it->generation < _it->wd->generation) return;
4955 _item_move_before(_it,
4956 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
4960 elm_genlist_item_demote(Elm_Object_Item *it)
4962 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4963 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4964 if (_it->generation < _it->wd->generation) return;
4965 _item_move_after(_it,
4966 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
4970 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4972 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4973 Evas_Coord x, y, w, h;
4974 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4976 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
4977 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
4981 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4984 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4985 Evas_Coord x, y, w, h;
4986 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4988 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
4989 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
4993 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
4995 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4997 Evas_Object *content;
4998 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5000 elm_widget_sub_object_del(WIDGET(it), content);
5001 evas_object_smart_member_del(content);
5002 evas_object_hide(content);
5003 if (l) *l = eina_list_append(*l, content);
5008 elm_genlist_item_update(Elm_Object_Item *it)
5010 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5011 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5013 if (!_it->item->block) return;
5014 if (_it->generation < _it->wd->generation) return;
5015 _it->item->mincalcd = EINA_FALSE;
5016 _it->item->updateme = EINA_TRUE;
5017 _it->item->block->updateme = EINA_TRUE;
5018 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5019 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5023 elm_genlist_item_fields_update(Elm_Object_Item *it,
5025 Elm_Genlist_Item_Field_Type itf)
5027 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5028 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5030 if (!_it->item->block) return;
5031 if (_it->generation < _it->wd->generation) return;
5033 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5034 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5035 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5037 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5038 &_it->contents, parts);
5039 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5040 &_it->contents, parts);
5044 _it->item->flip_content_objs =
5045 _item_mode_content_unrealize(_it, VIEW(_it),
5046 &_it->item->flip_contents, parts,
5047 &_it->item->flip_content_objs);
5048 _it->item->flip_content_objs =
5049 _item_mode_content_realize(_it, VIEW(_it),
5050 &_it->item->flip_contents, parts,
5051 &_it->item->flip_content_objs);
5053 if (_it->item->deco_it_view)
5055 _it->item->deco_it_content_objs =
5056 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5057 &_it->item->deco_it_contents, parts,
5058 &_it->item->deco_it_content_objs);
5059 _it->item->deco_it_content_objs =
5060 _item_mode_content_realize(_it, _it->item->deco_it_view,
5061 &_it->item->deco_it_contents, parts,
5062 &_it->item->deco_it_content_objs);
5064 if (_it->wd->decorate_all_mode)
5066 _it->item->deco_all_content_objs =
5067 _item_mode_content_unrealize(_it, _it->deco_all_view,
5068 &_it->item->deco_all_contents, parts,
5069 &_it->item->deco_all_content_objs);
5070 _it->item->deco_all_content_objs =
5071 _item_mode_content_realize(_it, _it->deco_all_view,
5072 &_it->item->deco_all_contents, parts,
5073 &_it->item->deco_all_content_objs);
5076 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5077 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5081 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5082 const Elm_Genlist_Item_Class *itc)
5084 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5085 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5087 if (!_it->item->block) return;
5088 EINA_SAFETY_ON_NULL_RETURN(itc);
5089 if (_it->generation < _it->wd->generation) return;
5091 _it->item->nocache_once = EINA_TRUE;
5093 elm_widget_stringlist_free(_it->texts);
5095 elm_widget_stringlist_free(_it->contents);
5096 _it->contents = NULL;
5097 elm_widget_stringlist_free(_it->states);
5102 elm_widget_stringlist_free(_it->item->flip_contents);
5103 _it->item->flip_contents = NULL;
5105 if (_it->item->deco_it_view)
5107 elm_widget_stringlist_free(_it->item->deco_it_texts);
5108 _it->item->deco_it_texts = NULL;
5109 elm_widget_stringlist_free(_it->item->deco_it_contents);
5110 _it->item->deco_it_contents = NULL;
5112 if (_it->wd->decorate_all_mode)
5114 elm_widget_stringlist_free(_it->item->deco_all_texts);
5115 _it->item->deco_all_texts = NULL;
5116 elm_widget_stringlist_free(_it->item->deco_all_contents);
5117 _it->item->deco_all_contents = NULL;
5120 elm_genlist_item_update(it);
5123 EAPI const Elm_Genlist_Item_Class *
5124 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5126 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5127 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5128 if (_it->generation < _it->wd->generation) return NULL;
5132 static Evas_Object *
5133 _elm_genlist_item_label_create(void *data,
5134 Evas_Object *obj __UNUSED__,
5135 Evas_Object *tooltip,
5136 void *it __UNUSED__)
5138 Evas_Object *label = elm_label_add(tooltip);
5141 elm_object_style_set(label, "tooltip");
5142 elm_object_text_set(label, data);
5147 _elm_genlist_item_label_del_cb(void *data,
5148 Evas_Object *obj __UNUSED__,
5149 void *event_info __UNUSED__)
5151 eina_stringshare_del(data);
5155 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5158 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5159 text = eina_stringshare_add(text);
5160 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5162 _elm_genlist_item_label_del_cb);
5166 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5167 Elm_Tooltip_Item_Content_Cb func,
5169 Evas_Smart_Cb del_cb)
5171 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5172 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5174 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5177 if (_it->tooltip.del_cb)
5178 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5180 _it->tooltip.content_cb = func;
5181 _it->tooltip.data = data;
5182 _it->tooltip.del_cb = del_cb;
5186 elm_widget_item_tooltip_content_cb_set(_it,
5187 _it->tooltip.content_cb,
5188 _it->tooltip.data, NULL);
5189 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5190 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5196 if (del_cb) del_cb((void *)data, NULL, NULL);
5200 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5202 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5203 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5205 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5206 elm_widget_item_tooltip_unset(_it);
5208 if (_it->tooltip.del_cb)
5209 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5210 _it->tooltip.del_cb = NULL;
5211 _it->tooltip.content_cb = NULL;
5212 _it->tooltip.data = NULL;
5213 _it->tooltip.free_size = EINA_FALSE;
5214 if (_it->tooltip.style)
5215 elm_genlist_item_tooltip_style_set(it, NULL);
5219 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5222 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5223 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5225 eina_stringshare_replace(&_it->tooltip.style, style);
5226 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5230 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5232 return elm_object_item_tooltip_style_get(it);
5236 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5239 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5240 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5242 _it->tooltip.free_size = disable;
5243 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5248 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5250 return elm_object_tooltip_window_mode_get(VIEW(it));
5254 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5257 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5258 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5259 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5260 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5264 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5266 return elm_widget_item_cursor_get(it);
5270 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5272 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5273 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5275 if (!_it->mouse_cursor) return;
5277 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5279 eina_stringshare_del(_it->mouse_cursor);
5280 _it->mouse_cursor = NULL;
5284 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5287 elm_widget_item_cursor_style_set(it, style);
5291 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5293 return elm_widget_item_cursor_style_get(it);
5297 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5298 Eina_Bool engine_only)
5300 elm_widget_item_cursor_engine_only_set(it, engine_only);
5304 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5306 return elm_widget_item_cursor_engine_only_get(it);
5310 elm_genlist_item_index_get(const Elm_Object_Item *it)
5312 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5313 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5315 if (_it->item->block)
5316 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5321 elm_genlist_mode_set(Evas_Object *obj,
5324 ELM_CHECK_WIDTYPE(obj, widtype);
5325 Widget_Data *wd = elm_widget_data_get(obj);
5327 if (wd->mode == mode) return;
5329 if (wd->mode == ELM_LIST_COMPRESS)
5330 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5336 elm_genlist_mode_get(const Evas_Object *obj)
5338 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5339 Widget_Data *wd = elm_widget_data_get(obj);
5340 if (!wd) return ELM_LIST_LAST;
5345 elm_genlist_bounce_set(Evas_Object *obj,
5349 ELM_CHECK_WIDTYPE(obj, widtype);
5350 Widget_Data *wd = elm_widget_data_get(obj);
5352 wd->h_bounce = !!h_bounce;
5353 wd->v_bounce = !!v_bounce;
5354 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5358 elm_genlist_bounce_get(const Evas_Object *obj,
5359 Eina_Bool *h_bounce,
5360 Eina_Bool *v_bounce)
5362 ELM_CHECK_WIDTYPE(obj, widtype);
5363 Widget_Data *wd = elm_widget_data_get(obj);
5365 if (h_bounce) *h_bounce = wd->h_bounce;
5366 if (v_bounce) *v_bounce = wd->v_bounce;
5370 elm_genlist_homogeneous_set(Evas_Object *obj,
5371 Eina_Bool homogeneous)
5373 ELM_CHECK_WIDTYPE(obj, widtype);
5374 Widget_Data *wd = elm_widget_data_get(obj);
5376 wd->homogeneous = !!homogeneous;
5380 elm_genlist_homogeneous_get(const Evas_Object *obj)
5382 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5383 Widget_Data *wd = elm_widget_data_get(obj);
5384 if (!wd) return EINA_FALSE;
5385 return wd->homogeneous;
5389 elm_genlist_block_count_set(Evas_Object *obj,
5392 ELM_CHECK_WIDTYPE(obj, widtype);
5393 Widget_Data *wd = elm_widget_data_get(obj);
5395 wd->max_items_per_block = count;
5396 wd->item_cache_max = wd->max_items_per_block * 2;
5397 _item_cache_clean(wd);
5401 elm_genlist_block_count_get(const Evas_Object *obj)
5403 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5404 Widget_Data *wd = elm_widget_data_get(obj);
5406 return wd->max_items_per_block;
5410 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5413 ELM_CHECK_WIDTYPE(obj, widtype);
5414 Widget_Data *wd = elm_widget_data_get(obj);
5416 wd->longpress_timeout = timeout;
5420 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5422 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5423 Widget_Data *wd = elm_widget_data_get(obj);
5425 return wd->longpress_timeout;
5429 elm_genlist_scroller_policy_set(Evas_Object *obj,
5430 Elm_Scroller_Policy policy_h,
5431 Elm_Scroller_Policy policy_v)
5433 ELM_CHECK_WIDTYPE(obj, widtype);
5434 Widget_Data *wd = elm_widget_data_get(obj);
5435 if ((!wd) || (!wd->scr)) return;
5436 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5437 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5439 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5443 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5444 Elm_Scroller_Policy *policy_h,
5445 Elm_Scroller_Policy *policy_v)
5447 ELM_CHECK_WIDTYPE(obj, widtype);
5448 Widget_Data *wd = elm_widget_data_get(obj);
5449 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5450 if ((!wd) || (!wd->scr)) return;
5451 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5452 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5453 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5457 elm_genlist_realized_items_update(Evas_Object *obj)
5459 ELM_CHECK_WIDTYPE(obj, widtype);
5461 Eina_List *list, *l;
5462 Elm_Object_Item *it;
5464 list = elm_genlist_realized_items_get(obj);
5465 EINA_LIST_FOREACH(list, l, it)
5466 elm_genlist_item_update(it);
5470 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5471 const char *decorate_it_type,
5472 Eina_Bool decorate_it_set)
5474 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5475 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5477 Widget_Data *wd = _it->wd;
5479 Elm_Object_Item *it2;
5482 if (!decorate_it_type) return;
5483 if ((_it->generation < _it->wd->generation) ||
5484 elm_widget_item_disabled_get(_it)) return;
5485 if (wd->decorate_all_mode) return;
5487 if ((wd->mode_item == _it) &&
5488 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5491 if (!_it->itc->decorate_item_style) return;
5492 _it->decorate_it_set = decorate_it_set;
5496 EINA_LIST_FOREACH(wd->selected, l, it2)
5497 if (((Elm_Gen_Item *)it2)->realized)
5498 elm_genlist_item_selected_set(it2, EINA_FALSE);
5502 it2 = elm_genlist_selected_item_get(wd->obj);
5503 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5504 elm_genlist_item_selected_set(it2, EINA_FALSE);
5507 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5508 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5509 _decorate_item_unset(wd);
5511 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5512 if (decorate_it_set) _decorate_item_set(_it);
5516 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5518 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5519 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5520 return _it->wd->decorate_it_type;
5523 EAPI const Elm_Object_Item *
5524 elm_genlist_decorated_item_get(const Evas_Object *obj)
5526 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5527 Widget_Data *wd = elm_widget_data_get(obj);
5528 if (!wd) return NULL;
5529 return (Elm_Object_Item *) wd->mode_item;
5533 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5535 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5536 Widget_Data *wd = elm_widget_data_get(obj);
5537 if (!wd) return EINA_FALSE;
5539 return wd->decorate_all_mode;
5543 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5545 ELM_CHECK_WIDTYPE(obj, widtype);
5546 Eina_List *list, *l;
5549 Widget_Data *wd = elm_widget_data_get(obj);
5551 decorated = !!decorated;
5552 if (wd->decorate_all_mode == decorated) return;
5553 wd->decorate_all_mode = decorated;
5555 list = elm_genlist_realized_items_get(obj);
5556 if (!wd->decorate_all_mode)
5558 EINA_LIST_FOREACH(list, l, it)
5560 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5561 _decorate_all_item_unrealize(it);
5563 _item_cache_zero(wd);
5567 EINA_LIST_FOREACH(list, l, it)
5569 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5571 if (it->itc->decorate_all_item_style)
5572 _decorate_all_item_realize(it, EINA_TRUE);
5576 if (wd->calc_job) ecore_job_del(wd->calc_job);
5577 wd->calc_job = ecore_job_add(_calc_job, wd);
5581 elm_genlist_reorder_mode_set(Evas_Object *obj,
5582 Eina_Bool reorder_mode)
5584 ELM_CHECK_WIDTYPE(obj, widtype);
5585 Widget_Data *wd = elm_widget_data_get(obj);
5587 wd->reorder_mode = !!reorder_mode;
5591 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5593 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5594 Widget_Data *wd = elm_widget_data_get(obj);
5595 if (!wd) return EINA_FALSE;
5596 return wd->reorder_mode;
5599 EAPI Elm_Genlist_Item_Type
5600 elm_genlist_item_type_get(const Elm_Object_Item *it)
5602 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5603 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5604 return _it->item->type;
5607 EAPI Elm_Genlist_Item_Class *
5608 elm_genlist_item_class_new(void)
5610 Elm_Genlist_Item_Class *itc;
5612 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5615 itc->version = CLASS_ALLOCATED;
5617 itc->delete_me = EINA_FALSE;
5623 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5625 if (itc && (itc->version == CLASS_ALLOCATED))
5627 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5628 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5638 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5640 if (itc && (itc->version == CLASS_ALLOCATED))
5643 if (itc->refcount == 0) itc->refcount--;
5648 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5650 if (itc && (itc->version == CLASS_ALLOCATED))
5652 if (itc->refcount > 0) itc->refcount--;
5653 if (itc->delete_me && (!itc->refcount))
5654 elm_genlist_item_class_free(itc);
5658 void _flip_job(void *data)
5660 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
5661 _item_unhighlight(it);
5663 _elm_genlist_item_unrealize(it, EINA_FALSE);
5664 it->flipped = EINA_TRUE;
5665 it->item->nocache = EINA_TRUE;
5666 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5667 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
5671 elm_genlist_item_flip_set(Elm_Object_Item *it,
5674 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5675 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5678 if (_it->flipped == flip) return;
5682 ecore_job_add(_flip_job, _it);
5686 _it->flipped = flip;
5687 _item_cache_zero(_it->wd);
5688 elm_genlist_item_update(it);
5689 _it->item->nocache = EINA_FALSE;
5694 elm_genlist_item_flip_get(const Elm_Object_Item *it)
5696 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5697 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5698 return _it->flipped;
5702 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
5704 ELM_CHECK_WIDTYPE(obj, widtype);
5705 Widget_Data *wd = elm_widget_data_get(obj);
5707 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5709 if (wd->select_mode != mode)
5710 wd->select_mode = mode;
5713 EAPI Elm_Object_Select_Mode
5714 elm_genlist_select_mode_get(const Evas_Object *obj)
5716 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
5717 Widget_Data *wd = elm_widget_data_get(obj);
5718 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
5719 return wd->select_mode;
5723 elm_genlist_highlight_mode_set(Evas_Object *obj,
5724 Eina_Bool highlight)
5726 ELM_CHECK_WIDTYPE(obj, widtype);
5727 Widget_Data *wd = elm_widget_data_get(obj);
5729 wd->highlight = !!highlight;
5733 elm_genlist_highlight_mode_get(const Evas_Object *obj)
5735 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5736 Widget_Data *wd = elm_widget_data_get(obj);
5737 if (!wd) return EINA_FALSE;
5738 return wd->highlight;
5742 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
5743 Elm_Object_Select_Mode mode)
5745 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5746 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5748 if (_it->generation < _it->wd->generation) return;
5749 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5751 if (_it->select_mode != mode)
5752 _it->select_mode = mode;
5754 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5756 _it->item->mincalcd = EINA_FALSE;
5757 _it->item->updateme = EINA_TRUE;
5758 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
5759 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5760 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5764 EAPI Elm_Object_Select_Mode
5765 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
5767 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
5768 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5769 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
5770 return _it->select_mode;
5773 /* for gengrid as of now */
5775 _elm_genlist_page_relative_set(Evas_Object *obj,
5779 Evas_Coord pagesize_h;
5780 Evas_Coord pagesize_v;
5782 ELM_CHECK_WIDTYPE(obj, widtype);
5783 Widget_Data *wd = elm_widget_data_get(obj);
5786 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5787 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5791 /* for gengrid as of now */
5793 _elm_genlist_page_relative_get(const Evas_Object *obj,
5797 ELM_CHECK_WIDTYPE(obj, widtype);
5798 Widget_Data *wd = elm_widget_data_get(obj);
5801 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5804 /* for gengrid as of now */
5806 _elm_genlist_page_size_set(Evas_Object *obj,
5807 Evas_Coord h_pagesize,
5808 Evas_Coord v_pagesize)
5813 ELM_CHECK_WIDTYPE(obj, widtype);
5814 Widget_Data *wd = elm_widget_data_get(obj);
5816 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5817 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5821 /* for gengrid as of now */
5823 _elm_genlist_current_page_get(const Evas_Object *obj,
5827 ELM_CHECK_WIDTYPE(obj, widtype);
5828 Widget_Data *wd = elm_widget_data_get(obj);
5830 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5833 /* for gengrid as of now */
5835 _elm_genlist_last_page_get(const Evas_Object *obj,
5839 ELM_CHECK_WIDTYPE(obj, widtype);
5840 Widget_Data *wd = elm_widget_data_get(obj);
5842 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5845 /* for gengrid as of now */
5847 _elm_genlist_page_show(const Evas_Object *obj,
5851 ELM_CHECK_WIDTYPE(obj, widtype);
5852 Widget_Data *wd = elm_widget_data_get(obj);
5854 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5857 /* for gengrid as of now */
5859 _elm_genlist_page_bring_in(const Evas_Object *obj,
5863 ELM_CHECK_WIDTYPE(obj, widtype);
5864 Widget_Data *wd = elm_widget_data_get(obj);
5866 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5870 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5873 Evas_Object *content;
5875 if (!it->realized) return;
5876 if (it->wd->reorder_it == it) return;
5878 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5880 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5883 ecore_timer_del(it->long_timer);
5884 it->long_timer = NULL;
5887 elm_widget_stringlist_free(it->texts);
5889 elm_widget_stringlist_free(it->contents);
5890 it->contents = NULL;
5891 elm_widget_stringlist_free(it->states);
5893 EINA_LIST_FREE(it->content_objs, content)
5894 evas_object_del(content);
5896 it->unrealize_cb(it);
5898 it->realized = EINA_FALSE;
5899 it->want_unrealize = EINA_FALSE;
5900 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5901 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5905 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5907 elm_widget_item_pre_notify_del(it);
5908 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5910 if ((it->relcount > 0) || (it->walking > 0)) return;
5912 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5914 if (it->itc->func.del)
5915 it->itc->func.del((void *)it->base.data, WIDGET(it));
5919 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5921 _elm_genlist_item_del_notserious(it);
5922 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5923 if (it->tooltip.del_cb)
5924 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5925 it->wd->walking -= it->walking;
5928 ecore_timer_del(it->long_timer);
5929 it->long_timer = NULL;
5932 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5936 eina_inlist_sorted_state_free(it->wd->state);
5937 it->wd->state = NULL;
5939 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5940 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5944 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
5945 it->wd->last_selected_item = NULL;
5946 it->wd->item_count--;
5950 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
5952 ELM_CHECK_WIDTYPE(obj, widtype);
5953 Widget_Data *wd = elm_widget_data_get(obj);
5955 wd->tree_effect_enabled = !!enabled;
5959 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
5961 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5962 Widget_Data *wd = elm_widget_data_get(obj);
5963 if (!wd) return EINA_FALSE;
5964 return wd->tree_effect_enabled;
5968 _create_tray_alpha_bg(const Evas_Object *obj)
5970 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5971 Widget_Data *wd = elm_widget_data_get(obj);
5972 if (!wd) return NULL;
5974 Evas_Object *bg = NULL;
5975 Evas_Coord ox, oy, ow, oh;
5977 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5978 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
5979 evas_object_color_set(bg,0,0,0,0);
5980 evas_object_resize(bg , ow, oh);
5981 evas_object_move(bg , ox, oy);
5986 _item_contract_emit(Elm_Gen_Item *it)
5991 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
5992 it->item->tree_effect_finished = EINA_FALSE;
5994 EINA_LIST_FOREACH(it->item->items, l, it2)
5995 if (it2) _item_contract_emit(it2);
5999 _item_tree_effect_before(Elm_Gen_Item *it)
6004 EINA_LIST_FOREACH(it->item->items, l, it2)
6006 if (it2->parent && (it == it2->parent))
6009 it2->item->tree_effect_hideme = EINA_TRUE;
6010 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6011 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6012 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6013 _item_contract_emit(it2);
6016 return ECORE_CALLBACK_CANCEL;
6020 _item_tree_effect(Widget_Data *wd, int y)
6022 Elm_Gen_Item *it = NULL, *expanded_next_it;
6024 expanded_next_it = wd->expanded_next_item;
6026 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6028 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6031 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6032 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6033 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6035 if (!it->item->tree_effect_finished)
6037 edje_object_signal_emit(VIEW(it), "flip_item", "");
6038 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6039 it->item->tree_effect_finished = EINA_TRUE;
6042 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6045 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6047 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6050 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6051 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6053 if (!it->item->tree_effect_finished)
6055 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6056 it->item->tree_effect_finished = EINA_TRUE;
6061 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6067 _item_tree_effect_finish(Widget_Data *wd)
6069 Elm_Gen_Item *it = NULL;
6072 if (wd->tree_effect_animator)
6074 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6075 _item_subitems_clear(wd->expanded_item);
6076 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6078 it->item->tree_effect_finished = EINA_TRUE;
6079 it->item->old_scrl_y = it->item->scrl_y;
6080 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6081 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6084 _item_auto_scroll(wd);
6085 evas_object_lower(wd->alpha_bg);
6086 evas_object_hide(wd->alpha_bg);
6087 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6088 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6090 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6091 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6092 evas_object_smart_changed(wd->pan_smart);
6094 wd->tree_effect_animator = NULL;
6098 _tree_effect_animator_cb(void *data)
6100 Widget_Data *wd = data;
6101 if (!wd) return ECORE_CALLBACK_CANCEL;
6102 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6103 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6105 double effect_duration = 0.3, t;
6106 int y = 0, dy = 0, dh = 0;
6107 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6110 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6111 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6112 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6113 if (t > effect_duration) end = EINA_TRUE;
6115 // Below while statement is needed, when the genlist is resized.
6116 it2 = wd->expanded_item;
6119 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6120 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6121 cvx, cvy, cvw, cvh));
6122 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6125 if (wd->expanded_next_item)
6127 expanded_next_it = wd->expanded_next_item;
6130 EINA_LIST_FOREACH(wd->move_items, l, it)
6132 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6134 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6135 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6136 expanded_next_it->item->scrl_y = cvy + cvh;
6138 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6139 cvy + cvh : expanded_next_it->item->scrl_y) -
6140 expanded_next_it->item->old_scrl_y;
6142 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6144 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6145 expanded_next_it->item->old_scrl_y = cvy + cvh;
6147 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6149 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6151 expanded_next_it->item->old_scrl_y = cvy + cvh;
6155 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6156 expanded_next_it->item->old_scrl_y;
6160 if (t <= effect_duration)
6162 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6172 _item_realize(it, in, 0);
6176 if (it != expanded_next_it)
6178 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6182 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6183 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6186 _item_tree_effect(wd, y);
6190 int expanded_item_num = 0;
6193 if (wd->expanded_item)
6194 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6199 expanded_item_num++;
6200 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6206 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6207 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6209 if (!it->item->tree_effect_finished)
6211 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6213 edje_object_signal_emit(VIEW(it), "flip_item", "");
6214 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6215 it->item->tree_effect_finished = EINA_TRUE;
6219 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6225 _item_tree_effect_finish(wd);
6226 return ECORE_CALLBACK_CANCEL;
6228 return ECORE_CALLBACK_RENEW;