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);
860 evas_event_freeze(evas_object_evas_get(obj));
861 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
862 if (it->wd->show_item == it) it->wd->show_item = NULL;
863 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
864 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
865 if (it->item->block) _item_block_del(it);
866 if (it->item->queued)
867 it->wd->queue = eina_list_remove(it->wd->queue, it);
868 if (it->wd->anchor_item == it)
870 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
871 if (!it->wd->anchor_item)
872 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
874 if (it->wd->expanded_item == it) it->wd->expanded_item = NULL;
875 if (it->wd->expanded_next_item == it) it->wd->expanded_next_item = NULL;
877 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
878 if (it->item->swipe_timer)
880 ecore_timer_del(it->item->swipe_timer);
881 it->item->swipe_timer = NULL;
883 _elm_genlist_item_del_serious(it);
884 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
885 evas_event_thaw(evas_object_evas_get(obj));
886 evas_event_thaw_eval(evas_object_evas_get(obj));
890 _clear_cb(Widget_Data *wd)
892 wd->anchor_item = NULL;
893 if (wd->queue_idle_enterer)
895 ecore_idle_enterer_del(wd->queue_idle_enterer);
896 wd->queue_idle_enterer = NULL;
898 if (wd->must_recalc_idler)
900 ecore_idler_del(wd->must_recalc_idler);
901 wd->must_recalc_idler = NULL;
903 if (wd->queue) wd->queue = eina_list_free(wd->queue);
904 if (wd->reorder_move_animator)
906 ecore_animator_del(wd->reorder_move_animator);
907 wd->reorder_move_animator = NULL;
909 wd->show_item = NULL;
910 wd->reorder_old_pan_y = 0;
914 _item_unselect(Elm_Gen_Item *it)
916 if ((it->generation < it->wd->generation) || (!it->selected)) return;
917 it->selected = EINA_FALSE;
918 it->wd->selected = eina_list_remove(it->wd->selected, it);
919 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
923 _mouse_move(void *data,
924 Evas *evas __UNUSED__,
928 Elm_Gen_Item *it = data;
929 Evas_Event_Mouse_Move *ev = event_info;
930 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
931 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
933 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
935 if (!it->wd->on_hold)
937 it->wd->on_hold = EINA_TRUE;
938 if ((!it->wd->wasselected) && (!it->flipped))
940 _item_unhighlight(it);
945 if (it->wd->multitouched)
947 it->wd->cur_x = ev->cur.canvas.x;
948 it->wd->cur_y = ev->cur.canvas.y;
951 if ((it->dragging) && (it->down))
953 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
956 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
957 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
958 if (abs((it->wd->history[it->wd->movements].x -
959 it->wd->history[0].x)) > 40)
960 it->wd->swipe = EINA_TRUE;
966 ecore_timer_del(it->long_timer);
967 it->long_timer = NULL;
969 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
972 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
976 ecore_timer_del(it->long_timer);
977 it->long_timer = NULL;
979 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
981 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
982 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
984 if (!it->wd->reorder_start_y)
985 it->wd->reorder_start_y = it->item->block->y + it->y;
989 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
990 y_pos = oy + oh - it->wd->reorder_it->item->h;
994 if (it->deco_all_view)
995 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
997 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
999 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1000 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1004 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1005 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1006 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1007 x = ev->cur.canvas.x - x;
1008 y = ev->cur.canvas.y - y;
1011 if (adx < 0) adx = -dx;
1014 if (ady < 0) ady = -dy;
1017 if ((adx > minw) || (ady > minh))
1019 it->dragging = EINA_TRUE;
1022 ecore_timer_del(it->long_timer);
1023 it->long_timer = NULL;
1025 if (!it->wd->wasselected)
1027 _item_unhighlight(it);
1033 evas_object_smart_callback_call(WIDGET(it),
1034 SIG_DRAG_START_UP, it);
1038 evas_object_smart_callback_call(WIDGET(it),
1039 SIG_DRAG_START_LEFT, it);
1041 evas_object_smart_callback_call(WIDGET(it),
1042 SIG_DRAG_START_RIGHT, it);
1048 evas_object_smart_callback_call(WIDGET(it),
1049 SIG_DRAG_START_DOWN, it);
1053 evas_object_smart_callback_call(WIDGET(it),
1054 SIG_DRAG_START_LEFT, it);
1056 evas_object_smart_callback_call(WIDGET(it),
1057 SIG_DRAG_START_RIGHT, it);
1064 _long_press(void *data)
1066 Elm_Gen_Item *it = data, *it_tmp;
1067 Eina_List *list, *l;
1069 it->long_timer = NULL;
1070 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1071 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1072 return ECORE_CALLBACK_CANCEL;
1073 it->wd->longpressed = EINA_TRUE;
1074 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1075 if ((it->wd->reorder_mode) && (!it->group))
1077 it->wd->reorder_it = it;
1078 it->wd->reorder_start_y = 0;
1079 if (it->deco_all_view)
1080 evas_object_raise(it->deco_all_view);
1082 evas_object_raise(VIEW(it));
1084 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1085 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1087 list = elm_genlist_realized_items_get(it->wd->obj);
1088 EINA_LIST_FOREACH(list, l, it_tmp)
1090 if (it != it_tmp) _item_unselect(it_tmp);
1092 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1094 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1095 return ECORE_CALLBACK_RENEW;
1098 if (!it->wd->decorate_all_mode)
1099 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1101 return ECORE_CALLBACK_CANCEL;
1105 _swipe(Elm_Gen_Item *it)
1110 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1111 elm_widget_item_disabled_get(it)) return;
1112 it->wd->swipe = EINA_FALSE;
1113 for (i = 0; i < it->wd->movements; i++)
1115 sum += it->wd->history[i].x;
1116 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1119 sum /= it->wd->movements;
1120 if (abs(sum - it->wd->history[0].x) <= 10) return;
1121 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1125 _swipe_cancel(void *data)
1127 Elm_Gen_Item *it = data;
1129 if (!it) return ECORE_CALLBACK_CANCEL;
1130 it->wd->swipe = EINA_FALSE;
1131 it->wd->movements = 0;
1132 return ECORE_CALLBACK_RENEW;
1136 _multi_cancel(void *data)
1138 Widget_Data *wd = data;
1140 if (!wd) return ECORE_CALLBACK_CANCEL;
1141 wd->multi_timeout = EINA_TRUE;
1142 return ECORE_CALLBACK_RENEW;
1146 _multi_touch_gesture_eval(void *data)
1148 Elm_Gen_Item *it = data;
1150 it->wd->multitouched = EINA_FALSE;
1151 if (it->wd->multi_timer)
1153 ecore_timer_del(it->wd->multi_timer);
1154 it->wd->multi_timer = NULL;
1156 if (it->wd->multi_timeout)
1158 it->wd->multi_timeout = EINA_FALSE;
1162 Evas_Coord minw = 0, minh = 0;
1163 Evas_Coord off_x, off_y, off_mx, off_my;
1165 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1166 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1167 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1168 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1169 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1171 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1173 if ((off_x + off_mx) > (off_y + off_my))
1175 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1176 evas_object_smart_callback_call(WIDGET(it),
1177 SIG_MULTI_SWIPE_RIGHT, it);
1178 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1179 evas_object_smart_callback_call(WIDGET(it),
1180 SIG_MULTI_SWIPE_LEFT, it);
1181 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1182 evas_object_smart_callback_call(WIDGET(it),
1183 SIG_MULTI_PINCH_OUT, it);
1185 evas_object_smart_callback_call(WIDGET(it),
1186 SIG_MULTI_PINCH_IN, it);
1190 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1191 evas_object_smart_callback_call(WIDGET(it),
1192 SIG_MULTI_SWIPE_DOWN, it);
1193 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1194 evas_object_smart_callback_call(WIDGET(it),
1195 SIG_MULTI_SWIPE_UP, it);
1196 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1197 evas_object_smart_callback_call(WIDGET(it),
1198 SIG_MULTI_PINCH_OUT, it);
1200 evas_object_smart_callback_call(WIDGET(it),
1201 SIG_MULTI_PINCH_IN, it);
1204 it->wd->multi_timeout = EINA_FALSE;
1208 _multi_down(void *data,
1209 Evas *evas __UNUSED__,
1210 Evas_Object *obj __UNUSED__,
1213 Elm_Gen_Item *it = data;
1214 Evas_Event_Multi_Down *ev = event_info;
1216 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1217 it->wd->multi_device = ev->device;
1218 it->wd->multi_down = EINA_TRUE;
1219 it->wd->multitouched = EINA_TRUE;
1220 it->wd->prev_mx = ev->canvas.x;
1221 it->wd->prev_my = ev->canvas.y;
1222 if (!it->wd->wasselected)
1224 _item_unhighlight(it);
1227 it->wd->wasselected = EINA_FALSE;
1228 it->wd->longpressed = EINA_FALSE;
1231 ecore_timer_del(it->long_timer);
1232 it->long_timer = NULL;
1236 it->dragging = EINA_FALSE;
1237 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1239 if (it->item->swipe_timer)
1241 ecore_timer_del(it->item->swipe_timer);
1242 it->item->swipe_timer = NULL;
1244 if (it->wd->on_hold)
1246 it->wd->swipe = EINA_FALSE;
1247 it->wd->movements = 0;
1248 it->wd->on_hold = EINA_FALSE;
1253 _multi_up(void *data,
1254 Evas *evas __UNUSED__,
1255 Evas_Object *obj __UNUSED__,
1258 Elm_Gen_Item *it = data;
1259 Evas_Event_Multi_Up *ev = event_info;
1261 if (it->wd->multi_device != ev->device) return;
1262 it->wd->multi_device = 0;
1263 it->wd->multi_down = EINA_FALSE;
1264 if (it->wd->mouse_down) return;
1265 _multi_touch_gesture_eval(data);
1269 _multi_move(void *data,
1270 Evas *evas __UNUSED__,
1271 Evas_Object *obj __UNUSED__,
1274 Elm_Gen_Item *it = data;
1275 Evas_Event_Multi_Move *ev = event_info;
1277 if (it->wd->multi_device != ev->device) return;
1278 it->wd->cur_mx = ev->cur.canvas.x;
1279 it->wd->cur_my = ev->cur.canvas.y;
1283 _mouse_down(void *data,
1284 Evas *evas __UNUSED__,
1288 Elm_Gen_Item *it = data;
1289 Evas_Event_Mouse_Down *ev = event_info;
1292 if (ev->button != 1) return;
1293 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1295 it->wd->on_hold = EINA_TRUE;
1298 it->down = EINA_TRUE;
1299 it->dragging = EINA_FALSE;
1300 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1301 it->dx = ev->canvas.x - x;
1302 it->dy = ev->canvas.y - y;
1303 it->wd->mouse_down = EINA_TRUE;
1304 if (!it->wd->multitouched)
1306 it->wd->prev_x = ev->canvas.x;
1307 it->wd->prev_y = ev->canvas.y;
1308 it->wd->multi_timeout = EINA_FALSE;
1309 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1310 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1312 it->wd->longpressed = EINA_FALSE;
1313 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1314 else it->wd->on_hold = EINA_FALSE;
1315 if (it->wd->on_hold) return;
1316 it->wd->wasselected = it->selected;
1317 _item_highlight(it);
1318 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1319 if ((!elm_widget_item_disabled_get(it)) &&
1320 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1322 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1323 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1325 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1326 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1327 if (it->long_timer) ecore_timer_del(it->long_timer);
1329 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1332 it->long_timer = NULL;
1333 it->wd->swipe = EINA_FALSE;
1334 it->wd->movements = 0;
1338 _mouse_up(void *data,
1339 Evas *evas __UNUSED__,
1340 Evas_Object *obj __UNUSED__,
1343 Elm_Gen_Item *it = data;
1344 Evas_Event_Mouse_Up *ev = event_info;
1345 Eina_Bool dragged = EINA_FALSE;
1347 if (ev->button != 1) return;
1348 it->down = EINA_FALSE;
1349 it->wd->mouse_down = EINA_FALSE;
1350 if (it->wd->multitouched)
1352 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1353 if (it->wd->multi_down) return;
1354 _multi_touch_gesture_eval(data);
1357 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1358 else it->wd->on_hold = EINA_FALSE;
1361 ecore_timer_del(it->long_timer);
1362 it->long_timer = NULL;
1366 it->dragging = EINA_FALSE;
1367 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1370 if (it->item->swipe_timer)
1372 ecore_timer_del(it->item->swipe_timer);
1373 it->item->swipe_timer = NULL;
1375 if (it->wd->multi_timer)
1377 ecore_timer_del(it->wd->multi_timer);
1378 it->wd->multi_timer = NULL;
1379 it->wd->multi_timeout = EINA_FALSE;
1381 if (it->wd->on_hold)
1383 if (it->wd->swipe) _swipe(data);
1384 it->wd->longpressed = EINA_FALSE;
1385 it->wd->on_hold = EINA_FALSE;
1388 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1390 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1392 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1394 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1395 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1397 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1398 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1402 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1403 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1405 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1406 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1407 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1408 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1410 if (it->wd->longpressed)
1412 it->wd->longpressed = EINA_FALSE;
1413 if ((!it->wd->wasselected) && (!it->flipped))
1415 _item_unhighlight(it);
1418 it->wd->wasselected = EINA_FALSE;
1423 if (it->want_unrealize)
1425 _elm_genlist_item_unrealize(it, EINA_FALSE);
1426 if (it->item->block->want_unrealize)
1427 _item_block_unrealize(it->item->block);
1430 if (elm_widget_item_disabled_get(it) || (dragged) ||
1431 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1433 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1438 _item_highlight(it);
1443 _item_unhighlight(it);
1451 Widget_Data *wd = it->wd;
1454 while (wd->selected)
1456 _item_unhighlight(wd->selected->data);
1457 _item_unselect(wd->selected->data);
1463 const Eina_List *l, *l_next;
1466 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1469 _item_unhighlight(it2);
1470 _item_unselect(it2);
1472 //_item_highlight(it);
1475 _item_highlight(it);
1481 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1483 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1485 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1487 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1489 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1491 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1493 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1498 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1500 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1502 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1504 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1506 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1508 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1510 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1515 _signal_expand_toggle(void *data,
1516 Evas_Object *obj __UNUSED__,
1517 const char *emission __UNUSED__,
1518 const char *source __UNUSED__)
1520 Elm_Gen_Item *it = data;
1522 if (it->item->expanded)
1523 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1525 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1529 _signal_expand(void *data,
1530 Evas_Object *obj __UNUSED__,
1531 const char *emission __UNUSED__,
1532 const char *source __UNUSED__)
1534 Elm_Gen_Item *it = data;
1536 if (!it->item->expanded)
1537 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1541 _signal_contract(void *data,
1542 Evas_Object *obj __UNUSED__,
1543 const char *emission __UNUSED__,
1544 const char *source __UNUSED__)
1546 Elm_Gen_Item *it = data;
1548 if (it->item->expanded)
1549 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1553 _scr_hold_timer_cb(void *data)
1555 if (!data) return ECORE_CALLBACK_CANCEL;
1556 Widget_Data *wd = data;
1557 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1558 wd->scr_hold_timer = NULL;
1559 return ECORE_CALLBACK_CANCEL;
1563 _decorate_item_finished_signal_cb(void *data,
1565 const char *emission __UNUSED__,
1566 const char *source __UNUSED__)
1570 Elm_Gen_Item *it = data;
1571 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1573 Evas *te = evas_object_evas_get(obj);
1575 evas_event_freeze(te);
1576 it->item->nocache_once = EINA_FALSE;
1577 _decorate_item_unrealize(it);
1578 if (it->item->group_item)
1579 evas_object_raise(it->item->VIEW(group_item));
1580 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1581 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1582 evas_event_thaw(te);
1583 evas_event_thaw_eval(te);
1587 _item_cache_clean(Widget_Data *wd)
1589 evas_event_freeze(evas_object_evas_get(wd->obj));
1590 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1594 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1595 wd->item_cache = eina_inlist_remove(wd->item_cache,
1596 wd->item_cache->last);
1597 wd->item_cache_count--;
1598 if (itc->spacer) evas_object_del(itc->spacer);
1599 if (itc->base_view) evas_object_del(itc->base_view);
1600 eina_stringshare_del(itc->item_style);
1603 evas_event_thaw(evas_object_evas_get(wd->obj));
1604 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1608 _item_cache_zero(Widget_Data *wd)
1610 int pmax = wd->item_cache_max;
1611 wd->item_cache_max = 0;
1612 _item_cache_clean(wd);
1613 wd->item_cache_max = pmax;
1617 _item_cache_add(Elm_Gen_Item *it)
1621 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1622 if (it->wd->item_cache_max <= 0)
1624 evas_object_del(VIEW(it));
1628 evas_object_del(it->spacer);
1631 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1632 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1636 it->wd->item_cache_count++;
1637 itc = calloc(1, sizeof(Item_Cache));
1640 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1641 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1644 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1645 EINA_INLIST_GET(itc));
1646 itc->spacer = it->spacer;
1648 itc->base_view = VIEW(it);
1650 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1651 evas_object_hide(itc->base_view);
1652 evas_object_move(itc->base_view, -9999, -9999);
1653 itc->item_style = eina_stringshare_add(it->itc->item_style);
1654 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1655 itc->selected = it->selected;
1656 itc->disabled = elm_widget_item_disabled_get(it);
1657 itc->expanded = it->item->expanded;
1660 ecore_timer_del(it->long_timer);
1661 it->long_timer = NULL;
1663 if (it->item->swipe_timer)
1665 ecore_timer_del(it->item->swipe_timer);
1666 it->item->swipe_timer = NULL;
1668 // FIXME: other callbacks?
1669 edje_object_signal_callback_del_full(itc->base_view,
1670 "elm,action,expand,toggle",
1671 "elm", _signal_expand_toggle, it);
1672 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1674 _signal_expand, it);
1675 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1676 "elm", _signal_contract, it);
1677 _item_mouse_callbacks_del(it, itc->base_view);
1678 _item_cache_clean(it->wd);
1679 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1680 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1684 _item_cache_find(Elm_Gen_Item *it)
1689 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1690 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1692 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1694 if ((itc->tree == tree) &&
1695 (((!it->itc->item_style) && (!itc->item_style)) ||
1696 (it->itc->item_style && itc->item_style &&
1697 (!strcmp(it->itc->item_style, itc->item_style)))))
1699 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1700 EINA_INLIST_GET(itc));
1701 it->wd->item_cache_count--;
1709 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1711 if (it->position_update || it->item->block->position_update)
1713 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1714 it->position_update = EINA_FALSE;
1719 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1721 if (!it->item->nostacking)
1723 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1725 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1726 else evas_object_lower(VIEW(it));
1730 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1731 else evas_object_raise(VIEW(it));
1735 if (it->item->order_num_in & 0x1)
1737 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1738 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1742 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1743 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1748 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1752 if (it->selected != itc->selected)
1756 edje_object_signal_emit(VIEW(it),
1757 "elm,state,selected", "elm");
1759 if (it->deco_all_view)
1760 edje_object_signal_emit(it->deco_all_view,
1761 "elm,state,selected", "elm");
1764 if (elm_widget_item_disabled_get(it) != itc->disabled)
1766 if (elm_widget_item_disabled_get(it))
1767 edje_object_signal_emit(VIEW(it),
1768 "elm,state,disabled", "elm");
1769 if (it->deco_all_view)
1770 edje_object_signal_emit(it->deco_all_view,
1771 "elm,state,disabled", "elm");
1773 if (it->item->expanded != itc->expanded)
1775 if (it->item->expanded)
1776 edje_object_signal_emit(VIEW(it),
1777 "elm,state,expanded", "elm");
1778 if (it->deco_all_view)
1779 edje_object_signal_emit(it->deco_all_view,
1780 "elm,state,expanded", "elm");
1787 edje_object_signal_emit(VIEW(it),
1788 "elm,state,selected", "elm");
1789 if (it->deco_all_view)
1790 edje_object_signal_emit(it->deco_all_view,
1791 "elm,state,selected", "elm");
1794 if (elm_widget_item_disabled_get(it))
1796 edje_object_signal_emit(VIEW(it),
1797 "elm,state,disabled", "elm");
1798 if (it->deco_all_view)
1799 edje_object_signal_emit(it->deco_all_view,
1800 "elm,state,disabled", "elm");
1802 if (it->item->expanded)
1804 edje_object_signal_emit(VIEW(it),
1805 "elm,state,expanded", "elm");
1806 if (it->deco_all_view)
1807 edje_object_signal_emit(it->deco_all_view,
1808 "elm,state,expanded", "elm");
1814 _item_mode_content_realize(Elm_Gen_Item *it,
1815 Evas_Object *target,
1818 Eina_List **contents_list)
1820 Eina_List *res = *contents_list;
1822 if (it->itc->func.content_get)
1827 EINA_LIST_FOREACH(*source, l, key)
1829 if (parts && fnmatch(parts, key, FNM_PERIOD))
1832 Evas_Object *ic = it->itc->func.content_get
1833 ((void *)it->base.data, WIDGET(it), l->data);
1837 res = eina_list_append(res, ic);
1838 edje_object_part_swallow(target, key, ic);
1839 evas_object_show(ic);
1840 elm_widget_sub_object_add(WIDGET(it), ic);
1841 if (it->item->deco_it_view || it->wd->decorate_all_mode)
1843 if (elm_widget_item_disabled_get(it))
1844 elm_widget_disabled_set(ic, EINA_TRUE);
1854 _item_mode_content_unrealize(Elm_Gen_Item *it,
1855 Evas_Object *target,
1858 Eina_List **contents_list)
1860 Eina_List *res = *contents_list;
1862 if (it->itc->func.content_get)
1866 Evas_Object *ic = NULL;
1868 EINA_LIST_FOREACH(*source, l, key)
1870 if (parts && fnmatch(parts, key, FNM_PERIOD))
1873 ic = edje_object_part_swallow_get(target, key);
1876 res = eina_list_remove(res, ic);
1877 edje_object_part_unswallow(target, ic);
1878 evas_object_del(ic);
1887 _item_cache_free(Item_Cache *itc)
1889 if (itc->spacer) evas_object_del(itc->spacer);
1890 if (itc->base_view) evas_object_del(itc->base_view);
1891 eina_stringshare_del(itc->item_style);
1896 _item_text_realize(Elm_Gen_Item *it,
1897 Evas_Object *target,
1901 if (it->itc->func.text_get)
1907 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1908 EINA_LIST_FOREACH(*source, l, key)
1910 if (parts && fnmatch(parts, key, FNM_PERIOD))
1913 char *s = it->itc->func.text_get
1914 ((void *)it->base.data, WIDGET(it), key);
1918 edje_object_part_text_set(target, key, s);
1923 edje_object_part_text_set(target, key, "");
1930 _item_content_unrealize(Elm_Gen_Item *it,
1931 Evas_Object *target,
1935 Eina_List *res = it->content_objs;
1937 if (it->itc->func.content_get)
1941 Evas_Object *ic = NULL;
1943 EINA_LIST_FOREACH(*source, l, key)
1945 if (parts && fnmatch(parts, key, FNM_PERIOD))
1948 ic = edje_object_part_swallow_get(target, key);
1951 res = eina_list_remove(res, ic);
1952 edje_object_part_unswallow(target, ic);
1953 evas_object_del(ic);
1962 _item_content_realize(Elm_Gen_Item *it,
1963 Evas_Object *target,
1967 Eina_List *res = it->content_objs;
1969 if (it->itc->func.content_get)
1973 Evas_Object *ic = NULL;
1976 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1978 EINA_LIST_FOREACH(*source, l, key)
1980 if (parts && fnmatch(parts, key, FNM_PERIOD))
1983 if (it->itc->func.content_get)
1984 ic = it->itc->func.content_get
1985 ((void *)it->base.data, WIDGET(it), key);
1988 res = eina_list_append(res, ic);
1989 edje_object_part_swallow(target, key, ic);
1990 evas_object_show(ic);
1991 elm_widget_sub_object_add(WIDGET(it), ic);
1992 if (elm_widget_item_disabled_get(it))
1993 elm_widget_disabled_set(ic, EINA_TRUE);
2002 _item_state_realize(Elm_Gen_Item *it,
2003 Evas_Object *target,
2007 if (it->itc->func.state_get)
2014 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2015 EINA_LIST_FOREACH(*source, l, key)
2017 if (parts && fnmatch(parts, key, FNM_PERIOD))
2020 Eina_Bool on = it->itc->func.state_get
2021 ((void *)it->base.data, WIDGET(it), key);
2025 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2026 edje_object_signal_emit(target, buf, "elm");
2030 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2031 edje_object_signal_emit(target, buf, "elm");
2038 _item_realize(Elm_Gen_Item *it,
2042 const char *treesize;
2045 Item_Cache *itc = NULL;
2047 if (it->generation < it->wd->generation) return;
2048 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2051 if (it->item->order_num_in != in)
2053 it->item->order_num_in = in;
2054 _elm_genlist_item_odd_even_update(it);
2055 _elm_genlist_item_state_update(it, NULL);
2056 _elm_genlist_item_index_update(it);
2058 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2059 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2062 it->item->order_num_in = in;
2064 if (it->item->nocache_once)
2065 it->item->nocache_once = EINA_FALSE;
2066 else if (!it->item->nocache)
2067 itc = _item_cache_find(it);
2068 if (itc && (!it->wd->tree_effect_enabled))
2070 VIEW(it) = itc->base_view;
2071 itc->base_view = NULL;
2072 it->spacer = itc->spacer;
2077 const char *stacking_even;
2078 const char *stacking;
2080 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2081 edje_object_scale_set(VIEW(it),
2082 elm_widget_scale_get(WIDGET(it)) *
2083 _elm_config->scale);
2084 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2085 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2087 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2088 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2090 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2092 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2093 elm_widget_style_get(WIDGET(it)));
2095 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2096 if (!stacking_even) stacking_even = "above";
2097 it->item->stacking_even = !!strcmp("above", stacking_even);
2099 stacking = edje_object_data_get(VIEW(it), "stacking");
2100 if (!stacking) stacking = "yes";
2101 it->item->nostacking = !!strcmp("yes", stacking);
2103 edje_object_mirrored_set(VIEW(it),
2104 elm_widget_mirrored_get(WIDGET(it)));
2107 _elm_genlist_item_odd_even_update(it);
2109 treesize = edje_object_data_get(VIEW(it), "treesize");
2110 if (treesize) tsize = atoi(treesize);
2111 if (!it->spacer && treesize)
2114 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2115 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2116 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2120 evas_object_size_hint_min_set(it->spacer,
2121 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2122 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2126 edje_object_signal_callback_add(VIEW(it),
2127 "elm,action,expand,toggle",
2128 "elm", _signal_expand_toggle, it);
2129 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2130 "elm", _signal_expand, it);
2131 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2132 "elm", _signal_contract, it);
2133 _item_mouse_callbacks_add(it, VIEW(it));
2135 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2136 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2137 _decorate_all_item_realize(it, EINA_FALSE);
2139 _elm_genlist_item_state_update(it, itc);
2140 _elm_genlist_item_index_update(it);
2143 if ((calc) && (it->wd->homogeneous) &&
2144 ((it->wd->item_width) ||
2145 ((it->wd->item_width) && (it->wd->group_item_width))))
2147 /* homogenous genlist shortcut */
2148 if (!it->item->mincalcd)
2152 it->item->w = it->item->minw = it->wd->group_item_width;
2153 it->item->h = it->item->minh = it->wd->group_item_height;
2157 it->item->w = it->item->minw = it->wd->item_width;
2158 it->item->h = it->item->minh = it->wd->item_height;
2160 it->item->mincalcd = EINA_TRUE;
2165 /* FIXME: If you see that assert, please notify us and we
2166 will clean our mess */
2167 assert(eina_list_count(it->content_objs) == 0);
2169 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2170 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2171 _item_state_realize(it, VIEW(it), &it->states, NULL);
2174 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2175 if (!(it->item->flip_contents))
2176 it->item->flip_contents =
2177 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2178 it->item->flip_content_objs =
2179 _item_mode_content_realize(it, VIEW(it),
2180 &it->item->flip_contents, NULL,
2181 &it->item->flip_content_objs);
2184 if (!it->item->mincalcd)
2186 Evas_Coord mw = -1, mh = -1;
2188 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2189 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2190 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2191 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2193 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2194 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2195 it->item->w = it->item->minw = mw;
2196 it->item->h = it->item->minh = mh;
2197 it->item->mincalcd = EINA_TRUE;
2199 if ((!it->wd->group_item_width) && (it->group))
2201 it->wd->group_item_width = mw;
2202 it->wd->group_item_height = mh;
2204 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2206 it->wd->item_width = mw;
2207 it->wd->item_height = mh;
2210 if (!calc) evas_object_show(VIEW(it));
2213 if (it->tooltip.content_cb)
2215 elm_widget_item_tooltip_content_cb_set(it,
2216 it->tooltip.content_cb,
2217 it->tooltip.data, NULL);
2218 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2219 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2222 if (it->mouse_cursor)
2223 elm_widget_item_cursor_set(it, it->mouse_cursor);
2225 it->realized = EINA_TRUE;
2226 it->want_unrealize = EINA_FALSE;
2228 if (itc) _item_cache_free(itc);
2229 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2230 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2233 if (it->item->tree_effect_hideme)
2235 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2236 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2237 it->item->tree_effect_hideme = EINA_FALSE;
2239 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2242 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2244 if (it->itc->decorate_all_item_style)
2246 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2247 edje_object_message_signal_process(it->deco_all_view);
2250 edje_object_message_signal_process(VIEW(it));
2254 _item_unrealize_cb(Elm_Gen_Item *it)
2256 if (it->item->nocache_once || it->item->nocache)
2258 evas_object_del(VIEW(it));
2262 evas_object_del(it->spacer);
2268 edje_object_mirrored_set(VIEW(it),
2269 elm_widget_mirrored_get(WIDGET(it)));
2270 edje_object_scale_set(VIEW(it),
2271 elm_widget_scale_get(WIDGET(it))
2272 * _elm_config->scale);
2273 _item_cache_add(it);
2276 _decorate_item_unrealize(it);
2278 it->realized = EINA_FALSE;
2279 it->want_unrealize = EINA_FALSE;
2280 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2284 _item_block_recalc(Item_Block *itb,
2290 Evas_Coord minw = 0, minh = 0;
2291 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2294 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2296 EINA_LIST_FOREACH(itb->items, l, it)
2298 if (it->generation < it->wd->generation) continue;
2299 showme |= it->item->showme;
2304 if (!it->item->mincalcd) changed = EINA_TRUE;
2307 _item_realize(it, in, EINA_TRUE);
2308 _elm_genlist_item_unrealize(it, EINA_TRUE);
2313 _item_realize(it, in, EINA_TRUE);
2314 _elm_genlist_item_unrealize(it, EINA_TRUE);
2319 if (!it->item->mincalcd) changed = EINA_TRUE;
2320 _item_realize(it, in, EINA_FALSE);
2322 minh += it->item->minh;
2323 if (minw < it->item->minw) minw = it->item->minw;
2329 if (changed) itb->wd->pan_changed = changed;
2332 itb->changed = EINA_FALSE;
2333 itb->position_update = EINA_FALSE;
2334 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2335 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2340 _item_block_realize(Item_Block *itb)
2342 if (itb->realized) return;
2343 itb->realized = EINA_TRUE;
2344 itb->want_unrealize = EINA_FALSE;
2348 _item_block_unrealize(Item_Block *itb)
2352 Eina_Bool dragging = EINA_FALSE;
2354 if (!itb->realized) return;
2355 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2356 EINA_LIST_FOREACH(itb->items, l, it)
2358 if (itb->must_recalc || !it->group)
2362 dragging = EINA_TRUE;
2363 it->want_unrealize = EINA_TRUE;
2366 _elm_genlist_item_unrealize(it, EINA_FALSE);
2371 itb->realized = EINA_FALSE;
2372 itb->want_unrealize = EINA_TRUE;
2375 itb->want_unrealize = EINA_FALSE;
2376 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2377 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2381 _get_space_for_reorder_item(Elm_Gen_Item *it)
2383 Evas_Coord rox, roy, row, roh, oy, oh;
2384 Eina_Bool top = EINA_FALSE;
2385 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2386 if (!reorder_it) return 0;
2388 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2389 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2391 if ((it->wd->reorder_start_y < it->item->block->y) &&
2392 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2394 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2395 if (it->item->block->count == 1)
2396 it->wd->reorder_rel = it;
2398 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2399 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2401 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2404 it->item->block->reorder_offset = 0;
2406 it->item->scrl_y += it->item->block->reorder_offset;
2408 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2409 rox, roy + (roh / 2), row, 1));
2412 it->wd->reorder_rel = it;
2413 it->item->scrl_y += it->wd->reorder_it->item->h;
2414 return it->wd->reorder_it->item->h;
2421 _reorder_move_animator_cb(void *data)
2423 Elm_Gen_Item *it = data;
2424 Eina_Bool down = EINA_FALSE;
2426 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2428 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2430 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2433 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2434 if (diff > it->item->h) y = diff / 2;
2436 if (it->item->old_scrl_y < it->item->scrl_y)
2438 it->item->old_scrl_y += y;
2441 else if (it->item->old_scrl_y > it->item->scrl_y)
2443 it->item->old_scrl_y -= y;
2447 if (it->deco_all_view)
2448 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2450 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2451 _group_items_recalc(it->wd);
2453 if ((it->wd->reorder_pan_move) ||
2454 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2455 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2457 it->item->old_scrl_y = it->item->scrl_y;
2458 it->item->move_effect_enabled = EINA_FALSE;
2459 it->wd->reorder_move_animator = NULL;
2460 return ECORE_CALLBACK_CANCEL;
2462 return ECORE_CALLBACK_RENEW;
2466 _item_position(Elm_Gen_Item *it,
2474 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2475 evas_object_resize(view, it->item->w, it->item->h);
2476 evas_object_move(view, it_x, it_y);
2477 evas_object_show(view);
2478 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2479 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2483 _item_block_position(Item_Block *itb,
2489 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2490 Eina_Bool vis = EINA_FALSE;
2492 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2493 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2494 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2496 EINA_LIST_FOREACH(itb->items, l, it)
2498 if (it->generation < it->wd->generation) continue;
2499 else if (it->wd->reorder_it == it) continue;
2502 it->item->w = itb->w;
2503 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2504 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2506 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2507 cvx, cvy, cvw, cvh));
2510 if ((itb->realized) && (!it->realized))
2512 if (vis) _item_realize(it, in, EINA_FALSE);
2516 if (vis || it->dragging)
2518 if (it->wd->reorder_mode)
2519 y += _get_space_for_reorder_item(it);
2520 git = it->item->group_item;
2523 if (git->item->scrl_y < oy)
2524 git->item->scrl_y = oy;
2525 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2526 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2527 git->item->want_realize = EINA_TRUE;
2529 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2531 if (!it->item->move_effect_enabled)
2533 it->item->move_effect_enabled = EINA_TRUE;
2534 it->wd->reorder_move_animator =
2536 _reorder_move_animator_cb, it);
2539 if (!it->item->move_effect_enabled)
2541 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2542 _decorate_all_item_position(it, it->item->scrl_x,
2546 if (!it->wd->tree_effect_enabled ||
2547 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2548 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2549 (it->item->old_scrl_y == it->item->scrl_y)))
2551 if (it->item->deco_it_view)
2552 _item_position(it, it->item->deco_it_view,
2556 _item_position(it, VIEW(it), it->item->scrl_x,
2560 it->item->old_scrl_y = it->item->scrl_y;
2565 if (!it->wd->tree_effect_animator)
2566 _elm_genlist_item_unrealize(it, EINA_FALSE);
2573 if (vis) it->item->want_realize = EINA_TRUE;
2577 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2578 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2582 _group_items_recalc(void *data)
2584 Widget_Data *wd = data;
2588 evas_event_freeze(evas_object_evas_get(wd->obj));
2589 EINA_LIST_FOREACH(wd->group_items, l, git)
2591 if (git->item->want_realize)
2594 _item_realize(git, 0, EINA_FALSE);
2595 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2596 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2597 evas_object_show(VIEW(git));
2598 evas_object_raise(VIEW(git));
2600 else if (!git->item->want_realize && git->realized)
2603 _elm_genlist_item_unrealize(git, EINA_FALSE);
2606 evas_event_thaw(evas_object_evas_get(wd->obj));
2607 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2611 _must_recalc_idler(void *data)
2613 Widget_Data *wd = data;
2614 if (wd->calc_job) ecore_job_del(wd->calc_job);
2615 wd->calc_job = ecore_job_add(_calc_job, wd);
2616 wd->must_recalc_idler = NULL;
2617 return ECORE_CALLBACK_CANCEL;
2621 _scroll_item(Widget_Data *wd)
2623 Elm_Gen_Item *it = NULL;
2624 Evas_Coord gith = 0;
2625 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2626 if (!wd->show_item) return;
2628 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2630 dx = it->x + it->item->block->x;
2631 dy = it->y + it->item->block->y;
2632 dw = it->item->block->w;
2634 switch (wd->scrollto_type)
2636 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2637 if (it->item->group_item) gith = it->item->group_item->item->h;
2640 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2641 dy += ((it->item->h / 2) - (oh / 2));
2643 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2645 if ((wd->expanded_item) &&
2646 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2647 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2649 it = wd->expanded_item;
2650 if (it->item->group_item) gith = it->item->group_item->item->h;
2651 dx = it->x + it->item->block->x;
2652 dy = it->y + it->item->block->y - gith;
2653 dw = it->item->block->w;
2657 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2658 gith = it->item->group_item->item->h;
2665 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2667 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2669 it->item->showme = EINA_FALSE;
2670 wd->show_item = NULL;
2671 wd->auto_scroll_enabled = EINA_FALSE;
2672 wd->check_scroll = EINA_FALSE;
2676 _calc_job(void *data)
2678 Widget_Data *wd = data;
2679 Item_Block *itb, *chb = NULL;
2680 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2681 Evas_Coord pan_w = 0, pan_h = 0;
2683 Eina_Bool minw_change = EINA_FALSE;
2684 Eina_Bool did_must_recalc = EINA_FALSE;
2687 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2688 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2693 evas_event_freeze(evas_object_evas_get(wd->obj));
2694 EINA_INLIST_FOREACH(wd->blocks, itb)
2696 Eina_Bool showme = EINA_FALSE;
2699 showme = itb->showme;
2700 itb->showme = EINA_FALSE;
2703 if (itb->realized) _item_block_unrealize(itb);
2705 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2707 if (itb->must_recalc)
2711 EINA_LIST_FOREACH(itb->items, l, it)
2712 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2713 itb->changed = EINA_TRUE;
2714 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2715 if (itb->realized) _item_block_unrealize(itb);
2716 itb->must_recalc = EINA_FALSE;
2718 showme = _item_block_recalc(itb, in, EINA_FALSE);
2724 if (minw == -1) minw = itb->minw;
2725 else if ((!itb->must_recalc) && (minw < itb->minw))
2728 minw_change = EINA_TRUE;
2733 minw_change = EINA_TRUE;
2739 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2740 wd->check_scroll = EINA_TRUE;
2744 EINA_INLIST_FOREACH(wd->blocks, itb)
2750 if ((chb) && (EINA_INLIST_GET(chb)->next))
2752 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2754 if (itb->realized) _item_block_unrealize(itb);
2757 wd->realminw = minw;
2758 if (minw < wd->w) minw = wd->w;
2759 if ((minw != wd->minw) || (minh != wd->minh))
2763 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2764 _sizing_eval(wd->obj);
2765 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2770 it = wd->anchor_item;
2771 it_y = wd->anchor_y;
2772 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2773 it->item->block->y + it->y + it_y);
2774 wd->anchor_item = it;
2775 wd->anchor_y = it_y;
2778 if (did_must_recalc)
2780 if (!wd->must_recalc_idler)
2781 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2783 if (wd->check_scroll)
2785 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2786 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2787 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2788 switch (wd->scrollto_type)
2790 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2793 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2796 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2803 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2804 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2810 wd->calc_job = NULL;
2811 evas_object_smart_changed(wd->pan_smart);
2812 evas_event_thaw(evas_object_evas_get(wd->obj));
2813 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2817 _update_job(void *data)
2819 Widget_Data *wd = data;
2823 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2825 wd->update_job = NULL;
2828 evas_event_freeze(evas_object_evas_get(wd->obj));
2829 EINA_INLIST_FOREACH(wd->blocks, itb)
2831 Evas_Coord itminw, itminh;
2838 _item_block_position(itb, num);
2842 recalc = EINA_FALSE;
2843 EINA_LIST_FOREACH(itb->items, l2, it)
2845 if (it->item->updateme)
2847 itminw = it->item->minw;
2848 itminh = it->item->minh;
2850 it->item->updateme = EINA_FALSE;
2853 _elm_genlist_item_unrealize(it, EINA_FALSE);
2854 _item_realize(it, num, EINA_FALSE);
2855 position = EINA_TRUE;
2859 _item_realize(it, num, EINA_TRUE);
2860 _elm_genlist_item_unrealize(it, EINA_TRUE);
2862 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2867 itb->updateme = EINA_FALSE;
2870 position = EINA_TRUE;
2871 itb->changed = EINA_TRUE;
2872 _item_block_recalc(itb, num0, EINA_FALSE);
2873 _item_block_position(itb, num0);
2878 if (wd->calc_job) ecore_job_del(wd->calc_job);
2879 wd->calc_job = ecore_job_add(_calc_job, wd);
2881 evas_event_thaw(evas_object_evas_get(wd->obj));
2882 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2886 _pan_set(Evas_Object *obj,
2890 Pan *sd = evas_object_smart_data_get(obj);
2894 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2898 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2900 if ((itb->y + itb->h) > y)
2905 EINA_LIST_FOREACH(itb->items, l2, it)
2907 if ((itb->y + it->y) >= y)
2909 sd->wd->anchor_item = it;
2910 sd->wd->anchor_y = -(itb->y + it->y - y);
2917 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2921 _pan_get(Evas_Object *obj,
2925 Pan *sd = evas_object_smart_data_get(obj);
2928 if (x) *x = sd->wd->pan_x;
2929 if (y) *y = sd->wd->pan_y;
2933 _pan_max_get(Evas_Object *obj,
2937 Pan *sd = evas_object_smart_data_get(obj);
2941 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2942 ow = sd->wd->minw - ow;
2944 oh = sd->wd->minh - oh;
2951 _pan_min_get(Evas_Object *obj __UNUSED__,
2960 _pan_child_size_get(Evas_Object *obj,
2964 Pan *sd = evas_object_smart_data_get(obj);
2967 if (w) *w = sd->wd->minw;
2968 if (h) *h = sd->wd->minh;
2972 _pan_add(Evas_Object *obj)
2975 Evas_Object_Smart_Clipped_Data *cd;
2978 cd = evas_object_smart_data_get(obj);
2981 sd->__clipped_data = *cd;
2983 evas_object_smart_data_set(obj, sd);
2987 _pan_del(Evas_Object *obj)
2989 Pan *sd = evas_object_smart_data_get(obj);
2994 ecore_job_del(sd->resize_job);
2995 sd->resize_job = NULL;
3001 _pan_resize_job(void *data)
3005 _sizing_eval(sd->wd->obj);
3006 sd->resize_job = NULL;
3010 _pan_resize(Evas_Object *obj,
3014 Pan *sd = evas_object_smart_data_get(obj);
3018 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3019 if ((ow == w) && (oh == h)) return;
3020 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3023 if (sd->resize_job) ecore_job_del(sd->resize_job);
3024 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3026 sd->wd->pan_changed = EINA_TRUE;
3027 evas_object_smart_changed(obj);
3028 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3029 sd->wd->calc_job = NULL;
3033 _pan_calculate(Evas_Object *obj)
3035 Pan *sd = evas_object_smart_data_get(obj);
3037 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3043 evas_event_freeze(evas_object_evas_get(obj));
3045 if (sd->wd->pan_changed)
3048 sd->wd->pan_changed = EINA_FALSE;
3051 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3052 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3053 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3055 git->item->want_realize = EINA_FALSE;
3058 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3060 if (!sd->wd->tree_effect_animator)
3062 _item_tree_effect_before(sd->wd->expanded_item);
3063 evas_object_raise(sd->wd->alpha_bg);
3064 evas_object_show(sd->wd->alpha_bg);
3065 sd->wd->start_time = ecore_time_get();
3066 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3070 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3072 itb->w = sd->wd->minw;
3073 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3074 itb->y - sd->wd->pan_y + oy,
3076 cvx, cvy, cvw, cvh))
3078 if ((!itb->realized) || (itb->changed))
3079 _item_block_realize(itb);
3080 _item_block_position(itb, in);
3084 if (itb->realized) _item_block_unrealize(itb);
3088 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3089 _group_items_recalc(sd->wd);
3090 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3092 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3093 sd->wd->reorder_pan_move = EINA_TRUE;
3094 else sd->wd->reorder_pan_move = EINA_FALSE;
3095 evas_object_raise(sd->wd->VIEW(reorder_it));
3096 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3097 sd->wd->start_time = ecore_loop_time_get();
3100 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3101 _item_auto_scroll(sd->wd);
3103 evas_event_thaw(evas_object_evas_get(obj));
3104 evas_event_thaw_eval(evas_object_evas_get(obj));
3108 _pan_move(Evas_Object *obj,
3109 Evas_Coord x __UNUSED__,
3110 Evas_Coord y __UNUSED__)
3112 Pan *sd = evas_object_smart_data_get(obj);
3116 sd->wd->pan_changed = EINA_TRUE;
3117 evas_object_smart_changed(obj);
3118 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3119 sd->wd->calc_job = NULL;
3123 _hold_on(void *data __UNUSED__,
3125 void *event_info __UNUSED__)
3127 Widget_Data *wd = elm_widget_data_get(obj);
3129 elm_smart_scroller_hold_set(wd->scr, 1);
3133 _hold_off(void *data __UNUSED__,
3135 void *event_info __UNUSED__)
3137 Widget_Data *wd = elm_widget_data_get(obj);
3139 elm_smart_scroller_hold_set(wd->scr, 0);
3143 _freeze_on(void *data __UNUSED__,
3145 void *event_info __UNUSED__)
3147 Widget_Data *wd = elm_widget_data_get(obj);
3149 elm_smart_scroller_freeze_set(wd->scr, 1);
3153 _freeze_off(void *data __UNUSED__,
3155 void *event_info __UNUSED__)
3157 Widget_Data *wd = elm_widget_data_get(obj);
3159 elm_smart_scroller_freeze_set(wd->scr, 0);
3163 _scr_anim_start(void *data,
3164 Evas_Object *obj __UNUSED__,
3165 void *event_info __UNUSED__)
3167 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3171 _scr_anim_stop(void *data,
3172 Evas_Object *obj __UNUSED__,
3173 void *event_info __UNUSED__)
3175 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3179 _scr_drag_start(void *data,
3180 Evas_Object *obj __UNUSED__,
3181 void *event_info __UNUSED__)
3183 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3187 _scr_drag_stop(void *data,
3188 Evas_Object *obj __UNUSED__,
3189 void *event_info __UNUSED__)
3191 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3195 _edge_left(void *data,
3196 Evas_Object *scr __UNUSED__,
3197 void *event_info __UNUSED__)
3199 Evas_Object *obj = data;
3200 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3204 _edge_right(void *data,
3205 Evas_Object *scr __UNUSED__,
3206 void *event_info __UNUSED__)
3208 Evas_Object *obj = data;
3209 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3213 _edge_top(void *data,
3214 Evas_Object *scr __UNUSED__,
3215 void *event_info __UNUSED__)
3217 Evas_Object *obj = data;
3218 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3222 _edge_bottom(void *data,
3223 Evas_Object *scr __UNUSED__,
3224 void *event_info __UNUSED__)
3226 Evas_Object *obj = data;
3227 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3231 _decorate_item_realize(Elm_Gen_Item *it)
3235 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3237 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3238 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3239 edje_object_scale_set(it->item->deco_it_view,
3240 elm_widget_scale_get(WIDGET(it)) *
3241 _elm_config->scale);
3242 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3243 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3245 strncpy(buf, "item", sizeof(buf));
3246 if (it->wd->mode == ELM_LIST_COMPRESS)
3247 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3249 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3250 strncat(buf, "/", sizeof(buf) - strlen(buf));
3251 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3253 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3254 elm_widget_style_get(WIDGET(it)));
3255 edje_object_mirrored_set(it->item->deco_it_view,
3256 elm_widget_mirrored_get(WIDGET(it)));
3258 /* signal callback add */
3259 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3261 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3263 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3266 /* text_get, content_get, state_get */
3267 /* FIXME: If you see that assert, please notify us and we
3268 will clean our mess */
3269 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3271 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3272 if (!it->item->deco_it_contents)
3273 it->item->deco_it_contents =
3274 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3275 it->item->deco_it_content_objs =
3276 _item_mode_content_realize(it, it->item->deco_it_view,
3277 &it->item->deco_it_contents, NULL,
3278 &it->item->deco_it_content_objs);
3279 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3280 edje_object_part_swallow(it->item->deco_it_view,
3281 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3284 it->want_unrealize = EINA_FALSE;
3285 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3286 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3290 _decorate_item_unrealize(Elm_Gen_Item *it)
3292 Widget_Data *wd = it->wd;
3293 Evas_Object *content;
3294 if (!it->item->deco_it_view) return;
3296 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3297 elm_widget_stringlist_free(it->item->deco_it_texts);
3298 it->item->deco_it_texts = NULL;
3299 elm_widget_stringlist_free(it->item->deco_it_contents);
3300 it->item->deco_it_contents = NULL;
3301 elm_widget_stringlist_free(it->item->deco_it_states);
3303 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3304 evas_object_del(content);
3306 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3307 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3308 evas_object_del(it->item->deco_it_view);
3309 it->item->deco_it_view = NULL;
3311 if (wd->mode_item == it)
3312 wd->mode_item = NULL;
3313 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3314 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3318 _decorate_item_set(Elm_Gen_Item *it)
3321 Widget_Data *wd = it->wd;
3326 it->item->nocache_once = EINA_TRUE;
3328 if (wd->scr_hold_timer)
3330 ecore_timer_del(wd->scr_hold_timer);
3331 wd->scr_hold_timer = NULL;
3333 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3334 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3336 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3337 _decorate_item_realize(it);
3338 if (it->item->group_item)
3339 evas_object_raise(it->item->VIEW(group_item));
3340 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3341 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3342 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3344 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3345 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3349 _decorate_item_unset(Widget_Data *wd)
3352 if (!wd->mode_item) return;
3353 char buf[1024], buf2[1024];
3357 it->item->nocache_once = EINA_TRUE;
3359 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3360 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3362 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3363 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3365 wd->mode_item = NULL;
3369 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3371 if ((!it) || (!it->wd->decorate_all_mode)) return;
3372 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3373 evas_object_move(it->deco_all_view, itx, ity);
3377 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3380 const char *stacking_even;
3381 const char *stacking;
3383 if ((!it) || (it->item->decorate_all_item_realized) ||
3384 (it->generation < it->wd->generation))
3387 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3388 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3389 _elm_config->scale);
3390 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3391 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3393 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3394 strncpy(buf, "tree", sizeof(buf));
3395 else strncpy(buf, "item", sizeof(buf));
3396 if (it->wd->mode == ELM_LIST_COMPRESS)
3397 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3399 strncat(buf, "/", sizeof(buf) - strlen(buf));
3400 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3402 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3403 elm_widget_style_get(WIDGET(it)));
3405 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3406 if (!stacking_even) stacking_even = "above";
3407 it->item->stacking_even = !!strcmp("above", stacking_even);
3409 stacking = edje_object_data_get(VIEW(it), "stacking");
3410 if (!stacking) stacking = "yes";
3411 it->item->nostacking = !!strcmp("yes", stacking);
3413 edje_object_mirrored_set(it->deco_all_view,
3414 elm_widget_mirrored_get(WIDGET(it)));
3416 _elm_genlist_item_odd_even_update(it);
3417 _elm_genlist_item_state_update(it, NULL);
3419 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3420 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3422 _item_mouse_callbacks_del(it, VIEW(it));
3423 _item_mouse_callbacks_add(it, it->deco_all_view);
3425 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3426 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3427 if (!it->item->deco_all_contents)
3428 it->item->deco_all_contents =
3429 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "contents"));
3430 it->item->deco_all_content_objs =
3431 _item_mode_content_realize(it, it->deco_all_view,
3432 &it->item->deco_all_contents, NULL,
3433 &it->item->deco_all_content_objs);
3434 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3435 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3437 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3438 evas_object_show(it->deco_all_view);
3440 if (it->selected) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
3442 it->item->decorate_all_item_realized = EINA_TRUE;
3443 it->want_unrealize = EINA_FALSE;
3447 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3450 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3452 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3453 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3454 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3455 _elm_genlist_item_odd_even_update(it);
3456 _elm_genlist_item_state_update(it, NULL);
3458 evas_object_del(it->deco_all_view);
3459 it->deco_all_view = NULL;
3460 elm_widget_stringlist_free(it->item->deco_all_texts);
3461 it->item->deco_all_texts = NULL;
3462 elm_widget_stringlist_free(it->item->deco_all_contents);
3463 it->item->deco_all_contents = NULL;
3464 elm_widget_stringlist_free(it->item->deco_all_states);
3465 it->item->deco_all_states = NULL;
3466 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3467 evas_object_del(icon);
3468 edje_object_message_signal_process(it->deco_all_view);
3469 _item_mouse_callbacks_del(it, it->deco_all_view);
3470 _item_mouse_callbacks_add(it, VIEW(it));
3472 it->item->decorate_all_item_realized = EINA_FALSE;
3476 _item_auto_scroll(Widget_Data *wd)
3479 Elm_Gen_Item *tmp_item = NULL;
3481 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3483 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3484 if (!tmp_item) return;
3485 wd->show_item = tmp_item;
3486 wd->bring_in = EINA_TRUE;
3487 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3488 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3490 wd->show_item->item->showme = EINA_TRUE;
3491 wd->auto_scroll_enabled = EINA_FALSE;
3499 elm_genlist_add(Evas_Object *parent)
3504 Evas_Coord minw, minh;
3505 static Evas_Smart *smart = NULL;
3509 static Evas_Smart_Class sc;
3511 evas_object_smart_clipped_smart_set(&_pan_sc);
3513 sc.name = "elm_genlist_pan";
3514 sc.version = EVAS_SMART_CLASS_VERSION;
3517 sc.resize = _pan_resize;
3518 sc.move = _pan_move;
3519 sc.calculate = _pan_calculate;
3520 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3523 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3525 ELM_SET_WIDTYPE(widtype, "genlist");
3527 elm_widget_type_set(obj, "genlist");
3528 elm_widget_sub_object_add(parent, obj);
3529 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3530 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3531 elm_widget_data_set(obj, wd);
3532 elm_widget_del_hook_set(obj, _del_hook);
3533 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3534 elm_widget_theme_hook_set(obj, _theme_hook);
3535 elm_widget_can_focus_set(obj, EINA_TRUE);
3536 elm_widget_event_hook_set(obj, _event_hook);
3537 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3538 elm_widget_translate_hook_set(obj, _translate_hook);
3541 wd->scr = elm_smart_scroller_add(e);
3542 elm_smart_scroller_widget_set(wd->scr, obj);
3543 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3544 elm_widget_style_get(obj));
3545 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3546 _elm_config->thumbscroll_bounce_enable);
3547 elm_widget_resize_object_set(obj, wd->scr);
3549 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3550 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3551 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3552 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3553 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3554 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3555 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3556 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3559 wd->mode = ELM_LIST_SCROLL;
3560 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3561 wd->item_cache_max = wd->max_items_per_block * 2;
3562 wd->longpress_timeout = _elm_config->longpress_timeout;
3563 wd->highlight = EINA_TRUE;
3565 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3566 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3567 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3568 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3570 wd->pan_smart = evas_object_smart_add(e, smart);
3571 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3574 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3575 _pan_set, _pan_get, _pan_max_get,
3576 _pan_min_get, _pan_child_size_get);
3578 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3580 evas_object_size_hint_min_set(obj, minw, minh);
3582 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3584 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3590 _item_select(Elm_Gen_Item *it)
3592 Evas_Object *obj = WIDGET(it);
3594 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3595 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3596 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3600 it->selected = EINA_TRUE;
3601 it->wd->selected = eina_list_append(it->wd->selected, it);
3603 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3605 evas_object_ref(obj);
3608 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3609 if (it->generation == it->wd->generation)
3610 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3613 if ((it->wd->clear_me) && (!it->wd->walking))
3614 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3617 if ((!it->walking) && (it->generation < it->wd->generation))
3622 elm_widget_item_free(it);
3626 it->wd->last_selected_item = (Elm_Object_Item *)it;
3628 evas_object_unref(obj);
3631 static Evas_Object *
3632 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3634 return edje_object_part_swallow_get(VIEW(it), part);
3638 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
3640 if (!it->itc->func.text_get) return NULL;
3641 return edje_object_part_text_get(VIEW(it), part);
3645 _item_disable_hook(Elm_Object_Item *it)
3649 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3651 if (_it->generation < _it->wd->generation) return;
3654 elm_genlist_item_selected_set(it, EINA_FALSE);
3658 if (elm_widget_item_disabled_get(it))
3660 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
3661 if (_it->deco_all_view)
3662 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
3666 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
3667 if (_it->deco_all_view)
3668 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
3670 EINA_LIST_FOREACH(_it->content_objs, l, obj)
3671 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
3676 _item_del_pre_hook(Elm_Object_Item *it)
3678 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3680 if ((_it->relcount > 0) || (_it->walking > 0))
3682 elm_genlist_item_subitems_clear(it);
3683 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
3684 _elm_genlist_item_del_notserious(_it);
3685 if (_it->item->block)
3687 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
3688 _it->item->block->changed = EINA_TRUE;
3689 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
3690 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
3694 _it->parent->item->items =
3695 eina_list_remove(_it->parent->item->items, it);
3705 _item_signal_emit_hook(Elm_Object_Item *it,
3706 const char *emission,
3709 edje_object_signal_emit(VIEW(it), emission, source);
3713 _elm_genlist_item_new(Widget_Data *wd,
3714 const Elm_Gen_Item_Class *itc,
3716 Elm_Gen_Item *parent,
3718 const void *func_data)
3722 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3723 if (!it) return NULL;
3725 it->generation = wd->generation;
3727 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
3728 it->base.data = data;
3729 it->parent = parent;
3730 it->func.func = func;
3731 it->func.data = func_data;
3732 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3733 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
3734 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3735 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3736 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
3739 it->sel_cb = (Ecore_Cb)_item_select;
3744 static Elm_Gen_Item *
3745 _item_new(Widget_Data *wd,
3746 const Elm_Genlist_Item_Class *itc,
3748 Elm_Gen_Item *parent,
3749 Elm_Genlist_Item_Type type,
3751 const void *func_data)
3753 Elm_Gen_Item *it, *it2;
3756 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3757 if (!it) return NULL;
3758 it->item = ELM_NEW(Elm_Gen_Item_Type);
3759 it->item->type = type;
3760 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
3761 it->item->expanded_depth = 0;
3762 ELM_GEN_ITEM_SETUP(it);
3765 if (it->parent->group)
3766 it->item->group_item = parent;
3767 else if (it->parent->item->group_item)
3768 it->item->group_item = it->parent->item->group_item;
3770 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3772 if (!it2->parent->group) depth += 1;
3774 it->item->expanded_depth = depth;
3780 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3784 itb = calloc(1, sizeof(Item_Block));
3785 if (!itb) return NULL;
3789 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3790 _item_block_position_update(wd->blocks, 0);
3794 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3795 itb->position_update = EINA_TRUE;
3796 if (wd->blocks != EINA_INLIST_GET(itb))
3798 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3809 _item_block_add(Widget_Data *wd,
3812 Item_Block *itb = NULL;
3819 itb = calloc(1, sizeof(Item_Block));
3820 if (!itb) return EINA_FALSE;
3822 if (!it->item->rel->item->block)
3825 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3826 itb->items = eina_list_append(itb->items, it);
3827 itb->position_update = EINA_TRUE;
3828 it->position = eina_list_count(itb->items);
3829 it->position_update = EINA_TRUE;
3831 if (wd->blocks != EINA_INLIST_GET(itb))
3833 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3844 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3845 if (it->item->before)
3847 wd->blocks = eina_inlist_prepend_relative
3848 (wd->blocks, EINA_INLIST_GET(itb),
3849 EINA_INLIST_GET(it->item->rel->item->block));
3851 eina_list_prepend_relative_list(itb->items, it, tmp);
3853 /* Update index from where we prepended */
3854 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3855 _item_block_position_update(EINA_INLIST_GET(itb),
3856 it->item->rel->item->block->position);
3860 wd->blocks = eina_inlist_append_relative
3861 (wd->blocks, EINA_INLIST_GET(itb),
3862 EINA_INLIST_GET(it->item->rel->item->block));
3864 eina_list_append_relative_list(itb->items, it, tmp);
3866 /* Update block index from where we appended */
3867 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3868 _item_block_position_update(EINA_INLIST_GET(itb),
3869 it->item->rel->item->block->position + 1);
3875 if (it->item->before)
3879 itb = (Item_Block *)(wd->blocks);
3880 if (itb->count >= wd->max_items_per_block)
3882 itb = _item_block_new(wd, EINA_TRUE);
3883 if (!itb) return EINA_FALSE;
3888 itb = _item_block_new(wd, EINA_TRUE);
3889 if (!itb) return EINA_FALSE;
3891 itb->items = eina_list_prepend(itb->items, it);
3893 _item_position_update(itb->items, 0);
3899 itb = (Item_Block *)(wd->blocks->last);
3900 if (itb->count >= wd->max_items_per_block)
3902 itb = _item_block_new(wd, EINA_FALSE);
3903 if (!itb) return EINA_FALSE;
3908 itb = _item_block_new(wd, EINA_FALSE);
3909 if (!itb) return EINA_FALSE;
3911 itb->items = eina_list_append(itb->items, it);
3912 it->position = eina_list_count(itb->items);
3920 if (it->item->rel->item->queued)
3922 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3923 on sorted insertion order, so the queue is not always ordered like the item list.
3924 This lead to issue where we depend on an item that is not yet created. As a quick
3925 work around, we reschedule the calc of the item and stop reordering the list to
3926 prevent any nasty issue to show up here.
3928 wd->queue = eina_list_append(wd->queue, it);
3929 wd->requeued = EINA_TRUE;
3930 it->item->queued = EINA_TRUE;
3933 itb = it->item->rel->item->block;
3934 if (!itb) goto newblock;
3935 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3936 if (it->item->before)
3938 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3939 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3943 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3944 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3948 itb->changed = EINA_TRUE;
3949 it->item->block = itb;
3950 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3951 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3954 it->item->rel->relcount--;
3955 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3957 _item_del(it->item->rel);
3958 elm_widget_item_free(it->item->rel);
3960 it->item->rel = NULL;
3962 if (itb->count > itb->wd->max_items_per_block)
3967 Eina_Bool done = EINA_FALSE;
3969 newc = itb->count / 2;
3971 if (EINA_INLIST_GET(itb)->prev)
3973 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3975 if (itbp->count + newc < wd->max_items_per_block / 2)
3977 /* moving items to previous block */
3978 while ((itb->count > newc) && (itb->items))
3980 it2 = eina_list_data_get(itb->items);
3981 itb->items = eina_list_remove_list(itb->items, itb->items);
3984 itbp->items = eina_list_append(itbp->items, it2);
3985 it2->item->block = itbp;
3993 if (!done && EINA_INLIST_GET(itb)->next)
3995 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3997 if (itbn->count + newc < wd->max_items_per_block / 2)
3999 /* moving items to next block */
4000 while ((itb->count > newc) && (itb->items))
4004 l = eina_list_last(itb->items);
4005 it2 = eina_list_data_get(l);
4006 itb->items = eina_list_remove_list(itb->items, l);
4009 itbn->items = eina_list_prepend(itbn->items, it2);
4010 it2->item->block = itbn;
4020 /* moving items to new block */
4021 itb2 = calloc(1, sizeof(Item_Block));
4022 if (!itb2) return EINA_FALSE;
4025 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4026 EINA_INLIST_GET(itb));
4027 itb2->changed = EINA_TRUE;
4028 while ((itb->count > newc) && (itb->items))
4032 l = eina_list_last(itb->items);
4034 itb->items = eina_list_remove_list(itb->items, l);
4037 itb2->items = eina_list_prepend(itb2->items, it2);
4038 it2->item->block = itb2;
4048 _queue_process(Widget_Data *wd)
4051 Eina_Bool showme = EINA_FALSE;
4054 t0 = ecore_loop_time_get();
4055 //evas_event_freeze(evas_object_evas_get(wd->obj));
4056 for (n = 0; (wd->queue) && (n < 128); n++)
4060 it = eina_list_data_get(wd->queue);
4061 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4062 it->item->queued = EINA_FALSE;
4063 if (!_item_block_add(wd, it)) continue;
4065 _item_block_realize(it->item->block);
4066 t = ecore_time_get();
4067 if (it->item->block->changed)
4069 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4070 it->item->block->changed = 0;
4071 if (wd->pan_changed)
4073 if (wd->calc_job) ecore_job_del(wd->calc_job);
4074 wd->calc_job = NULL;
4076 wd->pan_changed = EINA_FALSE;
4079 if (showme) it->item->block->showme = EINA_TRUE;
4080 /* same as eina_inlist_count > 1 */
4081 if (wd->blocks && wd->blocks->next)
4083 if ((t - t0) > (ecore_animator_frametime_get())) break;
4086 //evas_event_thaw(evas_object_evas_get(wd->obj));
4087 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4092 _idle_process(void *data, Eina_Bool *wakeup)
4094 Widget_Data *wd = data;
4097 //static double q_start = 0.0;
4098 //if (q_start == 0.0) q_start = ecore_time_get();
4100 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4104 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4106 return ECORE_CALLBACK_CANCEL;
4108 return ECORE_CALLBACK_RENEW;
4112 _item_idle_enterer(void *data)
4114 Widget_Data *wd = data;
4115 Eina_Bool wakeup = EINA_FALSE;
4116 Eina_Bool ok = _idle_process(data, &wakeup);
4121 if (wd->calc_job) ecore_job_del(wd->calc_job);
4122 wd->calc_job = ecore_job_add(_calc_job, wd);
4124 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4129 _item_queue(Widget_Data *wd,
4133 if (it->item->queued) return;
4134 it->item->queued = EINA_TRUE;
4135 if (cb && !wd->requeued)
4136 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4138 wd->queue = eina_list_append(wd->queue, it);
4139 // FIXME: why does a freeze then thaw here cause some genlist
4140 // elm_genlist_item_append() to be much much slower?
4141 // evas_event_freeze(evas_object_evas_get(wd->obj));
4142 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4144 if (wd->queue_idle_enterer)
4146 ecore_idle_enterer_del(wd->queue_idle_enterer);
4147 wd->queue_idle_enterer = NULL;
4151 // evas_event_thaw(evas_object_evas_get(wd->obj));
4152 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4153 if (!wd->queue_idle_enterer)
4154 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4158 _elm_genlist_item_compare(const void *data, const void *data1)
4160 const Elm_Gen_Item *it, *item1;
4161 it = ELM_GEN_ITEM_FROM_INLIST(data);
4162 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4163 return it->wd->item_compare_cb(it, item1);
4167 _elm_genlist_item_list_compare(const void *data, const void *data1)
4169 const Elm_Gen_Item *it = data;
4170 const Elm_Gen_Item *item1 = data1;
4171 return it->wd->item_compare_cb(it, item1);
4174 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4176 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4181 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4182 _item_block_del(it);
4184 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4185 it->item->rel = after;
4186 it->item->rel->relcount++;
4187 it->item->before = EINA_FALSE;
4188 if (after->item->group_item) it->item->group_item = after->item->group_item;
4189 _item_queue(it->wd, it, NULL);
4191 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4194 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4196 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4199 if (!before) return;
4201 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4202 _item_block_del(it);
4203 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4204 it->item->rel = before;
4205 it->item->rel->relcount++;
4206 it->item->before = EINA_TRUE;
4207 if (before->item->group_item) it->item->group_item = before->item->group_item;
4208 _item_queue(it->wd, it, NULL);
4210 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4214 elm_genlist_items_count(const Evas_Object *obj)
4216 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4217 Widget_Data *wd = elm_widget_data_get(obj);
4219 return wd->item_count;
4222 EAPI Elm_Object_Item *
4223 elm_genlist_item_append(Evas_Object *obj,
4224 const Elm_Genlist_Item_Class *itc,
4226 Elm_Object_Item *parent,
4227 Elm_Genlist_Item_Type type,
4229 const void *func_data)
4231 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4232 Widget_Data *wd = elm_widget_data_get(obj);
4233 if (!wd) return NULL;
4234 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4236 if (!it) return NULL;
4240 wd->group_items = eina_list_append(wd->group_items, it);
4241 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4242 it->item->rel = NULL;
4246 Elm_Gen_Item *it2 = NULL;
4247 Eina_List *ll = eina_list_last(it->parent->item->items);
4248 if (ll) it2 = ll->data;
4249 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4250 if (!it2) it2 = it->parent;
4252 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4253 EINA_INLIST_GET(it2));
4254 it->item->rel = it2;
4255 it->item->rel->relcount++;
4257 it->item->before = EINA_FALSE;
4258 _item_queue(wd, it, NULL);
4259 return (Elm_Object_Item *)it;
4262 EAPI Elm_Object_Item *
4263 elm_genlist_item_prepend(Evas_Object *obj,
4264 const Elm_Genlist_Item_Class *itc,
4266 Elm_Object_Item *parent,
4267 Elm_Genlist_Item_Type type,
4269 const void *func_data)
4271 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4272 Widget_Data *wd = elm_widget_data_get(obj);
4273 if (!wd) return NULL;
4274 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4276 if (!it) return NULL;
4280 wd->group_items = eina_list_prepend(wd->group_items, it);
4281 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4282 it->item->rel = NULL;
4286 Elm_Gen_Item *it2 = NULL;
4287 Eina_List *ll = it->parent->item->items;
4288 if (ll) it2 = ll->data;
4289 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4290 if (!it2) it2 = it->parent;
4292 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4293 EINA_INLIST_GET(it2));
4294 it->item->rel = it2;
4295 it->item->rel->relcount++;
4297 it->item->before = EINA_TRUE;
4298 _item_queue(wd, it, NULL);
4299 return (Elm_Object_Item *)it;
4302 EAPI Elm_Object_Item *
4303 elm_genlist_item_insert_after(Evas_Object *obj,
4304 const Elm_Genlist_Item_Class *itc,
4306 Elm_Object_Item *parent,
4307 Elm_Object_Item *after,
4308 Elm_Genlist_Item_Type type,
4310 const void *func_data)
4312 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4313 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4314 Widget_Data *wd = elm_widget_data_get(obj);
4315 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4316 if (!wd) return NULL;
4317 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4318 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4320 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4322 if (!it) return NULL;
4325 if ((it->group) && (_after->group))
4326 wd->group_items = eina_list_append_relative(wd->group_items, it,
4331 it->parent->item->items =
4332 eina_list_append_relative(it->parent->item->items, it, _after);
4334 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4335 EINA_INLIST_GET(_after));
4336 it->item->rel = _after;
4337 it->item->rel->relcount++;
4338 it->item->before = EINA_FALSE;
4339 _item_queue(wd, it, NULL);
4340 return (Elm_Object_Item *)it;
4343 EAPI Elm_Object_Item *
4344 elm_genlist_item_insert_before(Evas_Object *obj,
4345 const Elm_Genlist_Item_Class *itc,
4347 Elm_Object_Item *parent,
4348 Elm_Object_Item *before,
4349 Elm_Genlist_Item_Type type,
4351 const void *func_data)
4353 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4354 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4355 Widget_Data *wd = elm_widget_data_get(obj);
4356 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4357 if (!wd) return NULL;
4358 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4359 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4361 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4363 if (!it) return NULL;
4366 if (it->group && _before->group)
4367 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4372 it->parent->item->items =
4373 eina_list_prepend_relative(it->parent->item->items, it, _before);
4375 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4376 EINA_INLIST_GET(_before));
4377 it->item->rel = _before;
4378 it->item->rel->relcount++;
4379 it->item->before = EINA_TRUE;
4380 _item_queue(wd, it, NULL);
4381 return (Elm_Object_Item *)it;
4384 EAPI Elm_Object_Item *
4385 elm_genlist_item_sorted_insert(Evas_Object *obj,
4386 const Elm_Genlist_Item_Class *itc,
4388 Elm_Object_Item *parent,
4389 Elm_Genlist_Item_Type type,
4390 Eina_Compare_Cb comp,
4392 const void *func_data)
4394 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4395 Widget_Data *wd = elm_widget_data_get(obj);
4396 if (!wd) return NULL;
4397 Elm_Gen_Item *rel = NULL;
4398 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4400 if (!it) return NULL;
4402 wd->item_compare_cb = comp;
4409 l = eina_list_search_sorted_near_list(it->parent->item->items,
4410 _elm_genlist_item_list_compare,
4414 rel = eina_list_data_get(l);
4418 if (cmp_result >= 0)
4420 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4421 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4422 it->item->before = EINA_FALSE;
4424 else if (cmp_result < 0)
4426 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4427 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4428 it->item->before = EINA_TRUE;
4435 wd->state = eina_inlist_sorted_state_new();
4436 eina_inlist_sorted_state_init(wd->state, wd->items);
4437 wd->requeued = EINA_FALSE;
4441 wd->group_items = eina_list_append(wd->group_items, it);
4443 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4444 _elm_genlist_item_compare, wd->state);
4446 if (EINA_INLIST_GET(it)->next)
4448 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4449 it->item->before = EINA_TRUE;
4451 else if (EINA_INLIST_GET(it)->prev)
4453 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4454 it->item->before = EINA_FALSE;
4460 it->item->rel = rel;
4461 it->item->rel->relcount++;
4464 _item_queue(wd, it, _elm_genlist_item_list_compare);
4466 return (Elm_Object_Item *)it;
4470 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4472 Eina_Inlist *next, *l;
4473 Widget_Data *wd = elm_widget_data_get(obj);
4476 if (!standby) wd->generation++;
4480 eina_inlist_sorted_state_free(wd->state);
4484 if (wd->walking > 0)
4486 wd->clear_me = EINA_TRUE;
4489 evas_event_freeze(evas_object_evas_get(wd->obj));
4490 for (l = wd->items, next = l ? l->next : NULL;
4492 l = next, next = next ? next->next : NULL)
4494 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4496 if (it->generation < wd->generation)
4498 Elm_Gen_Item *itn = NULL;
4500 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4501 if (itn) itn->walking++; /* prevent early death of subitem */
4503 elm_widget_item_free(it);
4504 if (itn) itn->walking--;
4507 wd->clear_me = EINA_FALSE;
4508 wd->pan_changed = EINA_TRUE;
4511 ecore_job_del(wd->calc_job);
4512 wd->calc_job = NULL;
4514 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4515 if (wd->clear_cb) wd->clear_cb(wd);
4521 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4522 wd->alpha_bg = NULL;
4526 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4527 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4529 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4530 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4531 evas_event_thaw(evas_object_evas_get(wd->obj));
4532 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4536 elm_genlist_clear(Evas_Object *obj)
4538 ELM_CHECK_WIDTYPE(obj, widtype);
4539 _elm_genlist_clear(obj, EINA_FALSE);
4543 elm_genlist_multi_select_set(Evas_Object *obj,
4546 ELM_CHECK_WIDTYPE(obj, widtype);
4547 Widget_Data *wd = elm_widget_data_get(obj);
4549 wd->multi = !!multi;
4553 elm_genlist_multi_select_get(const Evas_Object *obj)
4555 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4556 Widget_Data *wd = elm_widget_data_get(obj);
4557 if (!wd) return EINA_FALSE;
4561 EAPI Elm_Object_Item *
4562 elm_genlist_selected_item_get(const Evas_Object *obj)
4564 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4565 Widget_Data *wd = elm_widget_data_get(obj);
4566 if (!wd) return NULL;
4567 if (wd->selected) return wd->selected->data;
4571 EAPI const Eina_List *
4572 elm_genlist_selected_items_get(const Evas_Object *obj)
4574 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4575 Widget_Data *wd = elm_widget_data_get(obj);
4576 if (!wd) return NULL;
4577 return wd->selected;
4581 elm_genlist_realized_items_get(const Evas_Object *obj)
4583 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4584 Widget_Data *wd = elm_widget_data_get(obj);
4585 Eina_List *list = NULL;
4587 Eina_Bool done = EINA_FALSE;
4588 if (!wd) return NULL;
4589 EINA_INLIST_FOREACH(wd->blocks, itb)
4597 EINA_LIST_FOREACH(itb->items, l, it)
4599 if (it->realized) list = eina_list_append(list, it);
4610 EAPI Elm_Object_Item *
4611 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4616 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4617 Widget_Data *wd = elm_widget_data_get(obj);
4618 Evas_Coord ox, oy, ow, oh;
4621 if (!wd) return NULL;
4622 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4624 EINA_INLIST_FOREACH(wd->blocks, itb)
4629 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4630 oy + itb->y - itb->wd->pan_y,
4631 itb->w, itb->h, x, y, 1, 1))
4633 EINA_LIST_FOREACH(itb->items, l, it)
4635 Evas_Coord itx, ity;
4637 itx = ox + itb->x + it->x - itb->wd->pan_x;
4638 ity = oy + itb->y + it->y - itb->wd->pan_y;
4639 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4643 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4644 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4648 return (Elm_Object_Item *)it;
4650 lasty = ity + it->item->h;
4655 if (y > lasty) *posret = 1;
4661 EAPI Elm_Object_Item *
4662 elm_genlist_first_item_get(const Evas_Object *obj)
4664 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4665 Widget_Data *wd = elm_widget_data_get(obj);
4666 if (!wd) return NULL;
4667 if (!wd->items) return NULL;
4668 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4669 while ((it) && (it->generation < wd->generation))
4670 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4671 return (Elm_Object_Item *)it;
4674 EAPI Elm_Object_Item *
4675 elm_genlist_last_item_get(const Evas_Object *obj)
4677 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4678 Widget_Data *wd = elm_widget_data_get(obj);
4679 if (!wd) return NULL;
4680 if (!wd->items) return NULL;
4681 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4682 while ((it) && (it->generation < wd->generation))
4683 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4684 return (Elm_Object_Item *)it;
4687 EAPI Elm_Object_Item *
4688 elm_genlist_item_next_get(const Elm_Object_Item *it)
4690 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4691 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4694 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
4695 if ((_it) && (_it->generation == _it->wd->generation)) break;
4697 return (Elm_Object_Item *) _it;
4700 EAPI Elm_Object_Item *
4701 elm_genlist_item_prev_get(const Elm_Object_Item *it)
4703 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4704 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4707 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
4708 if ((_it) && (_it->generation == _it->wd->generation)) break;
4710 return (Elm_Object_Item *) _it;
4713 EAPI Elm_Object_Item *
4714 elm_genlist_item_parent_get(const Elm_Object_Item *it)
4716 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4717 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
4721 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
4723 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4724 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
4726 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4728 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
4729 _item_subitems_clear(_it);
4732 if (!wd->tree_effect_animator)
4734 wd->expanded_item = _it;
4735 _item_tree_effect_before(_it);
4736 evas_object_raise(wd->alpha_bg);
4737 evas_object_show(wd->alpha_bg);
4738 wd->start_time = ecore_time_get();
4739 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
4742 _item_subitems_clear(_it);
4747 elm_genlist_item_selected_set(Elm_Object_Item *it,
4750 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4751 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4752 Widget_Data *wd = _it->wd;
4754 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
4756 selected = !!selected;
4757 if (_it->selected == selected) return;
4763 while (wd->selected)
4765 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
4766 _it->unsel_cb(wd->selected->data);
4769 _it->highlight_cb(_it);
4773 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
4778 elm_genlist_item_selected_get(const Elm_Object_Item *it)
4780 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4781 return ((Elm_Gen_Item *)it)->selected;
4785 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
4788 if (it->item->expanded)
4790 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4794 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4797 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
4798 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4805 _elm_genlist_move_items_set(Elm_Gen_Item *it)
4808 Elm_Gen_Item *it2 = NULL;
4809 Evas_Coord ox, oy, ow, oh, dh = 0;
4811 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
4813 if (it->item->expanded)
4815 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
4816 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
4818 if (it2 == it->wd->expanded_next_item) break;
4819 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
4824 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
4825 it2 = it->wd->expanded_next_item;
4826 while (it2 && (dh < oy + oh))
4829 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
4830 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4836 elm_genlist_item_expanded_set(Elm_Object_Item *it,
4839 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4840 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4841 expanded = !!expanded;
4842 if (_it->item->expanded == expanded) return;
4843 _it->item->expanded = expanded;
4844 _it->wd->expanded_item = _it;
4845 _elm_genlist_move_items_set(_it);
4847 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
4848 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
4850 if (_it->item->expanded)
4852 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
4854 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
4855 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
4856 _it->wd->auto_scroll_enabled = EINA_TRUE;
4860 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
4862 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
4863 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
4864 _it->wd->auto_scroll_enabled = EINA_FALSE;
4869 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
4871 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4872 return ((Elm_Gen_Item *)it)->item->expanded;
4876 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
4878 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
4879 return ((Elm_Gen_Item *)it)->item->expanded_depth;
4883 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
4884 Elm_Genlist_Item_Scrollto_Type type,
4891 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4892 Evas_Coord gith = 0;
4893 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4894 if ((_it->item->queued) || (!_it->item->mincalcd))
4896 _it->wd->show_item = _it;
4897 _it->wd->bring_in = bring_in;
4898 _it->wd->scrollto_type = type;
4899 _it->item->showme = EINA_TRUE;
4902 if (_it->wd->show_item)
4904 _it->wd->show_item->item->showme = EINA_FALSE;
4905 _it->wd->show_item = NULL;
4908 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
4911 case ELM_GENLIST_ITEM_SCROLLTO_IN:
4912 if ((_it->item->group_item) &&
4913 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4914 gith = _it->item->group_item->item->h;
4916 *y = _it->y + _it->item->block->y - gith;
4918 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
4919 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4920 *y = _it->y + _it->item->block->y - gith;
4922 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
4923 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
4929 *x = _it->x + _it->item->block->x;
4930 *w = _it->item->block->w;
4935 elm_genlist_item_promote(Elm_Object_Item *it)
4937 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4938 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4939 if (_it->generation < _it->wd->generation) return;
4940 _item_move_before(_it,
4941 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
4945 elm_genlist_item_demote(Elm_Object_Item *it)
4947 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4948 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4949 if (_it->generation < _it->wd->generation) return;
4950 _item_move_after(_it,
4951 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
4955 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4957 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4958 Evas_Coord x, y, w, h;
4959 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4961 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
4962 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
4966 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4969 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4970 Evas_Coord x, y, w, h;
4971 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4973 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
4974 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
4978 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
4980 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4982 Evas_Object *content;
4983 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
4985 elm_widget_sub_object_del(WIDGET(it), content);
4986 evas_object_smart_member_del(content);
4987 evas_object_hide(content);
4988 if (l) *l = eina_list_append(*l, content);
4993 elm_genlist_item_update(Elm_Object_Item *it)
4995 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4996 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4998 if (!_it->item->block) return;
4999 if (_it->generation < _it->wd->generation) return;
5000 _it->item->mincalcd = EINA_FALSE;
5001 _it->item->updateme = EINA_TRUE;
5002 _it->item->block->updateme = EINA_TRUE;
5003 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5004 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5008 elm_genlist_item_fields_update(Elm_Object_Item *it,
5010 Elm_Genlist_Item_Field_Type itf)
5012 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5013 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5015 if (!_it->item->block) return;
5016 if (_it->generation < _it->wd->generation) return;
5018 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5019 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5020 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5022 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5023 &_it->contents, parts);
5024 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5025 &_it->contents, parts);
5029 _it->item->flip_content_objs =
5030 _item_mode_content_unrealize(_it, VIEW(_it),
5031 &_it->item->flip_contents, parts,
5032 &_it->item->flip_content_objs);
5033 _it->item->flip_content_objs =
5034 _item_mode_content_realize(_it, VIEW(_it),
5035 &_it->item->flip_contents, parts,
5036 &_it->item->flip_content_objs);
5038 if (_it->item->deco_it_view)
5040 _it->item->deco_it_content_objs =
5041 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5042 &_it->item->deco_it_contents, parts,
5043 &_it->item->deco_it_content_objs);
5044 _it->item->deco_it_content_objs =
5045 _item_mode_content_realize(_it, _it->item->deco_it_view,
5046 &_it->item->deco_it_contents, parts,
5047 &_it->item->deco_it_content_objs);
5049 if (_it->wd->decorate_all_mode)
5051 _it->item->deco_all_content_objs =
5052 _item_mode_content_unrealize(_it, _it->deco_all_view,
5053 &_it->item->deco_all_contents, parts,
5054 &_it->item->deco_all_content_objs);
5055 _it->item->deco_all_content_objs =
5056 _item_mode_content_realize(_it, _it->deco_all_view,
5057 &_it->item->deco_all_contents, parts,
5058 &_it->item->deco_all_content_objs);
5061 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5062 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5066 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5067 const Elm_Genlist_Item_Class *itc)
5069 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5070 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5072 if (!_it->item->block) return;
5073 EINA_SAFETY_ON_NULL_RETURN(itc);
5074 if (_it->generation < _it->wd->generation) return;
5076 _it->item->nocache_once = EINA_TRUE;
5078 elm_widget_stringlist_free(_it->texts);
5080 elm_widget_stringlist_free(_it->contents);
5081 _it->contents = NULL;
5082 elm_widget_stringlist_free(_it->states);
5087 elm_widget_stringlist_free(_it->item->flip_contents);
5088 _it->item->flip_contents = NULL;
5090 if (_it->item->deco_it_view)
5092 elm_widget_stringlist_free(_it->item->deco_it_texts);
5093 _it->item->deco_it_texts = NULL;
5094 elm_widget_stringlist_free(_it->item->deco_it_contents);
5095 _it->item->deco_it_contents = NULL;
5097 if (_it->wd->decorate_all_mode)
5099 elm_widget_stringlist_free(_it->item->deco_all_texts);
5100 _it->item->deco_all_texts = NULL;
5101 elm_widget_stringlist_free(_it->item->deco_all_contents);
5102 _it->item->deco_all_contents = NULL;
5105 elm_genlist_item_update(it);
5108 EAPI const Elm_Genlist_Item_Class *
5109 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5111 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5112 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5113 if (_it->generation < _it->wd->generation) return NULL;
5117 static Evas_Object *
5118 _elm_genlist_item_label_create(void *data,
5119 Evas_Object *obj __UNUSED__,
5120 Evas_Object *tooltip,
5121 void *it __UNUSED__)
5123 Evas_Object *label = elm_label_add(tooltip);
5126 elm_object_style_set(label, "tooltip");
5127 elm_object_text_set(label, data);
5132 _elm_genlist_item_label_del_cb(void *data,
5133 Evas_Object *obj __UNUSED__,
5134 void *event_info __UNUSED__)
5136 eina_stringshare_del(data);
5140 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5143 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5144 text = eina_stringshare_add(text);
5145 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5147 _elm_genlist_item_label_del_cb);
5151 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5152 Elm_Tooltip_Item_Content_Cb func,
5154 Evas_Smart_Cb del_cb)
5156 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5157 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5159 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5162 if (_it->tooltip.del_cb)
5163 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5165 _it->tooltip.content_cb = func;
5166 _it->tooltip.data = data;
5167 _it->tooltip.del_cb = del_cb;
5171 elm_widget_item_tooltip_content_cb_set(_it,
5172 _it->tooltip.content_cb,
5173 _it->tooltip.data, NULL);
5174 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5175 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5181 if (del_cb) del_cb((void *)data, NULL, NULL);
5185 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5187 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5188 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5190 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5191 elm_widget_item_tooltip_unset(_it);
5193 if (_it->tooltip.del_cb)
5194 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5195 _it->tooltip.del_cb = NULL;
5196 _it->tooltip.content_cb = NULL;
5197 _it->tooltip.data = NULL;
5198 _it->tooltip.free_size = EINA_FALSE;
5199 if (_it->tooltip.style)
5200 elm_genlist_item_tooltip_style_set(it, NULL);
5204 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5207 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5208 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5210 eina_stringshare_replace(&_it->tooltip.style, style);
5211 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5215 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5217 return elm_object_item_tooltip_style_get(it);
5221 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5224 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5225 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5227 _it->tooltip.free_size = disable;
5228 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5233 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5235 return elm_object_tooltip_window_mode_get(VIEW(it));
5239 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5242 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5243 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5244 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5245 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5249 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5251 return elm_widget_item_cursor_get(it);
5255 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5257 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5258 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5260 if (!_it->mouse_cursor) return;
5262 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5264 eina_stringshare_del(_it->mouse_cursor);
5265 _it->mouse_cursor = NULL;
5269 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5272 elm_widget_item_cursor_style_set(it, style);
5276 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5278 return elm_widget_item_cursor_style_get(it);
5282 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5283 Eina_Bool engine_only)
5285 elm_widget_item_cursor_engine_only_set(it, engine_only);
5289 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5291 return elm_widget_item_cursor_engine_only_get(it);
5295 elm_genlist_item_index_get(const Elm_Object_Item *it)
5297 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5298 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5300 if (_it->item->block)
5301 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5306 elm_genlist_mode_set(Evas_Object *obj,
5309 ELM_CHECK_WIDTYPE(obj, widtype);
5310 Widget_Data *wd = elm_widget_data_get(obj);
5312 if (wd->mode == mode) return;
5314 if (wd->mode == ELM_LIST_COMPRESS)
5315 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5321 elm_genlist_mode_get(const Evas_Object *obj)
5323 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5324 Widget_Data *wd = elm_widget_data_get(obj);
5325 if (!wd) return ELM_LIST_LAST;
5330 elm_genlist_bounce_set(Evas_Object *obj,
5334 ELM_CHECK_WIDTYPE(obj, widtype);
5335 Widget_Data *wd = elm_widget_data_get(obj);
5337 wd->h_bounce = !!h_bounce;
5338 wd->v_bounce = !!v_bounce;
5339 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5343 elm_genlist_bounce_get(const Evas_Object *obj,
5344 Eina_Bool *h_bounce,
5345 Eina_Bool *v_bounce)
5347 ELM_CHECK_WIDTYPE(obj, widtype);
5348 Widget_Data *wd = elm_widget_data_get(obj);
5350 if (h_bounce) *h_bounce = wd->h_bounce;
5351 if (v_bounce) *v_bounce = wd->v_bounce;
5355 elm_genlist_homogeneous_set(Evas_Object *obj,
5356 Eina_Bool homogeneous)
5358 ELM_CHECK_WIDTYPE(obj, widtype);
5359 Widget_Data *wd = elm_widget_data_get(obj);
5361 wd->homogeneous = !!homogeneous;
5365 elm_genlist_homogeneous_get(const Evas_Object *obj)
5367 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5368 Widget_Data *wd = elm_widget_data_get(obj);
5369 if (!wd) return EINA_FALSE;
5370 return wd->homogeneous;
5374 elm_genlist_block_count_set(Evas_Object *obj,
5377 ELM_CHECK_WIDTYPE(obj, widtype);
5378 Widget_Data *wd = elm_widget_data_get(obj);
5380 wd->max_items_per_block = count;
5381 wd->item_cache_max = wd->max_items_per_block * 2;
5382 _item_cache_clean(wd);
5386 elm_genlist_block_count_get(const Evas_Object *obj)
5388 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5389 Widget_Data *wd = elm_widget_data_get(obj);
5391 return wd->max_items_per_block;
5395 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5398 ELM_CHECK_WIDTYPE(obj, widtype);
5399 Widget_Data *wd = elm_widget_data_get(obj);
5401 wd->longpress_timeout = timeout;
5405 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5407 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5408 Widget_Data *wd = elm_widget_data_get(obj);
5410 return wd->longpress_timeout;
5414 elm_genlist_scroller_policy_set(Evas_Object *obj,
5415 Elm_Scroller_Policy policy_h,
5416 Elm_Scroller_Policy policy_v)
5418 ELM_CHECK_WIDTYPE(obj, widtype);
5419 Widget_Data *wd = elm_widget_data_get(obj);
5420 if ((!wd) || (!wd->scr)) return;
5421 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5422 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5424 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5428 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5429 Elm_Scroller_Policy *policy_h,
5430 Elm_Scroller_Policy *policy_v)
5432 ELM_CHECK_WIDTYPE(obj, widtype);
5433 Widget_Data *wd = elm_widget_data_get(obj);
5434 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5435 if ((!wd) || (!wd->scr)) return;
5436 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5437 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5438 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5442 elm_genlist_realized_items_update(Evas_Object *obj)
5444 ELM_CHECK_WIDTYPE(obj, widtype);
5446 Eina_List *list, *l;
5447 Elm_Object_Item *it;
5449 list = elm_genlist_realized_items_get(obj);
5450 EINA_LIST_FOREACH(list, l, it)
5451 elm_genlist_item_update(it);
5455 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5456 const char *decorate_it_type,
5457 Eina_Bool decorate_it_set)
5459 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5460 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5462 Widget_Data *wd = _it->wd;
5464 Elm_Object_Item *it2;
5467 if (!decorate_it_type) return;
5468 if ((_it->generation < _it->wd->generation) ||
5469 elm_widget_item_disabled_get(_it)) return;
5470 if (wd->decorate_all_mode) return;
5472 if ((wd->mode_item == _it) &&
5473 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5476 if (!_it->itc->decorate_item_style) return;
5477 _it->decorate_it_set = decorate_it_set;
5481 EINA_LIST_FOREACH(wd->selected, l, it2)
5482 if (((Elm_Gen_Item *)it2)->realized)
5483 elm_genlist_item_selected_set(it2, EINA_FALSE);
5487 it2 = elm_genlist_selected_item_get(wd->obj);
5488 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5489 elm_genlist_item_selected_set(it2, EINA_FALSE);
5492 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5493 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5494 _decorate_item_unset(wd);
5496 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5497 if (decorate_it_set) _decorate_item_set(_it);
5501 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5503 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5504 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5505 return _it->wd->decorate_it_type;
5508 EAPI const Elm_Object_Item *
5509 elm_genlist_decorated_item_get(const Evas_Object *obj)
5511 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5512 Widget_Data *wd = elm_widget_data_get(obj);
5513 if (!wd) return NULL;
5514 return (Elm_Object_Item *) wd->mode_item;
5518 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5520 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5521 Widget_Data *wd = elm_widget_data_get(obj);
5522 if (!wd) return EINA_FALSE;
5524 return wd->decorate_all_mode;
5528 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5530 ELM_CHECK_WIDTYPE(obj, widtype);
5531 Eina_List *list, *l;
5534 Widget_Data *wd = elm_widget_data_get(obj);
5536 decorated = !!decorated;
5537 if (wd->decorate_all_mode == decorated) return;
5538 wd->decorate_all_mode = decorated;
5540 list = elm_genlist_realized_items_get(obj);
5541 if (!wd->decorate_all_mode)
5543 EINA_LIST_FOREACH(list, l, it)
5545 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5546 _decorate_all_item_unrealize(it);
5548 _item_cache_zero(wd);
5552 EINA_LIST_FOREACH(list, l, it)
5554 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5556 if (it->itc->decorate_all_item_style)
5557 _decorate_all_item_realize(it, EINA_TRUE);
5561 if (wd->calc_job) ecore_job_del(wd->calc_job);
5562 wd->calc_job = ecore_job_add(_calc_job, wd);
5566 elm_genlist_reorder_mode_set(Evas_Object *obj,
5567 Eina_Bool reorder_mode)
5569 ELM_CHECK_WIDTYPE(obj, widtype);
5570 Widget_Data *wd = elm_widget_data_get(obj);
5572 wd->reorder_mode = !!reorder_mode;
5576 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5578 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5579 Widget_Data *wd = elm_widget_data_get(obj);
5580 if (!wd) return EINA_FALSE;
5581 return wd->reorder_mode;
5584 EAPI Elm_Genlist_Item_Type
5585 elm_genlist_item_type_get(const Elm_Object_Item *it)
5587 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5588 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5589 return _it->item->type;
5592 EAPI Elm_Genlist_Item_Class *
5593 elm_genlist_item_class_new(void)
5595 Elm_Genlist_Item_Class *itc;
5597 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5600 itc->version = CLASS_ALLOCATED;
5602 itc->delete_me = EINA_FALSE;
5608 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5610 if (itc && (itc->version == CLASS_ALLOCATED))
5612 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5613 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5623 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5625 if (itc && (itc->version == CLASS_ALLOCATED))
5628 if (itc->refcount == 0) itc->refcount--;
5633 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5635 if (itc && (itc->version == CLASS_ALLOCATED))
5637 if (itc->refcount > 0) itc->refcount--;
5638 if (itc->delete_me && (!itc->refcount))
5639 elm_genlist_item_class_free(itc);
5643 void _flip_job(void *data)
5645 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
5646 _item_unhighlight(it);
5648 _elm_genlist_item_unrealize(it, EINA_FALSE);
5649 it->flipped = EINA_TRUE;
5650 it->item->nocache = EINA_TRUE;
5651 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5652 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
5656 elm_genlist_item_flip_set(Elm_Object_Item *it,
5659 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5660 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5663 if (_it->flipped == flip) return;
5667 ecore_job_add(_flip_job, _it);
5671 _it->flipped = flip;
5672 _item_cache_zero(_it->wd);
5673 elm_genlist_item_update(it);
5674 _it->item->nocache = EINA_FALSE;
5679 elm_genlist_item_flip_get(const Elm_Object_Item *it)
5681 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5682 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5683 return _it->flipped;
5687 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
5689 ELM_CHECK_WIDTYPE(obj, widtype);
5690 Widget_Data *wd = elm_widget_data_get(obj);
5692 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5694 if (wd->select_mode != mode)
5695 wd->select_mode = mode;
5698 EAPI Elm_Object_Select_Mode
5699 elm_genlist_select_mode_get(const Evas_Object *obj)
5701 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
5702 Widget_Data *wd = elm_widget_data_get(obj);
5703 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
5704 return wd->select_mode;
5708 elm_genlist_highlight_mode_set(Evas_Object *obj,
5709 Eina_Bool highlight)
5711 ELM_CHECK_WIDTYPE(obj, widtype);
5712 Widget_Data *wd = elm_widget_data_get(obj);
5714 wd->highlight = !!highlight;
5718 elm_genlist_highlight_mode_get(const Evas_Object *obj)
5720 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5721 Widget_Data *wd = elm_widget_data_get(obj);
5722 if (!wd) return EINA_FALSE;
5723 return wd->highlight;
5727 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
5728 Elm_Object_Select_Mode mode)
5730 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5731 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5733 if (_it->generation < _it->wd->generation) return;
5734 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5736 if (_it->select_mode != mode)
5737 _it->select_mode = mode;
5739 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5741 _it->item->mincalcd = EINA_FALSE;
5742 _it->item->updateme = EINA_TRUE;
5743 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
5744 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5745 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5749 EAPI Elm_Object_Select_Mode
5750 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
5752 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
5753 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5754 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
5755 return _it->select_mode;
5758 /* for gengrid as of now */
5760 _elm_genlist_page_relative_set(Evas_Object *obj,
5764 Evas_Coord pagesize_h;
5765 Evas_Coord pagesize_v;
5767 ELM_CHECK_WIDTYPE(obj, widtype);
5768 Widget_Data *wd = elm_widget_data_get(obj);
5771 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5772 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5776 /* for gengrid as of now */
5778 _elm_genlist_page_relative_get(const Evas_Object *obj,
5782 ELM_CHECK_WIDTYPE(obj, widtype);
5783 Widget_Data *wd = elm_widget_data_get(obj);
5786 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5789 /* for gengrid as of now */
5791 _elm_genlist_page_size_set(Evas_Object *obj,
5792 Evas_Coord h_pagesize,
5793 Evas_Coord v_pagesize)
5798 ELM_CHECK_WIDTYPE(obj, widtype);
5799 Widget_Data *wd = elm_widget_data_get(obj);
5801 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5802 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5806 /* for gengrid as of now */
5808 _elm_genlist_current_page_get(const Evas_Object *obj,
5812 ELM_CHECK_WIDTYPE(obj, widtype);
5813 Widget_Data *wd = elm_widget_data_get(obj);
5815 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5818 /* for gengrid as of now */
5820 _elm_genlist_last_page_get(const Evas_Object *obj,
5824 ELM_CHECK_WIDTYPE(obj, widtype);
5825 Widget_Data *wd = elm_widget_data_get(obj);
5827 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5830 /* for gengrid as of now */
5832 _elm_genlist_page_show(const Evas_Object *obj,
5836 ELM_CHECK_WIDTYPE(obj, widtype);
5837 Widget_Data *wd = elm_widget_data_get(obj);
5839 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5842 /* for gengrid as of now */
5844 _elm_genlist_page_bring_in(const Evas_Object *obj,
5848 ELM_CHECK_WIDTYPE(obj, widtype);
5849 Widget_Data *wd = elm_widget_data_get(obj);
5851 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5855 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5858 Evas_Object *content;
5860 if (!it->realized) return;
5861 if (it->wd->reorder_it == it) return;
5863 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5865 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5868 ecore_timer_del(it->long_timer);
5869 it->long_timer = NULL;
5872 elm_widget_stringlist_free(it->texts);
5874 elm_widget_stringlist_free(it->contents);
5875 it->contents = NULL;
5876 elm_widget_stringlist_free(it->states);
5878 EINA_LIST_FREE(it->content_objs, content)
5879 evas_object_del(content);
5881 elm_widget_stringlist_free(it->item->flip_contents);
5882 it->item->flip_contents = NULL;
5883 EINA_LIST_FREE(it->item->flip_content_objs, content)
5884 evas_object_del(content);
5886 it->unrealize_cb(it);
5888 it->realized = EINA_FALSE;
5889 it->want_unrealize = EINA_FALSE;
5890 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5891 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5895 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5897 elm_widget_item_pre_notify_del(it);
5898 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5900 if ((it->relcount > 0) || (it->walking > 0)) return;
5902 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5904 if (it->itc->func.del)
5905 it->itc->func.del((void *)it->base.data, WIDGET(it));
5909 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5911 _elm_genlist_item_del_notserious(it);
5912 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5913 if (it->tooltip.del_cb)
5914 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5915 it->wd->walking -= it->walking;
5918 ecore_timer_del(it->long_timer);
5919 it->long_timer = NULL;
5922 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5926 eina_inlist_sorted_state_free(it->wd->state);
5927 it->wd->state = NULL;
5929 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5930 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5934 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
5935 it->wd->last_selected_item = NULL;
5936 it->wd->item_count--;
5940 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
5942 ELM_CHECK_WIDTYPE(obj, widtype);
5943 Widget_Data *wd = elm_widget_data_get(obj);
5945 wd->tree_effect_enabled = !!enabled;
5949 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
5951 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5952 Widget_Data *wd = elm_widget_data_get(obj);
5953 if (!wd) return EINA_FALSE;
5954 return wd->tree_effect_enabled;
5958 _create_tray_alpha_bg(const Evas_Object *obj)
5960 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5961 Widget_Data *wd = elm_widget_data_get(obj);
5962 if (!wd) return NULL;
5964 Evas_Object *bg = NULL;
5965 Evas_Coord ox, oy, ow, oh;
5967 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5968 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
5969 evas_object_color_set(bg,0,0,0,0);
5970 evas_object_resize(bg , ow, oh);
5971 evas_object_move(bg , ox, oy);
5976 _item_contract_emit(Elm_Gen_Item *it)
5981 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
5982 it->item->tree_effect_finished = EINA_FALSE;
5984 EINA_LIST_FOREACH(it->item->items, l, it2)
5985 if (it2) _item_contract_emit(it2);
5989 _item_tree_effect_before(Elm_Gen_Item *it)
5994 EINA_LIST_FOREACH(it->item->items, l, it2)
5996 if (it2->parent && (it == it2->parent))
5999 it2->item->tree_effect_hideme = EINA_TRUE;
6000 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6001 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6002 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6003 _item_contract_emit(it2);
6006 return ECORE_CALLBACK_CANCEL;
6010 _item_tree_effect(Widget_Data *wd, int y)
6012 Elm_Gen_Item *it = NULL, *expanded_next_it;
6014 expanded_next_it = wd->expanded_next_item;
6016 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6018 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6021 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6022 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6023 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6025 if (!it->item->tree_effect_finished)
6027 edje_object_signal_emit(VIEW(it), "flip_item", "");
6028 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6029 it->item->tree_effect_finished = EINA_TRUE;
6032 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6035 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6037 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6040 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6041 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6043 if (!it->item->tree_effect_finished)
6045 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6046 it->item->tree_effect_finished = EINA_TRUE;
6051 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6057 _item_tree_effect_finish(Widget_Data *wd)
6059 Elm_Gen_Item *it = NULL;
6062 if (wd->tree_effect_animator)
6064 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6065 _item_subitems_clear(wd->expanded_item);
6066 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6068 it->item->tree_effect_finished = EINA_TRUE;
6069 it->item->old_scrl_y = it->item->scrl_y;
6070 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6071 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6074 _item_auto_scroll(wd);
6075 evas_object_lower(wd->alpha_bg);
6076 evas_object_hide(wd->alpha_bg);
6077 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6078 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6080 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6081 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6082 evas_object_smart_changed(wd->pan_smart);
6084 wd->tree_effect_animator = NULL;
6088 _tree_effect_animator_cb(void *data)
6090 Widget_Data *wd = data;
6091 if (!wd) return EINA_FALSE;
6092 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6093 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6095 double effect_duration = 0.3, t;
6096 int y = 0, dy = 0, dh = 0;
6097 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6100 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6101 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6102 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6103 if (t > effect_duration) end = EINA_TRUE;
6105 // Below while statement is needed, when the genlist is resized.
6106 it2 = wd->expanded_item;
6109 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6110 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6111 cvx, cvy, cvw, cvh));
6112 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6115 if (wd->expanded_next_item)
6117 expanded_next_it = wd->expanded_next_item;
6120 EINA_LIST_FOREACH(wd->move_items, l, it)
6122 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6124 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6125 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6126 expanded_next_it->item->scrl_y = cvy + cvh;
6128 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6129 cvy + cvh : expanded_next_it->item->scrl_y) -
6130 expanded_next_it->item->old_scrl_y;
6132 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6134 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6135 expanded_next_it->item->old_scrl_y = cvy + cvh;
6137 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6139 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6141 expanded_next_it->item->old_scrl_y = cvy + cvh;
6145 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6146 expanded_next_it->item->old_scrl_y;
6150 if (t <= effect_duration)
6152 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6162 _item_realize(it, in, 0);
6166 if (it != expanded_next_it)
6168 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6172 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6173 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6176 _item_tree_effect(wd, y);
6180 int expanded_item_num = 0;
6183 if (wd->expanded_item)
6184 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6189 expanded_item_num++;
6190 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6196 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6197 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6199 if (!it->item->tree_effect_finished)
6201 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6203 edje_object_signal_emit(VIEW(it), "flip_item", "");
6204 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6205 it->item->tree_effect_finished = EINA_TRUE;
6209 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6215 _item_tree_effect_finish(wd);
6216 return ECORE_CALLBACK_CANCEL;
6218 return ECORE_CALLBACK_RENEW;