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;
3031 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3032 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
3037 _pan_calculate(Evas_Object *obj)
3039 Pan *sd = evas_object_smart_data_get(obj);
3041 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3047 evas_event_freeze(evas_object_evas_get(obj));
3049 if (sd->wd->pan_changed)
3052 sd->wd->pan_changed = EINA_FALSE;
3055 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3056 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3057 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3059 git->item->want_realize = EINA_FALSE;
3062 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3064 if (!sd->wd->tree_effect_animator)
3066 _item_tree_effect_before(sd->wd->expanded_item);
3067 evas_object_raise(sd->wd->alpha_bg);
3068 evas_object_show(sd->wd->alpha_bg);
3069 sd->wd->start_time = ecore_time_get();
3070 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3074 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3076 itb->w = sd->wd->minw;
3077 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3078 itb->y - sd->wd->pan_y + oy,
3080 cvx, cvy, cvw, cvh))
3082 if ((!itb->realized) || (itb->changed))
3083 _item_block_realize(itb);
3084 _item_block_position(itb, in);
3088 if (itb->realized) _item_block_unrealize(itb);
3092 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3093 _group_items_recalc(sd->wd);
3094 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3096 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3097 sd->wd->reorder_pan_move = EINA_TRUE;
3098 else sd->wd->reorder_pan_move = EINA_FALSE;
3099 evas_object_raise(sd->wd->VIEW(reorder_it));
3100 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3101 sd->wd->start_time = ecore_loop_time_get();
3104 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3105 _item_auto_scroll(sd->wd);
3107 evas_event_thaw(evas_object_evas_get(obj));
3108 evas_event_thaw_eval(evas_object_evas_get(obj));
3112 _pan_move(Evas_Object *obj,
3113 Evas_Coord x __UNUSED__,
3114 Evas_Coord y __UNUSED__)
3116 Pan *sd = evas_object_smart_data_get(obj);
3120 sd->wd->pan_changed = EINA_TRUE;
3121 evas_object_smart_changed(obj);
3122 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3123 sd->wd->calc_job = NULL;
3127 _hold_on(void *data __UNUSED__,
3129 void *event_info __UNUSED__)
3131 Widget_Data *wd = elm_widget_data_get(obj);
3133 elm_smart_scroller_hold_set(wd->scr, 1);
3137 _hold_off(void *data __UNUSED__,
3139 void *event_info __UNUSED__)
3141 Widget_Data *wd = elm_widget_data_get(obj);
3143 elm_smart_scroller_hold_set(wd->scr, 0);
3147 _freeze_on(void *data __UNUSED__,
3149 void *event_info __UNUSED__)
3151 Widget_Data *wd = elm_widget_data_get(obj);
3153 elm_smart_scroller_freeze_set(wd->scr, 1);
3157 _freeze_off(void *data __UNUSED__,
3159 void *event_info __UNUSED__)
3161 Widget_Data *wd = elm_widget_data_get(obj);
3163 elm_smart_scroller_freeze_set(wd->scr, 0);
3167 _scr_anim_start(void *data,
3168 Evas_Object *obj __UNUSED__,
3169 void *event_info __UNUSED__)
3171 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3175 _scr_anim_stop(void *data,
3176 Evas_Object *obj __UNUSED__,
3177 void *event_info __UNUSED__)
3179 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3183 _scr_drag_start(void *data,
3184 Evas_Object *obj __UNUSED__,
3185 void *event_info __UNUSED__)
3187 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3191 _scr_drag_stop(void *data,
3192 Evas_Object *obj __UNUSED__,
3193 void *event_info __UNUSED__)
3195 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3199 _edge_left(void *data,
3200 Evas_Object *scr __UNUSED__,
3201 void *event_info __UNUSED__)
3203 Evas_Object *obj = data;
3204 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3208 _edge_right(void *data,
3209 Evas_Object *scr __UNUSED__,
3210 void *event_info __UNUSED__)
3212 Evas_Object *obj = data;
3213 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3217 _edge_top(void *data,
3218 Evas_Object *scr __UNUSED__,
3219 void *event_info __UNUSED__)
3221 Evas_Object *obj = data;
3222 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3226 _edge_bottom(void *data,
3227 Evas_Object *scr __UNUSED__,
3228 void *event_info __UNUSED__)
3230 Evas_Object *obj = data;
3231 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3235 _decorate_item_realize(Elm_Gen_Item *it)
3239 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3241 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3242 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3243 edje_object_scale_set(it->item->deco_it_view,
3244 elm_widget_scale_get(WIDGET(it)) *
3245 _elm_config->scale);
3246 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3247 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3249 strncpy(buf, "item", sizeof(buf));
3250 if (it->wd->mode == ELM_LIST_COMPRESS)
3251 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3253 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3254 strncat(buf, "/", sizeof(buf) - strlen(buf));
3255 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3257 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3258 elm_widget_style_get(WIDGET(it)));
3259 edje_object_mirrored_set(it->item->deco_it_view,
3260 elm_widget_mirrored_get(WIDGET(it)));
3262 /* signal callback add */
3263 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3265 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3267 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3270 /* text_get, content_get, state_get */
3271 /* FIXME: If you see that assert, please notify us and we
3272 will clean our mess */
3273 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3275 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3276 if (!it->item->deco_it_contents)
3277 it->item->deco_it_contents =
3278 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3279 it->item->deco_it_content_objs =
3280 _item_mode_content_realize(it, it->item->deco_it_view,
3281 &it->item->deco_it_contents, NULL,
3282 &it->item->deco_it_content_objs);
3283 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3284 edje_object_part_swallow(it->item->deco_it_view,
3285 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3288 it->want_unrealize = EINA_FALSE;
3289 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3290 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3294 _decorate_item_unrealize(Elm_Gen_Item *it)
3296 Widget_Data *wd = it->wd;
3297 Evas_Object *content;
3298 if (!it->item->deco_it_view) return;
3300 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3301 elm_widget_stringlist_free(it->item->deco_it_texts);
3302 it->item->deco_it_texts = NULL;
3303 elm_widget_stringlist_free(it->item->deco_it_contents);
3304 it->item->deco_it_contents = NULL;
3305 elm_widget_stringlist_free(it->item->deco_it_states);
3307 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3308 evas_object_del(content);
3310 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3311 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3312 evas_object_del(it->item->deco_it_view);
3313 it->item->deco_it_view = NULL;
3315 if (wd->mode_item == it)
3316 wd->mode_item = NULL;
3317 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3318 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3322 _decorate_item_set(Elm_Gen_Item *it)
3325 Widget_Data *wd = it->wd;
3330 it->item->nocache_once = EINA_TRUE;
3332 if (wd->scr_hold_timer)
3334 ecore_timer_del(wd->scr_hold_timer);
3335 wd->scr_hold_timer = NULL;
3337 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3338 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3340 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3341 _decorate_item_realize(it);
3342 if (it->item->group_item)
3343 evas_object_raise(it->item->VIEW(group_item));
3344 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3345 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3346 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3348 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3349 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3353 _decorate_item_unset(Widget_Data *wd)
3356 if (!wd->mode_item) return;
3357 char buf[1024], buf2[1024];
3361 it->item->nocache_once = EINA_TRUE;
3363 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3364 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3366 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3367 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3369 wd->mode_item = NULL;
3373 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3375 if ((!it) || (!it->wd->decorate_all_mode)) return;
3376 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3377 evas_object_move(it->deco_all_view, itx, ity);
3381 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3384 const char *stacking_even;
3385 const char *stacking;
3387 if ((!it) || (it->item->decorate_all_item_realized) ||
3388 (it->generation < it->wd->generation))
3391 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3392 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3393 _elm_config->scale);
3394 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3395 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3397 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3398 strncpy(buf, "tree", sizeof(buf));
3399 else strncpy(buf, "item", sizeof(buf));
3400 if (it->wd->mode == ELM_LIST_COMPRESS)
3401 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3403 strncat(buf, "/", sizeof(buf) - strlen(buf));
3404 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3406 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3407 elm_widget_style_get(WIDGET(it)));
3409 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3410 if (!stacking_even) stacking_even = "above";
3411 it->item->stacking_even = !!strcmp("above", stacking_even);
3413 stacking = edje_object_data_get(VIEW(it), "stacking");
3414 if (!stacking) stacking = "yes";
3415 it->item->nostacking = !!strcmp("yes", stacking);
3417 edje_object_mirrored_set(it->deco_all_view,
3418 elm_widget_mirrored_get(WIDGET(it)));
3420 _elm_genlist_item_odd_even_update(it);
3421 _elm_genlist_item_state_update(it, NULL);
3423 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3424 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3426 _item_mouse_callbacks_del(it, VIEW(it));
3427 _item_mouse_callbacks_add(it, it->deco_all_view);
3429 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3430 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3431 if (!it->item->deco_all_contents)
3432 it->item->deco_all_contents =
3433 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "contents"));
3434 it->item->deco_all_content_objs =
3435 _item_mode_content_realize(it, it->deco_all_view,
3436 &it->item->deco_all_contents, NULL,
3437 &it->item->deco_all_content_objs);
3438 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3439 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3441 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3442 evas_object_show(it->deco_all_view);
3444 it->item->decorate_all_item_realized = EINA_TRUE;
3445 it->want_unrealize = EINA_FALSE;
3449 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3452 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3454 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3455 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3456 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3457 _elm_genlist_item_odd_even_update(it);
3458 _elm_genlist_item_state_update(it, NULL);
3460 evas_object_del(it->deco_all_view);
3461 it->deco_all_view = NULL;
3462 elm_widget_stringlist_free(it->item->deco_all_texts);
3463 it->item->deco_all_texts = NULL;
3464 elm_widget_stringlist_free(it->item->deco_all_contents);
3465 it->item->deco_all_contents = NULL;
3466 elm_widget_stringlist_free(it->item->deco_all_states);
3467 it->item->deco_all_states = NULL;
3468 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3469 evas_object_del(icon);
3470 edje_object_message_signal_process(it->deco_all_view);
3471 _item_mouse_callbacks_del(it, it->deco_all_view);
3472 _item_mouse_callbacks_add(it, VIEW(it));
3474 it->item->decorate_all_item_realized = EINA_FALSE;
3478 _item_auto_scroll(Widget_Data *wd)
3481 Elm_Gen_Item *tmp_item = NULL;
3483 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3485 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3486 if (!tmp_item) return;
3487 wd->show_item = tmp_item;
3488 wd->bring_in = EINA_TRUE;
3489 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3490 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3492 wd->show_item->item->showme = EINA_TRUE;
3493 wd->auto_scroll_enabled = EINA_FALSE;
3501 elm_genlist_add(Evas_Object *parent)
3506 Evas_Coord minw, minh;
3507 static Evas_Smart *smart = NULL;
3511 static Evas_Smart_Class sc;
3513 evas_object_smart_clipped_smart_set(&_pan_sc);
3515 sc.name = "elm_genlist_pan";
3516 sc.version = EVAS_SMART_CLASS_VERSION;
3519 sc.resize = _pan_resize;
3520 sc.move = _pan_move;
3521 sc.calculate = _pan_calculate;
3522 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3525 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3527 ELM_SET_WIDTYPE(widtype, "genlist");
3529 elm_widget_type_set(obj, "genlist");
3530 elm_widget_sub_object_add(parent, obj);
3531 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3532 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3533 elm_widget_data_set(obj, wd);
3534 elm_widget_del_hook_set(obj, _del_hook);
3535 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3536 elm_widget_theme_hook_set(obj, _theme_hook);
3537 elm_widget_can_focus_set(obj, EINA_TRUE);
3538 elm_widget_event_hook_set(obj, _event_hook);
3539 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3540 elm_widget_translate_hook_set(obj, _translate_hook);
3543 wd->scr = elm_smart_scroller_add(e);
3544 elm_smart_scroller_widget_set(wd->scr, obj);
3545 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3546 elm_widget_style_get(obj));
3547 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3548 _elm_config->thumbscroll_bounce_enable);
3549 elm_widget_resize_object_set(obj, wd->scr);
3551 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3552 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3553 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3554 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3555 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3556 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3557 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3558 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3561 wd->mode = ELM_LIST_SCROLL;
3562 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3563 wd->item_cache_max = wd->max_items_per_block * 2;
3564 wd->longpress_timeout = _elm_config->longpress_timeout;
3565 wd->highlight = EINA_TRUE;
3567 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3568 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3569 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3570 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3572 wd->pan_smart = evas_object_smart_add(e, smart);
3573 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3576 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3577 _pan_set, _pan_get, _pan_max_get,
3578 _pan_min_get, _pan_child_size_get);
3580 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3582 evas_object_size_hint_min_set(obj, minw, minh);
3584 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3586 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3592 _item_select(Elm_Gen_Item *it)
3594 Evas_Object *obj = WIDGET(it);
3596 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3597 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3598 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3602 it->selected = EINA_TRUE;
3603 it->wd->selected = eina_list_append(it->wd->selected, it);
3605 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3607 evas_object_ref(obj);
3610 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3611 if (it->generation == it->wd->generation)
3612 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3615 if ((it->wd->clear_me) && (!it->wd->walking))
3616 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3619 if ((!it->walking) && (it->generation < it->wd->generation))
3624 elm_widget_item_free(it);
3628 it->wd->last_selected_item = (Elm_Object_Item *)it;
3630 evas_object_unref(obj);
3633 static Evas_Object *
3634 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3636 return edje_object_part_swallow_get(VIEW(it), part);
3640 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
3642 if (!it->itc->func.text_get) return NULL;
3643 return edje_object_part_text_get(VIEW(it), part);
3647 _item_disable_hook(Elm_Object_Item *it)
3651 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3653 if (_it->generation < _it->wd->generation) return;
3656 elm_genlist_item_selected_set(it, EINA_FALSE);
3660 if (elm_widget_item_disabled_get(it))
3662 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
3663 if (_it->deco_all_view)
3664 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
3668 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
3669 if (_it->deco_all_view)
3670 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
3672 EINA_LIST_FOREACH(_it->content_objs, l, obj)
3673 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
3678 _item_del_pre_hook(Elm_Object_Item *it)
3680 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3682 if ((_it->relcount > 0) || (_it->walking > 0))
3684 elm_genlist_item_subitems_clear(it);
3685 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
3686 _elm_genlist_item_del_notserious(_it);
3687 if (_it->item->block)
3689 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
3690 _it->item->block->changed = EINA_TRUE;
3691 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
3692 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
3696 _it->parent->item->items =
3697 eina_list_remove(_it->parent->item->items, it);
3707 _item_signal_emit_hook(Elm_Object_Item *it,
3708 const char *emission,
3711 edje_object_signal_emit(VIEW(it), emission, source);
3715 _elm_genlist_item_new(Widget_Data *wd,
3716 const Elm_Gen_Item_Class *itc,
3718 Elm_Gen_Item *parent,
3720 const void *func_data)
3724 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3725 if (!it) return NULL;
3727 it->generation = wd->generation;
3729 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
3730 it->base.data = data;
3731 it->parent = parent;
3732 it->func.func = func;
3733 it->func.data = func_data;
3734 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3735 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
3736 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3737 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3738 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
3741 it->sel_cb = (Ecore_Cb)_item_select;
3746 static Elm_Gen_Item *
3747 _item_new(Widget_Data *wd,
3748 const Elm_Genlist_Item_Class *itc,
3750 Elm_Gen_Item *parent,
3751 Elm_Genlist_Item_Type type,
3753 const void *func_data)
3755 Elm_Gen_Item *it, *it2;
3758 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3759 if (!it) return NULL;
3760 it->item = ELM_NEW(Elm_Gen_Item_Type);
3761 it->item->type = type;
3762 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
3763 it->item->expanded_depth = 0;
3764 ELM_GEN_ITEM_SETUP(it);
3767 if (it->parent->group)
3768 it->item->group_item = parent;
3769 else if (it->parent->item->group_item)
3770 it->item->group_item = it->parent->item->group_item;
3772 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3774 if (!it2->parent->group) depth += 1;
3776 it->item->expanded_depth = depth;
3782 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3786 itb = calloc(1, sizeof(Item_Block));
3787 if (!itb) return NULL;
3791 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3792 _item_block_position_update(wd->blocks, 0);
3796 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3797 itb->position_update = EINA_TRUE;
3798 if (wd->blocks != EINA_INLIST_GET(itb))
3800 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3811 _item_block_add(Widget_Data *wd,
3814 Item_Block *itb = NULL;
3821 itb = calloc(1, sizeof(Item_Block));
3822 if (!itb) return EINA_FALSE;
3824 if (!it->item->rel->item->block)
3827 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3828 itb->items = eina_list_append(itb->items, it);
3829 itb->position_update = EINA_TRUE;
3830 it->position = eina_list_count(itb->items);
3831 it->position_update = EINA_TRUE;
3833 if (wd->blocks != EINA_INLIST_GET(itb))
3835 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3846 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3847 if (it->item->before)
3849 wd->blocks = eina_inlist_prepend_relative
3850 (wd->blocks, EINA_INLIST_GET(itb),
3851 EINA_INLIST_GET(it->item->rel->item->block));
3853 eina_list_prepend_relative_list(itb->items, it, tmp);
3855 /* Update index from where we prepended */
3856 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3857 _item_block_position_update(EINA_INLIST_GET(itb),
3858 it->item->rel->item->block->position);
3862 wd->blocks = eina_inlist_append_relative
3863 (wd->blocks, EINA_INLIST_GET(itb),
3864 EINA_INLIST_GET(it->item->rel->item->block));
3866 eina_list_append_relative_list(itb->items, it, tmp);
3868 /* Update block index from where we appended */
3869 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3870 _item_block_position_update(EINA_INLIST_GET(itb),
3871 it->item->rel->item->block->position + 1);
3877 if (it->item->before)
3881 itb = (Item_Block *)(wd->blocks);
3882 if (itb->count >= wd->max_items_per_block)
3884 itb = _item_block_new(wd, EINA_TRUE);
3885 if (!itb) return EINA_FALSE;
3890 itb = _item_block_new(wd, EINA_TRUE);
3891 if (!itb) return EINA_FALSE;
3893 itb->items = eina_list_prepend(itb->items, it);
3895 _item_position_update(itb->items, 0);
3901 itb = (Item_Block *)(wd->blocks->last);
3902 if (itb->count >= wd->max_items_per_block)
3904 itb = _item_block_new(wd, EINA_FALSE);
3905 if (!itb) return EINA_FALSE;
3910 itb = _item_block_new(wd, EINA_FALSE);
3911 if (!itb) return EINA_FALSE;
3913 itb->items = eina_list_append(itb->items, it);
3914 it->position = eina_list_count(itb->items);
3922 if (it->item->rel->item->queued)
3924 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3925 on sorted insertion order, so the queue is not always ordered like the item list.
3926 This lead to issue where we depend on an item that is not yet created. As a quick
3927 work around, we reschedule the calc of the item and stop reordering the list to
3928 prevent any nasty issue to show up here.
3930 wd->queue = eina_list_append(wd->queue, it);
3931 wd->requeued = EINA_TRUE;
3932 it->item->queued = EINA_TRUE;
3935 itb = it->item->rel->item->block;
3936 if (!itb) goto newblock;
3937 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3938 if (it->item->before)
3940 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3941 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3945 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3946 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3950 itb->changed = EINA_TRUE;
3951 it->item->block = itb;
3952 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3953 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3956 it->item->rel->relcount--;
3957 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3959 _item_del(it->item->rel);
3960 elm_widget_item_free(it->item->rel);
3962 it->item->rel = NULL;
3964 if (itb->count > itb->wd->max_items_per_block)
3969 Eina_Bool done = EINA_FALSE;
3971 newc = itb->count / 2;
3973 if (EINA_INLIST_GET(itb)->prev)
3975 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3977 if (itbp->count + newc < wd->max_items_per_block / 2)
3979 /* moving items to previous block */
3980 while ((itb->count > newc) && (itb->items))
3982 it2 = eina_list_data_get(itb->items);
3983 itb->items = eina_list_remove_list(itb->items, itb->items);
3986 itbp->items = eina_list_append(itbp->items, it2);
3987 it2->item->block = itbp;
3995 if (!done && EINA_INLIST_GET(itb)->next)
3997 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3999 if (itbn->count + newc < wd->max_items_per_block / 2)
4001 /* moving items to next block */
4002 while ((itb->count > newc) && (itb->items))
4006 l = eina_list_last(itb->items);
4007 it2 = eina_list_data_get(l);
4008 itb->items = eina_list_remove_list(itb->items, l);
4011 itbn->items = eina_list_prepend(itbn->items, it2);
4012 it2->item->block = itbn;
4022 /* moving items to new block */
4023 itb2 = calloc(1, sizeof(Item_Block));
4024 if (!itb2) return EINA_FALSE;
4027 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4028 EINA_INLIST_GET(itb));
4029 itb2->changed = EINA_TRUE;
4030 while ((itb->count > newc) && (itb->items))
4034 l = eina_list_last(itb->items);
4036 itb->items = eina_list_remove_list(itb->items, l);
4039 itb2->items = eina_list_prepend(itb2->items, it2);
4040 it2->item->block = itb2;
4050 _queue_process(Widget_Data *wd)
4053 Eina_Bool showme = EINA_FALSE;
4056 t0 = ecore_loop_time_get();
4057 //evas_event_freeze(evas_object_evas_get(wd->obj));
4058 for (n = 0; (wd->queue) && (n < 128); n++)
4062 it = eina_list_data_get(wd->queue);
4063 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4064 it->item->queued = EINA_FALSE;
4065 if (!_item_block_add(wd, it)) continue;
4067 _item_block_realize(it->item->block);
4068 t = ecore_time_get();
4069 if (it->item->block->changed)
4071 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4072 it->item->block->changed = 0;
4073 if (wd->pan_changed)
4075 if (wd->calc_job) ecore_job_del(wd->calc_job);
4076 wd->calc_job = NULL;
4078 wd->pan_changed = EINA_FALSE;
4081 if (showme) it->item->block->showme = EINA_TRUE;
4082 /* same as eina_inlist_count > 1 */
4083 if (wd->blocks && wd->blocks->next)
4085 if ((t - t0) > (ecore_animator_frametime_get())) break;
4088 //evas_event_thaw(evas_object_evas_get(wd->obj));
4089 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4094 _idle_process(void *data, Eina_Bool *wakeup)
4096 Widget_Data *wd = data;
4099 //static double q_start = 0.0;
4100 //if (q_start == 0.0) q_start = ecore_time_get();
4102 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4106 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4108 return ECORE_CALLBACK_CANCEL;
4110 return ECORE_CALLBACK_RENEW;
4114 _item_idle_enterer(void *data)
4116 Widget_Data *wd = data;
4117 Eina_Bool wakeup = EINA_FALSE;
4118 Eina_Bool ok = _idle_process(data, &wakeup);
4123 if (wd->calc_job) ecore_job_del(wd->calc_job);
4124 wd->calc_job = ecore_job_add(_calc_job, wd);
4126 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4131 _item_queue(Widget_Data *wd,
4135 if (it->item->queued) return;
4136 it->item->queued = EINA_TRUE;
4137 if (cb && !wd->requeued)
4138 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4140 wd->queue = eina_list_append(wd->queue, it);
4141 // FIXME: why does a freeze then thaw here cause some genlist
4142 // elm_genlist_item_append() to be much much slower?
4143 // evas_event_freeze(evas_object_evas_get(wd->obj));
4144 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4146 if (wd->queue_idle_enterer)
4148 ecore_idle_enterer_del(wd->queue_idle_enterer);
4149 wd->queue_idle_enterer = NULL;
4153 // evas_event_thaw(evas_object_evas_get(wd->obj));
4154 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4155 if (!wd->queue_idle_enterer)
4156 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4160 _elm_genlist_item_compare(const void *data, const void *data1)
4162 const Elm_Gen_Item *it, *item1;
4163 it = ELM_GEN_ITEM_FROM_INLIST(data);
4164 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4165 return it->wd->item_compare_cb(it, item1);
4169 _elm_genlist_item_list_compare(const void *data, const void *data1)
4171 const Elm_Gen_Item *it = data;
4172 const Elm_Gen_Item *item1 = data1;
4173 return it->wd->item_compare_cb(it, item1);
4176 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4178 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4183 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4184 _item_block_del(it);
4186 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4187 it->item->rel = after;
4188 it->item->rel->relcount++;
4189 it->item->before = EINA_FALSE;
4190 if (after->item->group_item) it->item->group_item = after->item->group_item;
4191 _item_queue(it->wd, it, NULL);
4193 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4196 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4198 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4201 if (!before) return;
4203 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4204 _item_block_del(it);
4205 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4206 it->item->rel = before;
4207 it->item->rel->relcount++;
4208 it->item->before = EINA_TRUE;
4209 if (before->item->group_item) it->item->group_item = before->item->group_item;
4210 _item_queue(it->wd, it, NULL);
4212 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4216 elm_genlist_items_count(const Evas_Object *obj)
4218 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4219 Widget_Data *wd = elm_widget_data_get(obj);
4221 return wd->item_count;
4224 EAPI Elm_Object_Item *
4225 elm_genlist_item_append(Evas_Object *obj,
4226 const Elm_Genlist_Item_Class *itc,
4228 Elm_Object_Item *parent,
4229 Elm_Genlist_Item_Type type,
4231 const void *func_data)
4233 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4234 Widget_Data *wd = elm_widget_data_get(obj);
4235 if (!wd) return NULL;
4236 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4238 if (!it) return NULL;
4242 wd->group_items = eina_list_append(wd->group_items, it);
4243 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4244 it->item->rel = NULL;
4248 Elm_Gen_Item *it2 = NULL;
4249 Eina_List *ll = eina_list_last(it->parent->item->items);
4250 if (ll) it2 = ll->data;
4251 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4252 if (!it2) it2 = it->parent;
4254 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4255 EINA_INLIST_GET(it2));
4256 it->item->rel = it2;
4257 it->item->rel->relcount++;
4259 it->item->before = EINA_FALSE;
4260 _item_queue(wd, it, NULL);
4261 return (Elm_Object_Item *)it;
4264 EAPI Elm_Object_Item *
4265 elm_genlist_item_prepend(Evas_Object *obj,
4266 const Elm_Genlist_Item_Class *itc,
4268 Elm_Object_Item *parent,
4269 Elm_Genlist_Item_Type type,
4271 const void *func_data)
4273 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4274 Widget_Data *wd = elm_widget_data_get(obj);
4275 if (!wd) return NULL;
4276 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4278 if (!it) return NULL;
4282 wd->group_items = eina_list_prepend(wd->group_items, it);
4283 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4284 it->item->rel = NULL;
4288 Elm_Gen_Item *it2 = NULL;
4289 Eina_List *ll = it->parent->item->items;
4290 if (ll) it2 = ll->data;
4291 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4292 if (!it2) it2 = it->parent;
4294 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4295 EINA_INLIST_GET(it2));
4296 it->item->rel = it2;
4297 it->item->rel->relcount++;
4299 it->item->before = EINA_TRUE;
4300 _item_queue(wd, it, NULL);
4301 return (Elm_Object_Item *)it;
4304 EAPI Elm_Object_Item *
4305 elm_genlist_item_insert_after(Evas_Object *obj,
4306 const Elm_Genlist_Item_Class *itc,
4308 Elm_Object_Item *parent,
4309 Elm_Object_Item *after,
4310 Elm_Genlist_Item_Type type,
4312 const void *func_data)
4314 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4315 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4316 Widget_Data *wd = elm_widget_data_get(obj);
4317 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4318 if (!wd) return NULL;
4319 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4320 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4322 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4324 if (!it) return NULL;
4327 if ((it->group) && (_after->group))
4328 wd->group_items = eina_list_append_relative(wd->group_items, it,
4333 it->parent->item->items =
4334 eina_list_append_relative(it->parent->item->items, it, _after);
4336 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4337 EINA_INLIST_GET(_after));
4338 it->item->rel = _after;
4339 it->item->rel->relcount++;
4340 it->item->before = EINA_FALSE;
4341 _item_queue(wd, it, NULL);
4342 return (Elm_Object_Item *)it;
4345 EAPI Elm_Object_Item *
4346 elm_genlist_item_insert_before(Evas_Object *obj,
4347 const Elm_Genlist_Item_Class *itc,
4349 Elm_Object_Item *parent,
4350 Elm_Object_Item *before,
4351 Elm_Genlist_Item_Type type,
4353 const void *func_data)
4355 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4356 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4357 Widget_Data *wd = elm_widget_data_get(obj);
4358 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4359 if (!wd) return NULL;
4360 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4361 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4363 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4365 if (!it) return NULL;
4368 if (it->group && _before->group)
4369 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4374 it->parent->item->items =
4375 eina_list_prepend_relative(it->parent->item->items, it, _before);
4377 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4378 EINA_INLIST_GET(_before));
4379 it->item->rel = _before;
4380 it->item->rel->relcount++;
4381 it->item->before = EINA_TRUE;
4382 _item_queue(wd, it, NULL);
4383 return (Elm_Object_Item *)it;
4386 EAPI Elm_Object_Item *
4387 elm_genlist_item_sorted_insert(Evas_Object *obj,
4388 const Elm_Genlist_Item_Class *itc,
4390 Elm_Object_Item *parent,
4391 Elm_Genlist_Item_Type type,
4392 Eina_Compare_Cb comp,
4394 const void *func_data)
4396 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4397 Widget_Data *wd = elm_widget_data_get(obj);
4398 if (!wd) return NULL;
4399 Elm_Gen_Item *rel = NULL;
4400 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4402 if (!it) return NULL;
4404 wd->item_compare_cb = comp;
4411 l = eina_list_search_sorted_near_list(it->parent->item->items,
4412 _elm_genlist_item_list_compare,
4416 rel = eina_list_data_get(l);
4420 if (cmp_result >= 0)
4422 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4423 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4424 it->item->before = EINA_FALSE;
4426 else if (cmp_result < 0)
4428 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4429 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4430 it->item->before = EINA_TRUE;
4437 wd->state = eina_inlist_sorted_state_new();
4438 eina_inlist_sorted_state_init(wd->state, wd->items);
4439 wd->requeued = EINA_FALSE;
4443 wd->group_items = eina_list_append(wd->group_items, it);
4445 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4446 _elm_genlist_item_compare, wd->state);
4448 if (EINA_INLIST_GET(it)->next)
4450 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4451 it->item->before = EINA_TRUE;
4453 else if (EINA_INLIST_GET(it)->prev)
4455 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4456 it->item->before = EINA_FALSE;
4462 it->item->rel = rel;
4463 it->item->rel->relcount++;
4466 _item_queue(wd, it, _elm_genlist_item_list_compare);
4468 return (Elm_Object_Item *)it;
4472 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4474 Eina_Inlist *next, *l;
4475 Widget_Data *wd = elm_widget_data_get(obj);
4478 if (!standby) wd->generation++;
4482 eina_inlist_sorted_state_free(wd->state);
4486 if (wd->walking > 0)
4488 wd->clear_me = EINA_TRUE;
4491 evas_event_freeze(evas_object_evas_get(wd->obj));
4492 for (l = wd->items, next = l ? l->next : NULL;
4494 l = next, next = next ? next->next : NULL)
4496 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4498 if (it->generation < wd->generation)
4500 Elm_Gen_Item *itn = NULL;
4502 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4503 if (itn) itn->walking++; /* prevent early death of subitem */
4505 elm_widget_item_free(it);
4506 if (itn) itn->walking--;
4509 wd->clear_me = EINA_FALSE;
4510 wd->pan_changed = EINA_TRUE;
4513 ecore_job_del(wd->calc_job);
4514 wd->calc_job = NULL;
4516 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4517 if (wd->clear_cb) wd->clear_cb(wd);
4523 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4524 wd->alpha_bg = NULL;
4528 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4529 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4531 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4532 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4533 evas_event_thaw(evas_object_evas_get(wd->obj));
4534 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4538 elm_genlist_clear(Evas_Object *obj)
4540 ELM_CHECK_WIDTYPE(obj, widtype);
4541 _elm_genlist_clear(obj, EINA_FALSE);
4545 elm_genlist_multi_select_set(Evas_Object *obj,
4548 ELM_CHECK_WIDTYPE(obj, widtype);
4549 Widget_Data *wd = elm_widget_data_get(obj);
4551 wd->multi = !!multi;
4555 elm_genlist_multi_select_get(const Evas_Object *obj)
4557 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4558 Widget_Data *wd = elm_widget_data_get(obj);
4559 if (!wd) return EINA_FALSE;
4563 EAPI Elm_Object_Item *
4564 elm_genlist_selected_item_get(const Evas_Object *obj)
4566 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4567 Widget_Data *wd = elm_widget_data_get(obj);
4568 if (!wd) return NULL;
4569 if (wd->selected) return wd->selected->data;
4573 EAPI const Eina_List *
4574 elm_genlist_selected_items_get(const Evas_Object *obj)
4576 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4577 Widget_Data *wd = elm_widget_data_get(obj);
4578 if (!wd) return NULL;
4579 return wd->selected;
4583 elm_genlist_realized_items_get(const Evas_Object *obj)
4585 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4586 Widget_Data *wd = elm_widget_data_get(obj);
4587 Eina_List *list = NULL;
4589 Eina_Bool done = EINA_FALSE;
4590 if (!wd) return NULL;
4591 EINA_INLIST_FOREACH(wd->blocks, itb)
4599 EINA_LIST_FOREACH(itb->items, l, it)
4601 if (it->realized) list = eina_list_append(list, it);
4612 EAPI Elm_Object_Item *
4613 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4618 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4619 Widget_Data *wd = elm_widget_data_get(obj);
4620 Evas_Coord ox, oy, ow, oh;
4623 if (!wd) return NULL;
4624 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4626 EINA_INLIST_FOREACH(wd->blocks, itb)
4631 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4632 oy + itb->y - itb->wd->pan_y,
4633 itb->w, itb->h, x, y, 1, 1))
4635 EINA_LIST_FOREACH(itb->items, l, it)
4637 Evas_Coord itx, ity;
4639 itx = ox + itb->x + it->x - itb->wd->pan_x;
4640 ity = oy + itb->y + it->y - itb->wd->pan_y;
4641 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4645 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4646 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4650 return (Elm_Object_Item *)it;
4652 lasty = ity + it->item->h;
4657 if (y > lasty) *posret = 1;
4663 EAPI Elm_Object_Item *
4664 elm_genlist_first_item_get(const Evas_Object *obj)
4666 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4667 Widget_Data *wd = elm_widget_data_get(obj);
4668 if (!wd) return NULL;
4669 if (!wd->items) return NULL;
4670 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4671 while ((it) && (it->generation < wd->generation))
4672 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4673 return (Elm_Object_Item *)it;
4676 EAPI Elm_Object_Item *
4677 elm_genlist_last_item_get(const Evas_Object *obj)
4679 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4680 Widget_Data *wd = elm_widget_data_get(obj);
4681 if (!wd) return NULL;
4682 if (!wd->items) return NULL;
4683 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4684 while ((it) && (it->generation < wd->generation))
4685 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4686 return (Elm_Object_Item *)it;
4689 EAPI Elm_Object_Item *
4690 elm_genlist_item_next_get(const Elm_Object_Item *it)
4692 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4693 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4696 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
4697 if ((_it) && (_it->generation == _it->wd->generation)) break;
4699 return (Elm_Object_Item *) _it;
4702 EAPI Elm_Object_Item *
4703 elm_genlist_item_prev_get(const Elm_Object_Item *it)
4705 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4706 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4709 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
4710 if ((_it) && (_it->generation == _it->wd->generation)) break;
4712 return (Elm_Object_Item *) _it;
4715 EAPI Elm_Object_Item *
4716 elm_genlist_item_parent_get(const Elm_Object_Item *it)
4718 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4719 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
4723 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
4725 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4726 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
4728 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4730 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
4731 _item_subitems_clear(_it);
4734 if (!wd->tree_effect_animator)
4736 wd->expanded_item = _it;
4737 _item_tree_effect_before(_it);
4738 evas_object_raise(wd->alpha_bg);
4739 evas_object_show(wd->alpha_bg);
4740 wd->start_time = ecore_time_get();
4741 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
4744 _item_subitems_clear(_it);
4749 elm_genlist_item_selected_set(Elm_Object_Item *it,
4752 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4753 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4754 Widget_Data *wd = _it->wd;
4756 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
4758 selected = !!selected;
4759 if (_it->selected == selected) return;
4765 while (wd->selected)
4767 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
4768 _it->unsel_cb(wd->selected->data);
4771 _it->highlight_cb(_it);
4775 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
4780 elm_genlist_item_selected_get(const Elm_Object_Item *it)
4782 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4783 return ((Elm_Gen_Item *)it)->selected;
4787 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
4790 if (it->item->expanded)
4792 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4796 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4799 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
4800 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4807 _elm_genlist_move_items_set(Elm_Gen_Item *it)
4810 Elm_Gen_Item *it2 = NULL;
4811 Evas_Coord ox, oy, ow, oh, dh = 0;
4813 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
4815 if (it->item->expanded)
4817 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
4818 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
4820 if (it2 == it->wd->expanded_next_item) break;
4821 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
4826 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
4827 it2 = it->wd->expanded_next_item;
4828 while (it2 && (dh < oy + oh))
4831 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
4832 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4838 elm_genlist_item_expanded_set(Elm_Object_Item *it,
4841 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4842 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4843 expanded = !!expanded;
4844 if (_it->item->expanded == expanded) return;
4845 _it->item->expanded = expanded;
4846 _it->wd->expanded_item = _it;
4847 _elm_genlist_move_items_set(_it);
4849 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
4850 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
4852 if (_it->item->expanded)
4854 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
4856 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
4857 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
4858 _it->wd->auto_scroll_enabled = EINA_TRUE;
4862 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
4864 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
4865 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
4866 _it->wd->auto_scroll_enabled = EINA_FALSE;
4871 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
4873 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4874 return ((Elm_Gen_Item *)it)->item->expanded;
4878 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
4880 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
4881 return ((Elm_Gen_Item *)it)->item->expanded_depth;
4885 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
4886 Elm_Genlist_Item_Scrollto_Type type,
4893 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4894 Evas_Coord gith = 0;
4895 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4896 if ((_it->item->queued) || (!_it->item->mincalcd))
4898 _it->wd->show_item = _it;
4899 _it->wd->bring_in = bring_in;
4900 _it->wd->scrollto_type = type;
4901 _it->item->showme = EINA_TRUE;
4904 if (_it->wd->show_item)
4906 _it->wd->show_item->item->showme = EINA_FALSE;
4907 _it->wd->show_item = NULL;
4910 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
4913 case ELM_GENLIST_ITEM_SCROLLTO_IN:
4914 if ((_it->item->group_item) &&
4915 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4916 gith = _it->item->group_item->item->h;
4918 *y = _it->y + _it->item->block->y - gith;
4920 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
4921 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4922 *y = _it->y + _it->item->block->y - gith;
4924 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
4925 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
4931 *x = _it->x + _it->item->block->x;
4932 *w = _it->item->block->w;
4937 elm_genlist_item_promote(Elm_Object_Item *it)
4939 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4940 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4941 if (_it->generation < _it->wd->generation) return;
4942 _item_move_before(_it,
4943 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
4947 elm_genlist_item_demote(Elm_Object_Item *it)
4949 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4950 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4951 if (_it->generation < _it->wd->generation) return;
4952 _item_move_after(_it,
4953 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
4957 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4959 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4960 Evas_Coord x, y, w, h;
4961 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4963 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
4964 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
4968 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4971 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4972 Evas_Coord x, y, w, h;
4973 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4975 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
4976 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
4980 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
4982 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4984 Evas_Object *content;
4985 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
4987 elm_widget_sub_object_del(WIDGET(it), content);
4988 evas_object_smart_member_del(content);
4989 evas_object_hide(content);
4990 if (l) *l = eina_list_append(*l, content);
4995 elm_genlist_item_update(Elm_Object_Item *it)
4997 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4998 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5000 if (!_it->item->block) return;
5001 if (_it->generation < _it->wd->generation) return;
5002 _it->item->mincalcd = EINA_FALSE;
5003 _it->item->updateme = EINA_TRUE;
5004 _it->item->block->updateme = EINA_TRUE;
5005 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5006 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5010 elm_genlist_item_fields_update(Elm_Object_Item *it,
5012 Elm_Genlist_Item_Field_Type itf)
5014 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5015 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5017 if (!_it->item->block) return;
5018 if (_it->generation < _it->wd->generation) return;
5020 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5021 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5022 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5024 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5025 &_it->contents, parts);
5026 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5027 &_it->contents, parts);
5031 _it->item->flip_content_objs =
5032 _item_mode_content_unrealize(_it, VIEW(_it),
5033 &_it->item->flip_contents, parts,
5034 &_it->item->flip_content_objs);
5035 _it->item->flip_content_objs =
5036 _item_mode_content_realize(_it, VIEW(_it),
5037 &_it->item->flip_contents, parts,
5038 &_it->item->flip_content_objs);
5040 if (_it->item->deco_it_view)
5042 _it->item->deco_it_content_objs =
5043 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5044 &_it->item->deco_it_contents, parts,
5045 &_it->item->deco_it_content_objs);
5046 _it->item->deco_it_content_objs =
5047 _item_mode_content_realize(_it, _it->item->deco_it_view,
5048 &_it->item->deco_it_contents, parts,
5049 &_it->item->deco_it_content_objs);
5051 if (_it->wd->decorate_all_mode)
5053 _it->item->deco_all_content_objs =
5054 _item_mode_content_unrealize(_it, _it->deco_all_view,
5055 &_it->item->deco_all_contents, parts,
5056 &_it->item->deco_all_content_objs);
5057 _it->item->deco_all_content_objs =
5058 _item_mode_content_realize(_it, _it->deco_all_view,
5059 &_it->item->deco_all_contents, parts,
5060 &_it->item->deco_all_content_objs);
5063 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5064 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5068 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5069 const Elm_Genlist_Item_Class *itc)
5071 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5072 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5074 if (!_it->item->block) return;
5075 EINA_SAFETY_ON_NULL_RETURN(itc);
5076 if (_it->generation < _it->wd->generation) return;
5078 _it->item->nocache_once = EINA_TRUE;
5080 elm_widget_stringlist_free(_it->texts);
5082 elm_widget_stringlist_free(_it->contents);
5083 _it->contents = NULL;
5084 elm_widget_stringlist_free(_it->states);
5089 elm_widget_stringlist_free(_it->item->flip_contents);
5090 _it->item->flip_contents = NULL;
5092 if (_it->item->deco_it_view)
5094 elm_widget_stringlist_free(_it->item->deco_it_texts);
5095 _it->item->deco_it_texts = NULL;
5096 elm_widget_stringlist_free(_it->item->deco_it_contents);
5097 _it->item->deco_it_contents = NULL;
5099 if (_it->wd->decorate_all_mode)
5101 elm_widget_stringlist_free(_it->item->deco_all_texts);
5102 _it->item->deco_all_texts = NULL;
5103 elm_widget_stringlist_free(_it->item->deco_all_contents);
5104 _it->item->deco_all_contents = NULL;
5107 elm_genlist_item_update(it);
5110 EAPI const Elm_Genlist_Item_Class *
5111 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5113 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5114 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5115 if (_it->generation < _it->wd->generation) return NULL;
5119 static Evas_Object *
5120 _elm_genlist_item_label_create(void *data,
5121 Evas_Object *obj __UNUSED__,
5122 Evas_Object *tooltip,
5123 void *it __UNUSED__)
5125 Evas_Object *label = elm_label_add(tooltip);
5128 elm_object_style_set(label, "tooltip");
5129 elm_object_text_set(label, data);
5134 _elm_genlist_item_label_del_cb(void *data,
5135 Evas_Object *obj __UNUSED__,
5136 void *event_info __UNUSED__)
5138 eina_stringshare_del(data);
5142 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5145 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5146 text = eina_stringshare_add(text);
5147 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5149 _elm_genlist_item_label_del_cb);
5153 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5154 Elm_Tooltip_Item_Content_Cb func,
5156 Evas_Smart_Cb del_cb)
5158 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5159 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5161 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5164 if (_it->tooltip.del_cb)
5165 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5167 _it->tooltip.content_cb = func;
5168 _it->tooltip.data = data;
5169 _it->tooltip.del_cb = del_cb;
5173 elm_widget_item_tooltip_content_cb_set(_it,
5174 _it->tooltip.content_cb,
5175 _it->tooltip.data, NULL);
5176 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5177 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5183 if (del_cb) del_cb((void *)data, NULL, NULL);
5187 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5189 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5190 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5192 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5193 elm_widget_item_tooltip_unset(_it);
5195 if (_it->tooltip.del_cb)
5196 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5197 _it->tooltip.del_cb = NULL;
5198 _it->tooltip.content_cb = NULL;
5199 _it->tooltip.data = NULL;
5200 _it->tooltip.free_size = EINA_FALSE;
5201 if (_it->tooltip.style)
5202 elm_genlist_item_tooltip_style_set(it, NULL);
5206 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5209 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5210 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5212 eina_stringshare_replace(&_it->tooltip.style, style);
5213 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5217 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5219 return elm_object_item_tooltip_style_get(it);
5223 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5226 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5227 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5229 _it->tooltip.free_size = disable;
5230 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5235 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5237 return elm_object_tooltip_window_mode_get(VIEW(it));
5241 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5244 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5245 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5246 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5247 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5251 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5253 return elm_widget_item_cursor_get(it);
5257 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5259 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5260 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5262 if (!_it->mouse_cursor) return;
5264 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5266 eina_stringshare_del(_it->mouse_cursor);
5267 _it->mouse_cursor = NULL;
5271 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5274 elm_widget_item_cursor_style_set(it, style);
5278 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5280 return elm_widget_item_cursor_style_get(it);
5284 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5285 Eina_Bool engine_only)
5287 elm_widget_item_cursor_engine_only_set(it, engine_only);
5291 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5293 return elm_widget_item_cursor_engine_only_get(it);
5297 elm_genlist_item_index_get(const Elm_Object_Item *it)
5299 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5300 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5302 if (_it->item->block)
5303 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5308 elm_genlist_mode_set(Evas_Object *obj,
5311 ELM_CHECK_WIDTYPE(obj, widtype);
5312 Widget_Data *wd = elm_widget_data_get(obj);
5314 if (wd->mode == mode) return;
5316 if (wd->mode == ELM_LIST_COMPRESS)
5317 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5323 elm_genlist_mode_get(const Evas_Object *obj)
5325 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5326 Widget_Data *wd = elm_widget_data_get(obj);
5327 if (!wd) return ELM_LIST_LAST;
5332 elm_genlist_bounce_set(Evas_Object *obj,
5336 ELM_CHECK_WIDTYPE(obj, widtype);
5337 Widget_Data *wd = elm_widget_data_get(obj);
5339 wd->h_bounce = !!h_bounce;
5340 wd->v_bounce = !!v_bounce;
5341 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5345 elm_genlist_bounce_get(const Evas_Object *obj,
5346 Eina_Bool *h_bounce,
5347 Eina_Bool *v_bounce)
5349 ELM_CHECK_WIDTYPE(obj, widtype);
5350 Widget_Data *wd = elm_widget_data_get(obj);
5352 if (h_bounce) *h_bounce = wd->h_bounce;
5353 if (v_bounce) *v_bounce = wd->v_bounce;
5357 elm_genlist_homogeneous_set(Evas_Object *obj,
5358 Eina_Bool homogeneous)
5360 ELM_CHECK_WIDTYPE(obj, widtype);
5361 Widget_Data *wd = elm_widget_data_get(obj);
5363 wd->homogeneous = !!homogeneous;
5367 elm_genlist_homogeneous_get(const Evas_Object *obj)
5369 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5370 Widget_Data *wd = elm_widget_data_get(obj);
5371 if (!wd) return EINA_FALSE;
5372 return wd->homogeneous;
5376 elm_genlist_block_count_set(Evas_Object *obj,
5379 ELM_CHECK_WIDTYPE(obj, widtype);
5380 Widget_Data *wd = elm_widget_data_get(obj);
5382 wd->max_items_per_block = count;
5383 wd->item_cache_max = wd->max_items_per_block * 2;
5384 _item_cache_clean(wd);
5388 elm_genlist_block_count_get(const Evas_Object *obj)
5390 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5391 Widget_Data *wd = elm_widget_data_get(obj);
5393 return wd->max_items_per_block;
5397 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5400 ELM_CHECK_WIDTYPE(obj, widtype);
5401 Widget_Data *wd = elm_widget_data_get(obj);
5403 wd->longpress_timeout = timeout;
5407 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5409 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5410 Widget_Data *wd = elm_widget_data_get(obj);
5412 return wd->longpress_timeout;
5416 elm_genlist_scroller_policy_set(Evas_Object *obj,
5417 Elm_Scroller_Policy policy_h,
5418 Elm_Scroller_Policy policy_v)
5420 ELM_CHECK_WIDTYPE(obj, widtype);
5421 Widget_Data *wd = elm_widget_data_get(obj);
5422 if ((!wd) || (!wd->scr)) return;
5423 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5424 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5426 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5430 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5431 Elm_Scroller_Policy *policy_h,
5432 Elm_Scroller_Policy *policy_v)
5434 ELM_CHECK_WIDTYPE(obj, widtype);
5435 Widget_Data *wd = elm_widget_data_get(obj);
5436 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5437 if ((!wd) || (!wd->scr)) return;
5438 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5439 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5440 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5444 elm_genlist_realized_items_update(Evas_Object *obj)
5446 ELM_CHECK_WIDTYPE(obj, widtype);
5448 Eina_List *list, *l;
5449 Elm_Object_Item *it;
5451 list = elm_genlist_realized_items_get(obj);
5452 EINA_LIST_FOREACH(list, l, it)
5453 elm_genlist_item_update(it);
5457 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5458 const char *decorate_it_type,
5459 Eina_Bool decorate_it_set)
5461 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5462 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5464 Widget_Data *wd = _it->wd;
5466 Elm_Object_Item *it2;
5469 if (!decorate_it_type) return;
5470 if ((_it->generation < _it->wd->generation) ||
5471 elm_widget_item_disabled_get(_it)) return;
5472 if (wd->decorate_all_mode) return;
5474 if ((wd->mode_item == _it) &&
5475 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5478 if (!_it->itc->decorate_item_style) return;
5479 _it->decorate_it_set = decorate_it_set;
5483 EINA_LIST_FOREACH(wd->selected, l, it2)
5484 if (((Elm_Gen_Item *)it2)->realized)
5485 elm_genlist_item_selected_set(it2, EINA_FALSE);
5489 it2 = elm_genlist_selected_item_get(wd->obj);
5490 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5491 elm_genlist_item_selected_set(it2, EINA_FALSE);
5494 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5495 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5496 _decorate_item_unset(wd);
5498 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5499 if (decorate_it_set) _decorate_item_set(_it);
5503 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5505 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5506 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5507 return _it->wd->decorate_it_type;
5510 EAPI const Elm_Object_Item *
5511 elm_genlist_decorated_item_get(const Evas_Object *obj)
5513 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5514 Widget_Data *wd = elm_widget_data_get(obj);
5515 if (!wd) return NULL;
5516 return (Elm_Object_Item *) wd->mode_item;
5520 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5522 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5523 Widget_Data *wd = elm_widget_data_get(obj);
5524 if (!wd) return EINA_FALSE;
5526 return wd->decorate_all_mode;
5530 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5532 ELM_CHECK_WIDTYPE(obj, widtype);
5533 Eina_List *list, *l;
5536 Widget_Data *wd = elm_widget_data_get(obj);
5538 decorated = !!decorated;
5539 if (wd->decorate_all_mode == decorated) return;
5540 wd->decorate_all_mode = decorated;
5542 list = elm_genlist_realized_items_get(obj);
5543 if (!wd->decorate_all_mode)
5545 EINA_LIST_FOREACH(list, l, it)
5547 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5548 _decorate_all_item_unrealize(it);
5550 _item_cache_zero(wd);
5554 EINA_LIST_FOREACH(list, l, it)
5556 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5558 if (it->selected) _item_unselect(it);
5559 if (it->itc->decorate_all_item_style)
5560 _decorate_all_item_realize(it, EINA_TRUE);
5564 if (wd->calc_job) ecore_job_del(wd->calc_job);
5565 wd->calc_job = ecore_job_add(_calc_job, wd);
5569 elm_genlist_reorder_mode_set(Evas_Object *obj,
5570 Eina_Bool reorder_mode)
5572 ELM_CHECK_WIDTYPE(obj, widtype);
5573 Widget_Data *wd = elm_widget_data_get(obj);
5575 wd->reorder_mode = !!reorder_mode;
5579 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5581 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5582 Widget_Data *wd = elm_widget_data_get(obj);
5583 if (!wd) return EINA_FALSE;
5584 return wd->reorder_mode;
5587 EAPI Elm_Genlist_Item_Type
5588 elm_genlist_item_type_get(const Elm_Object_Item *it)
5590 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5591 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5592 return _it->item->type;
5595 EAPI Elm_Genlist_Item_Class *
5596 elm_genlist_item_class_new(void)
5598 Elm_Genlist_Item_Class *itc;
5600 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5603 itc->version = CLASS_ALLOCATED;
5605 itc->delete_me = EINA_FALSE;
5611 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5613 if (itc && (itc->version == CLASS_ALLOCATED))
5615 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5616 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5626 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5628 if (itc && (itc->version == CLASS_ALLOCATED))
5631 if (itc->refcount == 0) itc->refcount--;
5636 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5638 if (itc && (itc->version == CLASS_ALLOCATED))
5640 if (itc->refcount > 0) itc->refcount--;
5641 if (itc->delete_me && (!itc->refcount))
5642 elm_genlist_item_class_free(itc);
5646 void _flip_job(void *data)
5648 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
5649 _elm_genlist_item_unrealize(it, EINA_FALSE);
5650 if (it->selected) _item_unselect(it);
5651 it->flipped = EINA_TRUE;
5652 it->item->nocache = EINA_TRUE;
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);
5668 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
5669 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
5673 _it->flipped = flip;
5674 _item_cache_zero(_it->wd);
5675 elm_genlist_item_update(it);
5676 _it->item->nocache = EINA_FALSE;
5681 elm_genlist_item_flip_get(const Elm_Object_Item *it)
5683 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5684 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5685 return _it->flipped;
5689 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
5691 ELM_CHECK_WIDTYPE(obj, widtype);
5692 Widget_Data *wd = elm_widget_data_get(obj);
5694 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5696 if (wd->select_mode != mode)
5697 wd->select_mode = mode;
5700 EAPI Elm_Object_Select_Mode
5701 elm_genlist_select_mode_get(const Evas_Object *obj)
5703 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
5704 Widget_Data *wd = elm_widget_data_get(obj);
5705 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
5706 return wd->select_mode;
5710 elm_genlist_highlight_mode_set(Evas_Object *obj,
5711 Eina_Bool highlight)
5713 ELM_CHECK_WIDTYPE(obj, widtype);
5714 Widget_Data *wd = elm_widget_data_get(obj);
5716 wd->highlight = !!highlight;
5720 elm_genlist_highlight_mode_get(const Evas_Object *obj)
5722 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5723 Widget_Data *wd = elm_widget_data_get(obj);
5724 if (!wd) return EINA_FALSE;
5725 return wd->highlight;
5729 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
5730 Elm_Object_Select_Mode mode)
5732 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5733 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5735 if (_it->generation < _it->wd->generation) return;
5736 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5738 if (_it->select_mode != mode)
5739 _it->select_mode = mode;
5741 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5743 _it->item->mincalcd = EINA_FALSE;
5744 _it->item->updateme = EINA_TRUE;
5745 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
5746 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5747 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5751 EAPI Elm_Object_Select_Mode
5752 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
5754 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
5755 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5756 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
5757 return _it->select_mode;
5760 /* for gengrid as of now */
5762 _elm_genlist_page_relative_set(Evas_Object *obj,
5766 Evas_Coord pagesize_h;
5767 Evas_Coord pagesize_v;
5769 ELM_CHECK_WIDTYPE(obj, widtype);
5770 Widget_Data *wd = elm_widget_data_get(obj);
5773 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5774 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5778 /* for gengrid as of now */
5780 _elm_genlist_page_relative_get(const Evas_Object *obj,
5784 ELM_CHECK_WIDTYPE(obj, widtype);
5785 Widget_Data *wd = elm_widget_data_get(obj);
5788 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5791 /* for gengrid as of now */
5793 _elm_genlist_page_size_set(Evas_Object *obj,
5794 Evas_Coord h_pagesize,
5795 Evas_Coord v_pagesize)
5800 ELM_CHECK_WIDTYPE(obj, widtype);
5801 Widget_Data *wd = elm_widget_data_get(obj);
5803 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5804 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5808 /* for gengrid as of now */
5810 _elm_genlist_current_page_get(const Evas_Object *obj,
5814 ELM_CHECK_WIDTYPE(obj, widtype);
5815 Widget_Data *wd = elm_widget_data_get(obj);
5817 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5820 /* for gengrid as of now */
5822 _elm_genlist_last_page_get(const Evas_Object *obj,
5826 ELM_CHECK_WIDTYPE(obj, widtype);
5827 Widget_Data *wd = elm_widget_data_get(obj);
5829 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5832 /* for gengrid as of now */
5834 _elm_genlist_page_show(const Evas_Object *obj,
5838 ELM_CHECK_WIDTYPE(obj, widtype);
5839 Widget_Data *wd = elm_widget_data_get(obj);
5841 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5844 /* for gengrid as of now */
5846 _elm_genlist_page_bring_in(const Evas_Object *obj,
5850 ELM_CHECK_WIDTYPE(obj, widtype);
5851 Widget_Data *wd = elm_widget_data_get(obj);
5853 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5857 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5860 Evas_Object *content;
5862 if (!it->realized) return;
5863 if (it->wd->reorder_it == it) return;
5865 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5867 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5870 ecore_timer_del(it->long_timer);
5871 it->long_timer = NULL;
5874 elm_widget_stringlist_free(it->texts);
5876 elm_widget_stringlist_free(it->contents);
5877 it->contents = NULL;
5878 elm_widget_stringlist_free(it->states);
5880 EINA_LIST_FREE(it->content_objs, content)
5881 evas_object_del(content);
5885 elm_widget_stringlist_free(it->item->flip_contents);
5886 it->item->flip_contents = NULL;
5887 EINA_LIST_FREE(it->item->flip_content_objs, content)
5888 evas_object_del(content);
5891 it->unrealize_cb(it);
5893 it->realized = EINA_FALSE;
5894 it->want_unrealize = EINA_FALSE;
5895 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5896 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5900 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5902 elm_widget_item_pre_notify_del(it);
5903 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5904 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5906 if (it->itc->func.del)
5907 it->itc->func.del((void *)it->base.data, WIDGET(it));
5911 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5913 _elm_genlist_item_del_notserious(it);
5914 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5915 if (it->tooltip.del_cb)
5916 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5917 it->wd->walking -= it->walking;
5920 ecore_timer_del(it->long_timer);
5921 it->long_timer = NULL;
5924 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5928 eina_inlist_sorted_state_free(it->wd->state);
5929 it->wd->state = NULL;
5931 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5932 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5936 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
5937 it->wd->last_selected_item = NULL;
5938 it->wd->item_count--;
5942 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
5944 ELM_CHECK_WIDTYPE(obj, widtype);
5945 Widget_Data *wd = elm_widget_data_get(obj);
5947 wd->tree_effect_enabled = !!enabled;
5951 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
5953 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5954 Widget_Data *wd = elm_widget_data_get(obj);
5955 if (!wd) return EINA_FALSE;
5956 return wd->tree_effect_enabled;
5960 _create_tray_alpha_bg(const Evas_Object *obj)
5962 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5963 Widget_Data *wd = elm_widget_data_get(obj);
5964 if (!wd) return NULL;
5966 Evas_Object *bg = NULL;
5967 Evas_Coord ox, oy, ow, oh;
5969 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5970 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
5971 evas_object_color_set(bg,0,0,0,0);
5972 evas_object_resize(bg , ow, oh);
5973 evas_object_move(bg , ox, oy);
5978 _item_contract_emit(Elm_Gen_Item *it)
5983 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
5984 it->item->tree_effect_finished = EINA_FALSE;
5986 EINA_LIST_FOREACH(it->item->items, l, it2)
5987 if (it2) _item_contract_emit(it2);
5991 _item_tree_effect_before(Elm_Gen_Item *it)
5996 EINA_LIST_FOREACH(it->item->items, l, it2)
5998 if (it2->parent && (it == it2->parent))
6001 it2->item->tree_effect_hideme = EINA_TRUE;
6002 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6003 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6004 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6005 _item_contract_emit(it2);
6008 return ECORE_CALLBACK_CANCEL;
6012 _item_tree_effect(Widget_Data *wd, int y)
6014 Elm_Gen_Item *it = NULL, *expanded_next_it;
6016 expanded_next_it = wd->expanded_next_item;
6018 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6020 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6023 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6024 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6025 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6027 if (!it->item->tree_effect_finished)
6029 edje_object_signal_emit(VIEW(it), "flip_item", "");
6030 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6031 it->item->tree_effect_finished = EINA_TRUE;
6034 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6037 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6039 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6042 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6043 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6045 if (!it->item->tree_effect_finished)
6047 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6048 it->item->tree_effect_finished = EINA_TRUE;
6053 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6059 _item_tree_effect_finish(Widget_Data *wd)
6061 Elm_Gen_Item *it = NULL;
6064 if (wd->tree_effect_animator)
6066 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6067 _item_subitems_clear(wd->expanded_item);
6068 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6070 it->item->tree_effect_finished = EINA_TRUE;
6071 it->item->old_scrl_y = it->item->scrl_y;
6072 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6073 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6076 _item_auto_scroll(wd);
6077 evas_object_lower(wd->alpha_bg);
6078 evas_object_hide(wd->alpha_bg);
6079 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6080 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6082 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6083 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6084 evas_object_smart_changed(wd->pan_smart);
6086 wd->tree_effect_animator = NULL;
6090 _tree_effect_animator_cb(void *data)
6092 Widget_Data *wd = data;
6093 if (!wd) return EINA_FALSE;
6094 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6095 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6097 double effect_duration = 0.3, t;
6098 int y = 0, dy = 0, dh = 0;
6099 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6102 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6103 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6104 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6105 if (t > effect_duration) end = EINA_TRUE;
6107 // Below while statement is needed, when the genlist is resized.
6108 it2 = wd->expanded_item;
6111 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6112 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6113 cvx, cvy, cvw, cvh));
6114 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6117 if (wd->expanded_next_item)
6119 expanded_next_it = wd->expanded_next_item;
6122 EINA_LIST_FOREACH(wd->move_items, l, it)
6124 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6126 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6127 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6128 expanded_next_it->item->scrl_y = cvy + cvh;
6130 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6131 cvy + cvh : expanded_next_it->item->scrl_y) -
6132 expanded_next_it->item->old_scrl_y;
6134 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6136 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6137 expanded_next_it->item->old_scrl_y = cvy + cvh;
6139 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6141 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6143 expanded_next_it->item->old_scrl_y = cvy + cvh;
6147 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6148 expanded_next_it->item->old_scrl_y;
6152 if (t <= effect_duration)
6154 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6164 _item_realize(it, in, 0);
6168 if (it != expanded_next_it)
6170 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6174 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6175 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6178 _item_tree_effect(wd, y);
6182 int expanded_item_num = 0;
6185 if (wd->expanded_item)
6186 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6191 expanded_item_num++;
6192 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6198 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6199 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6201 if (!it->item->tree_effect_finished)
6203 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6205 edje_object_signal_emit(VIEW(it), "flip_item", "");
6206 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6207 it->item->tree_effect_finished = EINA_TRUE;
6211 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6217 _item_tree_effect_finish(wd);
6218 return ECORE_CALLBACK_CANCEL;
6220 return ECORE_CALLBACK_RENEW;