3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.h"
9 // internally allocated
10 #define CLASS_ALLOCATED 0x3a70f11f
12 #define MAX_ITEMS_PER_BLOCK 32
13 #define REORDER_EFFECT_TIME 0.5
15 #define ELM_GEN_SETUP(wd) \
16 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
17 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
18 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
32 ERR("Genlist_Item_Class(itc) is NULL"); \
35 if ((itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) && \
36 (itc->version != CLASS_ALLOCATED)) \
38 ERR("Genlist_Item_Class version mismatched! current = (%d), required = (%d) or (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION, CLASS_ALLOCATED); \
44 typedef struct _Item_Block Item_Block;
45 typedef struct _Item_Cache Item_Cache;
47 struct Elm_Gen_Item_Type
52 Evas_Coord w, h, minw, minh;
53 Elm_Gen_Item *group_item;
54 Elm_Genlist_Item_Type type;
55 Eina_List *deco_it_texts, *deco_it_contents, *deco_it_states, *deco_it_content_objs;
56 Eina_List *deco_all_texts, *deco_all_contents, *deco_all_states, *deco_all_content_objs;
57 Eina_List *flip_contents, *flip_content_objs;
58 Ecore_Timer *swipe_timer;
59 Evas_Coord scrl_x, scrl_y, old_scrl_y;
62 Evas_Object *deco_it_view;
68 Eina_Bool want_realize : 1;
69 Eina_Bool expanded : 1;
70 Eina_Bool mincalcd : 1;
73 Eina_Bool updateme : 1;
74 Eina_Bool nocache : 1; /* do not use cache for this item */
75 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
76 Eina_Bool stacking_even : 1;
77 Eina_Bool nostacking : 1;
78 Eina_Bool move_effect_enabled : 1;
79 Eina_Bool decorate_all_item_realized : 1;
80 Eina_Bool tree_effect_finished : 1; /* tree effect */
81 Eina_Bool tree_effect_hideme : 1; /* item hide for tree effect */
92 Evas_Coord x, y, w, h, minw, minh;
94 int item_position_stamp;
96 Eina_Bool position_update : 1;
97 Eina_Bool want_unrealize : 1;
98 Eina_Bool realized : 1;
99 Eina_Bool changed : 1;
100 Eina_Bool updateme : 1;
101 Eina_Bool showme : 1;
102 Eina_Bool must_recalc : 1;
109 Evas_Object *base_view, *spacer;
111 const char *item_style; // it->itc->item_style
112 Eina_Bool tree : 1; // it->group
114 Eina_Bool selected : 1; // it->selected
115 Eina_Bool disabled : 1; // it->disabled
116 Eina_Bool expanded : 1; // it->item->expanded
119 static const char *widtype = NULL;
120 static void _item_cache_zero(Widget_Data *wd);
121 static void _del_hook(Evas_Object *obj);
122 static void _mirrored_set(Evas_Object *obj,
124 static void _theme_hook(Evas_Object *obj);
125 static void _show_region_hook(void *data,
127 static void _sizing_eval(Evas_Object *obj);
128 static void _item_realize(Elm_Gen_Item *it,
131 static void _item_unrealize_cb(Elm_Gen_Item *it);
132 static void _item_block_unrealize(Item_Block *itb);
133 static void _calc_job(void *data);
134 static void _on_focus_hook(void *data,
136 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
137 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
138 static Eina_Bool _item_single_select_up(Widget_Data *wd);
139 static Eina_Bool _item_single_select_down(Widget_Data *wd);
140 static Eina_Bool _event_hook(Evas_Object *obj,
142 Evas_Callback_Type type,
144 static void _signal_emit_hook(Evas_Object *obj,
145 const char *emission,
147 static Eina_Bool _deselect_all_items(Widget_Data *wd);
148 static void _pan_calculate(Evas_Object *obj);
149 static void _pan_max_get(Evas_Object *obj,
152 static void _item_position(Elm_Gen_Item *it,
156 static void _decorate_item_realize(Elm_Gen_Item *it);
157 static void _decorate_item_unrealize(Elm_Gen_Item *it);
158 static void _decorate_item_set(Elm_Gen_Item *it);
159 static void _decorate_item_unset(Widget_Data *wd);
160 static void _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity);
161 static void _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
162 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
163 static void _group_items_recalc(void *data);
164 static void _item_move_after(Elm_Gen_Item *it,
165 Elm_Gen_Item *after);
166 static void _item_move_before(Elm_Gen_Item *it,
167 Elm_Gen_Item *before);
168 static void _item_auto_scroll(Widget_Data *wd);
169 static void _elm_genlist_clear(Evas_Object *obj,
171 static void _pan_child_size_get(Evas_Object *obj,
174 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
175 static void _item_contract_emit(Elm_Gen_Item *it);
176 static int _item_tree_effect_before(Elm_Gen_Item *it);
177 static void _item_tree_effect(Widget_Data *wd, int y);
178 static void _item_tree_effect_finish(Widget_Data *wd);
179 static Eina_Bool _tree_effect_animator_cb(void *data);
181 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
183 static const char SIG_ACTIVATED[] = "activated";
184 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
185 static const char SIG_SELECTED[] = "selected";
186 static const char SIG_UNSELECTED[] = "unselected";
187 static const char SIG_EXPANDED[] = "expanded";
188 static const char SIG_CONTRACTED[] = "contracted";
189 static const char SIG_EXPAND_REQUEST[] = "expand,request";
190 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
191 static const char SIG_REALIZED[] = "realized";
192 static const char SIG_UNREALIZED[] = "unrealized";
193 static const char SIG_DRAG_START_UP[] = "drag,start,up";
194 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
195 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
196 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
197 static const char SIG_DRAG_STOP[] = "drag,stop";
198 static const char SIG_DRAG[] = "drag";
199 static const char SIG_LONGPRESSED[] = "longpressed";
200 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
201 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
202 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
203 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
204 static const char SIG_EDGE_TOP[] = "edge,top";
205 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
206 static const char SIG_EDGE_LEFT[] = "edge,left";
207 static const char SIG_EDGE_RIGHT[] = "edge,right";
208 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
209 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
210 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
211 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
212 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
213 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
214 static const char SIG_SWIPE[] = "swipe";
215 static const char SIG_MOVED[] = "moved";
216 static const char SIG_MOVED_AFTER[] = "moved,after";
217 static const char SIG_MOVED_BEFORE[] = "moved,before";
218 static const char SIG_INDEX_UPDATE[] = "index,update";
219 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
221 static const Evas_Smart_Cb_Description _signals[] = {
222 {SIG_CLICKED_DOUBLE, ""},
225 {SIG_UNSELECTED, ""},
227 {SIG_CONTRACTED, ""},
228 {SIG_EXPAND_REQUEST, ""},
229 {SIG_CONTRACT_REQUEST, ""},
231 {SIG_UNREALIZED, ""},
232 {SIG_DRAG_START_UP, ""},
233 {SIG_DRAG_START_DOWN, ""},
234 {SIG_DRAG_START_LEFT, ""},
235 {SIG_DRAG_START_RIGHT, ""},
238 {SIG_LONGPRESSED, ""},
239 {SIG_SCROLL_ANIM_START, ""},
240 {SIG_SCROLL_ANIM_STOP, ""},
241 {SIG_SCROLL_DRAG_START, ""},
242 {SIG_SCROLL_DRAG_STOP, ""},
244 {SIG_EDGE_BOTTOM, ""},
246 {SIG_EDGE_RIGHT, ""},
247 {SIG_MULTI_SWIPE_LEFT, ""},
248 {SIG_MULTI_SWIPE_RIGHT, ""},
249 {SIG_MULTI_SWIPE_UP, ""},
250 {SIG_MULTI_SWIPE_DOWN, ""},
251 {SIG_MULTI_PINCH_OUT, ""},
252 {SIG_MULTI_PINCH_IN, ""},
255 {SIG_MOVED_AFTER, ""},
256 {SIG_MOVED_BEFORE, ""},
257 {SIG_TREE_EFFECT_FINISHED, ""},
262 #undef ELM_CHECK_WIDTYPE
263 #define ELM_CHECK_WIDTYPE(obj, widtype) \
264 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
265 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
266 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
267 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
268 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
270 static const char *_gengrid = NULL;
271 static const char *_genlist = NULL;
273 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
275 elm_genlist_type_check(const Evas_Object *obj,
278 const char *provided, *expected = "(unknown)";
279 static int abort_on_warn = -1;
280 provided = elm_widget_type_get(obj);
281 if (!_genlist) _genlist = eina_stringshare_add("genlist");
282 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
283 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
285 if ((!provided) || (!provided[0]))
287 provided = evas_object_type_get(obj);
288 if ((!provided) || (!provided[0]))
289 provided = "(unknown)";
291 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
292 if (abort_on_warn == -1)
294 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
295 else abort_on_warn = 0;
297 if (abort_on_warn == 1) abort();
302 _event_hook(Evas_Object *obj,
303 Evas_Object *src __UNUSED__,
304 Evas_Callback_Type type,
307 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
308 Evas_Event_Key_Down *ev = event_info;
309 Widget_Data *wd = elm_widget_data_get(obj);
310 Evas_Coord pan_max_x = 0, pan_max_y = 0;
311 if (!wd) return EINA_FALSE;
312 if (!wd->items) return EINA_FALSE;
313 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
314 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
316 Elm_Object_Item *it = NULL;
319 Evas_Coord step_x = 0;
320 Evas_Coord step_y = 0;
323 Evas_Coord page_x = 0;
324 Evas_Coord page_y = 0;
326 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
327 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
328 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
329 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
331 if ((!strcmp(ev->keyname, "Left")) ||
332 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
336 else if ((!strcmp(ev->keyname, "Right")) ||
337 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
341 else if ((!strcmp(ev->keyname, "Up")) ||
342 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
344 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
345 (_item_multi_select_up(wd)))
346 || (_item_single_select_up(wd)))
348 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
354 else if ((!strcmp(ev->keyname, "Down")) ||
355 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
357 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
358 (_item_multi_select_down(wd)))
359 || (_item_single_select_down(wd)))
361 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
367 else if ((!strcmp(ev->keyname, "Home")) ||
368 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
370 it = elm_genlist_first_item_get(obj);
371 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
372 elm_genlist_item_selected_set(it, EINA_TRUE);
373 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
376 else if ((!strcmp(ev->keyname, "End")) ||
377 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
379 it = elm_genlist_last_item_get(obj);
380 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
381 elm_genlist_item_selected_set(it, EINA_TRUE);
382 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
385 else if ((!strcmp(ev->keyname, "Prior")) ||
386 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
389 y -= -(page_y * v_h) / 100;
393 else if ((!strcmp(ev->keyname, "Next")) ||
394 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
397 y += -(page_y * v_h) / 100;
401 else if (!strcmp(ev->keyname, "Escape"))
403 if (!_deselect_all_items(wd)) return EINA_FALSE;
404 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
407 else if (((!strcmp(ev->keyname, "Return")) ||
408 (!strcmp(ev->keyname, "KP_Enter")) ||
409 (!strcmp(ev->keyname, "space")))
410 && (!wd->multi) && (wd->selected))
412 it = elm_genlist_selected_item_get(obj);
413 elm_genlist_item_expanded_set(it,
414 !elm_genlist_item_expanded_get(it));
415 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
417 else return EINA_FALSE;
419 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
420 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
422 if (x > pan_max_x) x = pan_max_x;
424 if (y > pan_max_y) y = pan_max_y;
425 elm_smart_scroller_child_pos_set(wd->scr, x, y);
430 _deselect_all_items(Widget_Data *wd)
432 if (!wd->selected) return EINA_FALSE;
434 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
440 _item_multi_select_up(Widget_Data *wd)
442 if (!wd->selected) return EINA_FALSE;
443 if (!wd->multi) return EINA_FALSE;
445 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
446 if (!prev) return EINA_TRUE;
448 if (elm_genlist_item_selected_get(prev))
450 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
451 wd->last_selected_item = prev;
452 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
456 elm_genlist_item_selected_set(prev, EINA_TRUE);
457 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
463 _item_multi_select_down(Widget_Data *wd)
465 if (!wd->selected) return EINA_FALSE;
466 if (!wd->multi) return EINA_FALSE;
468 Elm_Object_Item *next;
469 next = elm_genlist_item_next_get(wd->last_selected_item);
470 if (!next) return EINA_TRUE;
472 if (elm_genlist_item_selected_get(next))
474 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
475 wd->last_selected_item = next;
476 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
480 elm_genlist_item_selected_set(next, EINA_TRUE);
481 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
487 _item_single_select_up(Widget_Data *wd)
492 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
493 while ((prev) && (prev->generation < wd->generation))
494 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
496 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
498 if (!prev) return EINA_FALSE;
500 _deselect_all_items(wd);
502 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
503 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
508 _item_single_select_down(Widget_Data *wd)
513 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
514 while ((next) && (next->generation < wd->generation))
515 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
517 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
519 if (!next) return EINA_FALSE;
521 _deselect_all_items(wd);
523 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
524 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
529 _on_focus_hook(void *data __UNUSED__,
532 Widget_Data *wd = elm_widget_data_get(obj);
534 if (elm_widget_focus_get(obj))
536 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
537 evas_object_focus_set(wd->obj, EINA_TRUE);
538 if ((wd->selected) && (!wd->last_selected_item))
539 wd->last_selected_item = eina_list_data_get(wd->selected);
543 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
544 evas_object_focus_set(wd->obj, EINA_FALSE);
549 _del_hook(Evas_Object *obj)
551 Widget_Data *wd = elm_widget_data_get(obj);
553 _item_cache_zero(wd);
554 if (wd->calc_job) ecore_job_del(wd->calc_job);
555 if (wd->update_job) ecore_job_del(wd->update_job);
556 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
557 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
558 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
559 if (wd->decorate_it_type) eina_stringshare_del(wd->decorate_it_type);
560 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
561 if (wd->tree_effect_animator) ecore_animator_del(wd->tree_effect_animator);
566 _del_pre_hook(Evas_Object *obj)
568 Widget_Data *wd = elm_widget_data_get(obj);
570 if (wd->decorate_all_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
571 elm_genlist_clear(obj);
572 evas_object_del(wd->pan_smart);
573 wd->pan_smart = NULL;
577 _mirrored_set(Evas_Object *obj,
580 Widget_Data *wd = elm_widget_data_get(obj);
582 _item_cache_zero(wd);
583 elm_smart_scroller_mirrored_set(wd->scr, rtl);
587 _theme_hook(Evas_Object *obj)
589 Widget_Data *wd = elm_widget_data_get(obj);
592 evas_event_freeze(evas_object_evas_get(wd->obj));
593 _item_cache_zero(wd);
594 _elm_widget_mirrored_reload(obj);
595 _mirrored_set(obj, elm_widget_mirrored_get(obj));
596 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
597 elm_widget_style_get(obj));
598 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
599 wd->item_width = wd->item_height = 0;
600 wd->group_item_width = wd->group_item_height = 0;
601 wd->minw = wd->minh = wd->realminw = 0;
602 EINA_INLIST_FOREACH(wd->blocks, itb)
607 if (itb->realized) _item_block_unrealize(itb);
608 EINA_LIST_FOREACH(itb->items, l, it)
609 it->item->mincalcd = EINA_FALSE;
611 itb->changed = EINA_TRUE;
613 if (wd->calc_job) ecore_job_del(wd->calc_job);
614 wd->calc_job = ecore_job_add(_calc_job, wd);
616 evas_event_thaw(evas_object_evas_get(wd->obj));
617 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
621 _show_region_hook(void *data,
624 Widget_Data *wd = elm_widget_data_get(data);
625 Evas_Coord x, y, w, h;
627 elm_widget_show_region_get(obj, &x, &y, &w, &h);
628 //x & y are screen coordinates, Add with pan coordinates
631 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
635 _translate_hook(Evas_Object *obj)
637 evas_object_smart_callback_call(obj, "language,changed", NULL);
641 _sizing_eval(Evas_Object *obj)
643 Widget_Data *wd = elm_widget_data_get(obj);
644 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
645 Evas_Coord vmw = 0, vmh = 0;
648 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
649 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
651 edje_object_size_min_calc
652 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
654 if (wd->mode == ELM_LIST_COMPRESS)
658 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
659 if ((vw != 0) && (vw != wd->prev_viewport_w))
663 wd->prev_viewport_w = vw;
664 EINA_INLIST_FOREACH(wd->blocks, itb)
666 itb->must_recalc = EINA_TRUE;
668 if (wd->calc_job) ecore_job_del(wd->calc_job);
669 wd->calc_job = ecore_job_add(_calc_job, wd);
674 else if (wd->mode == ELM_LIST_LIMIT)
685 evas_object_size_hint_min_set(obj, minw, minh);
686 evas_object_size_hint_max_set(obj, maxw, maxh);
690 _signal_emit_hook(Evas_Object *obj,
691 const char *emission,
694 Widget_Data *wd = elm_widget_data_get(obj);
695 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
700 _item_highlight(Elm_Gen_Item *it)
702 const char *selectraise;
703 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
704 (!it->wd->highlight) ||
705 (it->generation < it->wd->generation) ||
706 (it->highlighted) || elm_widget_item_disabled_get(it) ||
707 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->deco_it_view) ||
708 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
710 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
711 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
712 selectraise = edje_object_data_get(VIEW(it), "selectraise");
713 if ((selectraise) && (!strcmp(selectraise, "on")))
715 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
716 else evas_object_raise(VIEW(it));
717 if ((it->item->group_item) && (it->item->group_item->realized))
718 evas_object_raise(it->item->VIEW(group_item));
720 it->highlighted = EINA_TRUE;
724 _item_unhighlight(Elm_Gen_Item *it)
726 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
727 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
728 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
729 if (!it->item->nostacking)
731 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
733 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
734 else evas_object_lower(VIEW(it));
738 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
739 else evas_object_raise(VIEW(it));
742 it->highlighted = EINA_FALSE;
746 _item_block_position_update(Eina_Inlist *list, int idx)
750 EINA_INLIST_FOREACH(list, tmp)
752 tmp->position = idx++;
753 tmp->position_update = EINA_TRUE;
758 _item_position_update(Eina_List *list, int idx)
763 EINA_LIST_FOREACH(list, l, it)
765 it->position = idx++;
766 it->position_update = EINA_TRUE;
771 _item_block_del(Elm_Gen_Item *it)
774 Item_Block *itb = it->item->block;
776 itb->items = eina_list_remove(itb->items, it);
778 itb->changed = EINA_TRUE;
779 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
780 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
783 il = EINA_INLIST_GET(itb);
784 Item_Block *itbn = (Item_Block *)(il->next);
786 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
789 _item_block_position_update(il->next, itb->position);
790 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
793 if (itbn) itbn->changed = EINA_TRUE;
797 if (itb->count < itb->wd->max_items_per_block/2)
799 il = EINA_INLIST_GET(itb);
800 Item_Block *itbp = (Item_Block *)(il->prev);
801 Item_Block *itbn = (Item_Block *)(il->next);
802 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
806 EINA_LIST_FREE(itb->items, it2)
808 it2->item->block = itbp;
809 itbp->items = eina_list_append(itbp->items, it2);
811 itbp->changed = EINA_TRUE;
813 _item_block_position_update(EINA_INLIST_GET(itb)->next,
815 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
816 EINA_INLIST_GET(itb));
819 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
823 Eina_List *last = eina_list_last(itb->items);
824 Elm_Gen_Item *it2 = last->data;
826 it2->item->block = itbn;
827 itb->items = eina_list_remove_list(itb->items, last);
828 itbn->items = eina_list_prepend(itbn->items, it2);
830 itbn->changed = EINA_TRUE;
832 _item_block_position_update(EINA_INLIST_GET(itb)->next,
835 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
843 _item_subitems_clear(Elm_Gen_Item *it)
845 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
846 Eina_List *tl = NULL, *l;
847 Elm_Object_Item *it2;
849 EINA_LIST_FOREACH(it->item->items, l, it2)
850 tl = eina_list_append(tl, it2);
851 EINA_LIST_FREE(tl, it2)
852 elm_object_item_del(it2);
856 _item_del(Elm_Gen_Item *it)
858 Evas_Object *obj = WIDGET(it);
859 Widget_Data *wd = it->wd;
861 evas_event_freeze(evas_object_evas_get(obj));
862 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
863 if (wd->show_item == it) wd->show_item = NULL;
864 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
865 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
866 if (it->item->block) _item_block_del(it);
867 if (it->item->queued)
868 wd->queue = eina_list_remove(wd->queue, it);
869 if (wd->anchor_item == it)
871 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
872 if (!wd->anchor_item)
873 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
875 if (wd->expanded_item == it)
877 wd->expanded_item = NULL;
878 if (wd->tree_effect_animator)
880 ecore_animator_del(wd->tree_effect_animator);
881 wd->tree_effect_animator = NULL;
883 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
885 if (wd->expanded_next_item == it) wd->expanded_next_item = NULL;
886 if (wd->move_items) wd->move_items = eina_list_remove(wd->move_items, it);
888 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
889 if (it->item->swipe_timer)
891 ecore_timer_del(it->item->swipe_timer);
892 it->item->swipe_timer = NULL;
894 _elm_genlist_item_del_serious(it);
895 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
896 evas_event_thaw(evas_object_evas_get(obj));
897 evas_event_thaw_eval(evas_object_evas_get(obj));
901 _clear_cb(Widget_Data *wd)
903 wd->anchor_item = NULL;
904 if (wd->queue_idle_enterer)
906 ecore_idle_enterer_del(wd->queue_idle_enterer);
907 wd->queue_idle_enterer = NULL;
909 if (wd->must_recalc_idler)
911 ecore_idler_del(wd->must_recalc_idler);
912 wd->must_recalc_idler = NULL;
914 if (wd->queue) wd->queue = eina_list_free(wd->queue);
915 if (wd->reorder_move_animator)
917 ecore_animator_del(wd->reorder_move_animator);
918 wd->reorder_move_animator = NULL;
920 wd->show_item = NULL;
921 wd->reorder_old_pan_y = 0;
925 _item_unselect(Elm_Gen_Item *it)
927 if ((it->generation < it->wd->generation) || (!it->selected)) return;
928 it->selected = EINA_FALSE;
929 it->wd->selected = eina_list_remove(it->wd->selected, it);
930 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
934 _mouse_move(void *data,
935 Evas *evas __UNUSED__,
939 Elm_Gen_Item *it = data;
940 Evas_Event_Mouse_Move *ev = event_info;
941 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
942 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
944 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
946 if (!it->wd->on_hold)
948 it->wd->on_hold = EINA_TRUE;
949 if ((!it->wd->wasselected) && (!it->flipped))
951 _item_unhighlight(it);
956 if (it->wd->multitouched)
958 it->wd->cur_x = ev->cur.canvas.x;
959 it->wd->cur_y = ev->cur.canvas.y;
962 if ((it->dragging) && (it->down))
964 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
967 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
968 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
969 if (abs((it->wd->history[it->wd->movements].x -
970 it->wd->history[0].x)) > 40)
971 it->wd->swipe = EINA_TRUE;
977 ecore_timer_del(it->long_timer);
978 it->long_timer = NULL;
980 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
983 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
987 ecore_timer_del(it->long_timer);
988 it->long_timer = NULL;
990 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
992 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
993 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
995 if (!it->wd->reorder_start_y)
996 it->wd->reorder_start_y = it->item->block->y + it->y;
1000 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
1001 y_pos = oy + oh - it->wd->reorder_it->item->h;
1005 if (it->deco_all_view)
1006 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
1008 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1010 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1011 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1015 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1016 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1017 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1018 x = ev->cur.canvas.x - x;
1019 y = ev->cur.canvas.y - y;
1022 if (adx < 0) adx = -dx;
1025 if (ady < 0) ady = -dy;
1028 if ((adx > minw) || (ady > minh))
1030 it->dragging = EINA_TRUE;
1033 ecore_timer_del(it->long_timer);
1034 it->long_timer = NULL;
1036 if (!it->wd->wasselected)
1038 _item_unhighlight(it);
1044 evas_object_smart_callback_call(WIDGET(it),
1045 SIG_DRAG_START_UP, it);
1049 evas_object_smart_callback_call(WIDGET(it),
1050 SIG_DRAG_START_LEFT, it);
1052 evas_object_smart_callback_call(WIDGET(it),
1053 SIG_DRAG_START_RIGHT, it);
1059 evas_object_smart_callback_call(WIDGET(it),
1060 SIG_DRAG_START_DOWN, it);
1064 evas_object_smart_callback_call(WIDGET(it),
1065 SIG_DRAG_START_LEFT, it);
1067 evas_object_smart_callback_call(WIDGET(it),
1068 SIG_DRAG_START_RIGHT, it);
1075 _long_press(void *data)
1077 Elm_Gen_Item *it = data, *it_tmp;
1078 Eina_List *list, *l;
1080 it->long_timer = NULL;
1081 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1082 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1083 return ECORE_CALLBACK_CANCEL;
1084 it->wd->longpressed = EINA_TRUE;
1085 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1086 if ((it->wd->reorder_mode) && (!it->group))
1088 it->wd->reorder_it = it;
1089 it->wd->reorder_start_y = 0;
1090 if (it->deco_all_view)
1091 evas_object_raise(it->deco_all_view);
1093 evas_object_raise(VIEW(it));
1095 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1096 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1098 list = elm_genlist_realized_items_get(it->wd->obj);
1099 EINA_LIST_FOREACH(list, l, it_tmp)
1101 if (it != it_tmp) _item_unselect(it_tmp);
1103 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1105 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1106 return ECORE_CALLBACK_RENEW;
1109 if (!it->wd->decorate_all_mode)
1110 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1112 return ECORE_CALLBACK_CANCEL;
1116 _swipe(Elm_Gen_Item *it)
1121 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1122 elm_widget_item_disabled_get(it)) return;
1123 it->wd->swipe = EINA_FALSE;
1124 for (i = 0; i < it->wd->movements; i++)
1126 sum += it->wd->history[i].x;
1127 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1130 sum /= it->wd->movements;
1131 if (abs(sum - it->wd->history[0].x) <= 10) return;
1132 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1136 _swipe_cancel(void *data)
1138 Elm_Gen_Item *it = data;
1140 if (!it) return ECORE_CALLBACK_CANCEL;
1141 it->wd->swipe = EINA_FALSE;
1142 it->wd->movements = 0;
1143 return ECORE_CALLBACK_RENEW;
1147 _multi_cancel(void *data)
1149 Widget_Data *wd = data;
1151 if (!wd) return ECORE_CALLBACK_CANCEL;
1152 wd->multi_timeout = EINA_TRUE;
1153 return ECORE_CALLBACK_RENEW;
1157 _multi_touch_gesture_eval(void *data)
1159 Elm_Gen_Item *it = data;
1161 it->wd->multitouched = EINA_FALSE;
1162 if (it->wd->multi_timer)
1164 ecore_timer_del(it->wd->multi_timer);
1165 it->wd->multi_timer = NULL;
1167 if (it->wd->multi_timeout)
1169 it->wd->multi_timeout = EINA_FALSE;
1173 Evas_Coord minw = 0, minh = 0;
1174 Evas_Coord off_x, off_y, off_mx, off_my;
1176 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1177 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1178 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1179 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1180 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1182 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1184 if ((off_x + off_mx) > (off_y + off_my))
1186 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1187 evas_object_smart_callback_call(WIDGET(it),
1188 SIG_MULTI_SWIPE_RIGHT, it);
1189 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1190 evas_object_smart_callback_call(WIDGET(it),
1191 SIG_MULTI_SWIPE_LEFT, it);
1192 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1193 evas_object_smart_callback_call(WIDGET(it),
1194 SIG_MULTI_PINCH_OUT, it);
1196 evas_object_smart_callback_call(WIDGET(it),
1197 SIG_MULTI_PINCH_IN, it);
1201 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1202 evas_object_smart_callback_call(WIDGET(it),
1203 SIG_MULTI_SWIPE_DOWN, it);
1204 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1205 evas_object_smart_callback_call(WIDGET(it),
1206 SIG_MULTI_SWIPE_UP, it);
1207 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1208 evas_object_smart_callback_call(WIDGET(it),
1209 SIG_MULTI_PINCH_OUT, it);
1211 evas_object_smart_callback_call(WIDGET(it),
1212 SIG_MULTI_PINCH_IN, it);
1215 it->wd->multi_timeout = EINA_FALSE;
1219 _multi_down(void *data,
1220 Evas *evas __UNUSED__,
1221 Evas_Object *obj __UNUSED__,
1224 Elm_Gen_Item *it = data;
1225 Evas_Event_Multi_Down *ev = event_info;
1227 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1228 it->wd->multi_device = ev->device;
1229 it->wd->multi_down = EINA_TRUE;
1230 it->wd->multitouched = EINA_TRUE;
1231 it->wd->prev_mx = ev->canvas.x;
1232 it->wd->prev_my = ev->canvas.y;
1233 if (!it->wd->wasselected)
1235 _item_unhighlight(it);
1238 it->wd->wasselected = EINA_FALSE;
1239 it->wd->longpressed = EINA_FALSE;
1242 ecore_timer_del(it->long_timer);
1243 it->long_timer = NULL;
1247 it->dragging = EINA_FALSE;
1248 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1250 if (it->item->swipe_timer)
1252 ecore_timer_del(it->item->swipe_timer);
1253 it->item->swipe_timer = NULL;
1255 if (it->wd->on_hold)
1257 it->wd->swipe = EINA_FALSE;
1258 it->wd->movements = 0;
1259 it->wd->on_hold = EINA_FALSE;
1264 _multi_up(void *data,
1265 Evas *evas __UNUSED__,
1266 Evas_Object *obj __UNUSED__,
1269 Elm_Gen_Item *it = data;
1270 Evas_Event_Multi_Up *ev = event_info;
1272 if (it->wd->multi_device != ev->device) return;
1273 it->wd->multi_device = 0;
1274 it->wd->multi_down = EINA_FALSE;
1275 if (it->wd->mouse_down) return;
1276 _multi_touch_gesture_eval(data);
1280 _multi_move(void *data,
1281 Evas *evas __UNUSED__,
1282 Evas_Object *obj __UNUSED__,
1285 Elm_Gen_Item *it = data;
1286 Evas_Event_Multi_Move *ev = event_info;
1288 if (it->wd->multi_device != ev->device) return;
1289 it->wd->cur_mx = ev->cur.canvas.x;
1290 it->wd->cur_my = ev->cur.canvas.y;
1294 _mouse_down(void *data,
1295 Evas *evas __UNUSED__,
1299 Elm_Gen_Item *it = data;
1300 Evas_Event_Mouse_Down *ev = event_info;
1303 if (ev->button != 1) return;
1304 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1306 it->wd->on_hold = EINA_TRUE;
1309 it->down = EINA_TRUE;
1310 it->dragging = EINA_FALSE;
1311 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1312 it->dx = ev->canvas.x - x;
1313 it->dy = ev->canvas.y - y;
1314 it->wd->mouse_down = EINA_TRUE;
1315 if (!it->wd->multitouched)
1317 it->wd->prev_x = ev->canvas.x;
1318 it->wd->prev_y = ev->canvas.y;
1319 it->wd->multi_timeout = EINA_FALSE;
1320 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1321 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1323 it->wd->longpressed = EINA_FALSE;
1324 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1325 else it->wd->on_hold = EINA_FALSE;
1326 if (it->wd->on_hold) return;
1327 it->wd->wasselected = it->selected;
1328 _item_highlight(it);
1329 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1330 if ((!elm_widget_item_disabled_get(it)) &&
1331 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1333 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1334 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1336 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1337 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1338 if (it->long_timer) ecore_timer_del(it->long_timer);
1340 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1343 it->long_timer = NULL;
1344 it->wd->swipe = EINA_FALSE;
1345 it->wd->movements = 0;
1349 _mouse_up(void *data,
1350 Evas *evas __UNUSED__,
1351 Evas_Object *obj __UNUSED__,
1354 Elm_Gen_Item *it = data;
1355 Evas_Event_Mouse_Up *ev = event_info;
1356 Eina_Bool dragged = EINA_FALSE;
1358 if (ev->button != 1) return;
1359 it->down = EINA_FALSE;
1360 it->wd->mouse_down = EINA_FALSE;
1361 if (it->wd->multitouched)
1363 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1364 if (it->wd->multi_down) return;
1365 _multi_touch_gesture_eval(data);
1368 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1369 else it->wd->on_hold = EINA_FALSE;
1372 ecore_timer_del(it->long_timer);
1373 it->long_timer = NULL;
1377 it->dragging = EINA_FALSE;
1378 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1381 if (it->item->swipe_timer)
1383 ecore_timer_del(it->item->swipe_timer);
1384 it->item->swipe_timer = NULL;
1386 if (it->wd->multi_timer)
1388 ecore_timer_del(it->wd->multi_timer);
1389 it->wd->multi_timer = NULL;
1390 it->wd->multi_timeout = EINA_FALSE;
1392 if (it->wd->on_hold)
1394 if (it->wd->swipe) _swipe(data);
1395 it->wd->longpressed = EINA_FALSE;
1396 it->wd->on_hold = EINA_FALSE;
1399 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1401 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1403 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1405 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1406 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1408 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1409 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1413 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1414 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1416 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1417 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1418 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1419 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1421 if (it->wd->longpressed)
1423 it->wd->longpressed = EINA_FALSE;
1424 if ((!it->wd->wasselected) && (!it->flipped))
1426 _item_unhighlight(it);
1429 it->wd->wasselected = EINA_FALSE;
1434 if (it->want_unrealize)
1436 _elm_genlist_item_unrealize(it, EINA_FALSE);
1437 if (it->item->block->want_unrealize)
1438 _item_block_unrealize(it->item->block);
1441 if (elm_widget_item_disabled_get(it) || (dragged) ||
1442 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1444 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1449 _item_highlight(it);
1454 _item_unhighlight(it);
1462 Widget_Data *wd = it->wd;
1465 while (wd->selected)
1467 _item_unhighlight(wd->selected->data);
1468 _item_unselect(wd->selected->data);
1474 const Eina_List *l, *l_next;
1477 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1480 _item_unhighlight(it2);
1481 _item_unselect(it2);
1483 //_item_highlight(it);
1486 _item_highlight(it);
1492 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1494 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1496 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1498 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1500 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1502 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1504 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1509 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1511 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1513 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1515 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1517 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1519 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1521 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1526 _signal_expand_toggle(void *data,
1527 Evas_Object *obj __UNUSED__,
1528 const char *emission __UNUSED__,
1529 const char *source __UNUSED__)
1531 Elm_Gen_Item *it = data;
1533 if (it->item->expanded)
1534 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1536 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1540 _signal_expand(void *data,
1541 Evas_Object *obj __UNUSED__,
1542 const char *emission __UNUSED__,
1543 const char *source __UNUSED__)
1545 Elm_Gen_Item *it = data;
1547 if (!it->item->expanded)
1548 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1552 _signal_contract(void *data,
1553 Evas_Object *obj __UNUSED__,
1554 const char *emission __UNUSED__,
1555 const char *source __UNUSED__)
1557 Elm_Gen_Item *it = data;
1559 if (it->item->expanded)
1560 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1564 _scr_hold_timer_cb(void *data)
1566 if (!data) return ECORE_CALLBACK_CANCEL;
1567 Widget_Data *wd = data;
1568 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1569 wd->scr_hold_timer = NULL;
1570 return ECORE_CALLBACK_CANCEL;
1574 _decorate_item_finished_signal_cb(void *data,
1576 const char *emission __UNUSED__,
1577 const char *source __UNUSED__)
1581 Elm_Gen_Item *it = data;
1582 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1584 Evas *te = evas_object_evas_get(obj);
1586 evas_event_freeze(te);
1587 it->item->nocache_once = EINA_FALSE;
1588 _decorate_item_unrealize(it);
1589 if (it->item->group_item)
1590 evas_object_raise(it->item->VIEW(group_item));
1591 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1592 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1593 evas_event_thaw(te);
1594 evas_event_thaw_eval(te);
1598 _item_cache_clean(Widget_Data *wd)
1600 evas_event_freeze(evas_object_evas_get(wd->obj));
1601 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1605 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1606 wd->item_cache = eina_inlist_remove(wd->item_cache,
1607 wd->item_cache->last);
1608 wd->item_cache_count--;
1609 if (itc->spacer) evas_object_del(itc->spacer);
1610 if (itc->base_view) evas_object_del(itc->base_view);
1611 eina_stringshare_del(itc->item_style);
1614 evas_event_thaw(evas_object_evas_get(wd->obj));
1615 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1619 _item_cache_zero(Widget_Data *wd)
1621 int pmax = wd->item_cache_max;
1622 wd->item_cache_max = 0;
1623 _item_cache_clean(wd);
1624 wd->item_cache_max = pmax;
1628 _item_cache_add(Elm_Gen_Item *it)
1632 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1633 if (it->wd->item_cache_max <= 0)
1635 evas_object_del(VIEW(it));
1639 evas_object_del(it->spacer);
1642 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1643 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1647 it->wd->item_cache_count++;
1648 itc = calloc(1, sizeof(Item_Cache));
1651 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1652 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1655 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1656 EINA_INLIST_GET(itc));
1657 itc->spacer = it->spacer;
1659 itc->base_view = VIEW(it);
1661 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1662 evas_object_hide(itc->base_view);
1663 evas_object_move(itc->base_view, -9999, -9999);
1664 itc->item_style = eina_stringshare_add(it->itc->item_style);
1665 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1666 itc->selected = it->selected;
1667 itc->disabled = elm_widget_item_disabled_get(it);
1668 itc->expanded = it->item->expanded;
1671 ecore_timer_del(it->long_timer);
1672 it->long_timer = NULL;
1674 if (it->item->swipe_timer)
1676 ecore_timer_del(it->item->swipe_timer);
1677 it->item->swipe_timer = NULL;
1679 // FIXME: other callbacks?
1680 edje_object_signal_callback_del_full(itc->base_view,
1681 "elm,action,expand,toggle",
1682 "elm", _signal_expand_toggle, it);
1683 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1685 _signal_expand, it);
1686 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1687 "elm", _signal_contract, it);
1688 _item_mouse_callbacks_del(it, itc->base_view);
1689 _item_cache_clean(it->wd);
1690 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1691 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1695 _item_cache_find(Elm_Gen_Item *it)
1700 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1701 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1703 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1705 if ((itc->tree == tree) &&
1706 (((!it->itc->item_style) && (!itc->item_style)) ||
1707 (it->itc->item_style && itc->item_style &&
1708 (!strcmp(it->itc->item_style, itc->item_style)))))
1710 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1711 EINA_INLIST_GET(itc));
1712 it->wd->item_cache_count--;
1720 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1722 if (it->position_update || it->item->block->position_update)
1724 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1725 it->position_update = EINA_FALSE;
1730 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1732 if (!it->item->nostacking)
1734 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1736 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1737 else evas_object_lower(VIEW(it));
1741 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1742 else evas_object_raise(VIEW(it));
1746 if (it->item->order_num_in & 0x1)
1748 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1749 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1753 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1754 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1759 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1763 if (it->selected != itc->selected)
1767 edje_object_signal_emit(VIEW(it),
1768 "elm,state,selected", "elm");
1770 if (it->deco_all_view)
1771 edje_object_signal_emit(it->deco_all_view,
1772 "elm,state,selected", "elm");
1775 if (elm_widget_item_disabled_get(it) != itc->disabled)
1777 if (elm_widget_item_disabled_get(it))
1778 edje_object_signal_emit(VIEW(it),
1779 "elm,state,disabled", "elm");
1780 if (it->deco_all_view)
1781 edje_object_signal_emit(it->deco_all_view,
1782 "elm,state,disabled", "elm");
1784 if (it->item->expanded != itc->expanded)
1786 if (it->item->expanded)
1787 edje_object_signal_emit(VIEW(it),
1788 "elm,state,expanded", "elm");
1789 if (it->deco_all_view)
1790 edje_object_signal_emit(it->deco_all_view,
1791 "elm,state,expanded", "elm");
1798 edje_object_signal_emit(VIEW(it),
1799 "elm,state,selected", "elm");
1800 if (it->deco_all_view)
1801 edje_object_signal_emit(it->deco_all_view,
1802 "elm,state,selected", "elm");
1805 if (elm_widget_item_disabled_get(it))
1807 edje_object_signal_emit(VIEW(it),
1808 "elm,state,disabled", "elm");
1809 if (it->deco_all_view)
1810 edje_object_signal_emit(it->deco_all_view,
1811 "elm,state,disabled", "elm");
1813 if (it->item->expanded)
1815 edje_object_signal_emit(VIEW(it),
1816 "elm,state,expanded", "elm");
1817 if (it->deco_all_view)
1818 edje_object_signal_emit(it->deco_all_view,
1819 "elm,state,expanded", "elm");
1825 _item_mode_content_realize(Elm_Gen_Item *it,
1826 Evas_Object *target,
1829 Eina_List **contents_list)
1831 Eina_List *res = *contents_list;
1833 if (it->itc->func.content_get)
1838 EINA_LIST_FOREACH(*source, l, key)
1840 if (parts && fnmatch(parts, key, FNM_PERIOD))
1843 Evas_Object *ic = it->itc->func.content_get
1844 ((void *)it->base.data, WIDGET(it), l->data);
1848 res = eina_list_append(res, ic);
1849 edje_object_part_swallow(target, key, ic);
1850 evas_object_show(ic);
1851 elm_widget_sub_object_add(WIDGET(it), ic);
1852 if (it->item->deco_it_view || it->wd->decorate_all_mode)
1854 if (elm_widget_item_disabled_get(it))
1855 elm_widget_disabled_set(ic, EINA_TRUE);
1865 _item_mode_content_unrealize(Elm_Gen_Item *it,
1866 Evas_Object *target,
1869 Eina_List **contents_list)
1871 Eina_List *res = *contents_list;
1873 if (it->itc->func.content_get)
1877 Evas_Object *ic = NULL;
1879 EINA_LIST_FOREACH(*source, l, key)
1881 if (parts && fnmatch(parts, key, FNM_PERIOD))
1884 ic = edje_object_part_swallow_get(target, key);
1887 res = eina_list_remove(res, ic);
1888 edje_object_part_unswallow(target, ic);
1889 evas_object_del(ic);
1898 _item_cache_free(Item_Cache *itc)
1900 if (itc->spacer) evas_object_del(itc->spacer);
1901 if (itc->base_view) evas_object_del(itc->base_view);
1902 eina_stringshare_del(itc->item_style);
1907 _item_text_realize(Elm_Gen_Item *it,
1908 Evas_Object *target,
1912 if (it->itc->func.text_get)
1918 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1919 EINA_LIST_FOREACH(*source, l, key)
1921 if (parts && fnmatch(parts, key, FNM_PERIOD))
1924 char *s = it->itc->func.text_get
1925 ((void *)it->base.data, WIDGET(it), key);
1929 edje_object_part_text_set(target, key, s);
1934 edje_object_part_text_set(target, key, "");
1941 _item_content_unrealize(Elm_Gen_Item *it,
1942 Evas_Object *target,
1946 Eina_List *res = it->content_objs;
1948 if (it->itc->func.content_get)
1952 Evas_Object *ic = NULL;
1954 EINA_LIST_FOREACH(*source, l, key)
1956 if (parts && fnmatch(parts, key, FNM_PERIOD))
1959 ic = edje_object_part_swallow_get(target, key);
1962 res = eina_list_remove(res, ic);
1963 edje_object_part_unswallow(target, ic);
1964 evas_object_del(ic);
1973 _item_content_realize(Elm_Gen_Item *it,
1974 Evas_Object *target,
1978 Eina_List *res = it->content_objs;
1980 if (it->itc->func.content_get)
1984 Evas_Object *ic = NULL;
1987 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1989 EINA_LIST_FOREACH(*source, l, key)
1991 if (parts && fnmatch(parts, key, FNM_PERIOD))
1994 if (it->itc->func.content_get)
1995 ic = it->itc->func.content_get
1996 ((void *)it->base.data, WIDGET(it), key);
1999 res = eina_list_append(res, ic);
2000 edje_object_part_swallow(target, key, ic);
2001 evas_object_show(ic);
2002 elm_widget_sub_object_add(WIDGET(it), ic);
2003 if (elm_widget_item_disabled_get(it))
2004 elm_widget_disabled_set(ic, EINA_TRUE);
2013 _item_state_realize(Elm_Gen_Item *it,
2014 Evas_Object *target,
2018 if (it->itc->func.state_get)
2025 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2026 EINA_LIST_FOREACH(*source, l, key)
2028 if (parts && fnmatch(parts, key, FNM_PERIOD))
2031 Eina_Bool on = it->itc->func.state_get
2032 ((void *)it->base.data, WIDGET(it), key);
2036 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2037 edje_object_signal_emit(target, buf, "elm");
2041 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2042 edje_object_signal_emit(target, buf, "elm");
2049 _item_realize(Elm_Gen_Item *it,
2053 const char *treesize;
2056 Item_Cache *itc = NULL;
2058 if (it->generation < it->wd->generation) return;
2059 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2062 if (it->item->order_num_in != in)
2064 it->item->order_num_in = in;
2065 _elm_genlist_item_odd_even_update(it);
2066 _elm_genlist_item_state_update(it, NULL);
2067 _elm_genlist_item_index_update(it);
2069 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2070 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2073 it->item->order_num_in = in;
2075 if (it->item->nocache_once)
2076 it->item->nocache_once = EINA_FALSE;
2077 else if (!it->item->nocache)
2078 itc = _item_cache_find(it);
2079 if (itc && (!it->wd->tree_effect_enabled))
2081 VIEW(it) = itc->base_view;
2082 itc->base_view = NULL;
2083 it->spacer = itc->spacer;
2088 const char *stacking_even;
2089 const char *stacking;
2091 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2092 edje_object_scale_set(VIEW(it),
2093 elm_widget_scale_get(WIDGET(it)) *
2094 _elm_config->scale);
2095 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2096 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2098 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2099 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2101 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2103 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2104 elm_widget_style_get(WIDGET(it)));
2106 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2107 if (!stacking_even) stacking_even = "above";
2108 it->item->stacking_even = !!strcmp("above", stacking_even);
2110 stacking = edje_object_data_get(VIEW(it), "stacking");
2111 if (!stacking) stacking = "yes";
2112 it->item->nostacking = !!strcmp("yes", stacking);
2114 edje_object_mirrored_set(VIEW(it),
2115 elm_widget_mirrored_get(WIDGET(it)));
2118 _elm_genlist_item_odd_even_update(it);
2120 treesize = edje_object_data_get(VIEW(it), "treesize");
2121 if (treesize) tsize = atoi(treesize);
2122 if (!it->spacer && treesize)
2125 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2126 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2127 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2131 evas_object_size_hint_min_set(it->spacer,
2132 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2133 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2137 edje_object_signal_callback_add(VIEW(it),
2138 "elm,action,expand,toggle",
2139 "elm", _signal_expand_toggle, it);
2140 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2141 "elm", _signal_expand, it);
2142 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2143 "elm", _signal_contract, it);
2144 _item_mouse_callbacks_add(it, VIEW(it));
2146 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2147 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2148 _decorate_all_item_realize(it, EINA_FALSE);
2150 _elm_genlist_item_state_update(it, itc);
2151 _elm_genlist_item_index_update(it);
2154 if ((calc) && (it->wd->homogeneous) &&
2155 ((it->wd->item_width) ||
2156 ((it->wd->item_width) && (it->wd->group_item_width))))
2158 /* homogenous genlist shortcut */
2159 if (!it->item->mincalcd)
2163 it->item->w = it->item->minw = it->wd->group_item_width;
2164 it->item->h = it->item->minh = it->wd->group_item_height;
2168 it->item->w = it->item->minw = it->wd->item_width;
2169 it->item->h = it->item->minh = it->wd->item_height;
2171 it->item->mincalcd = EINA_TRUE;
2176 /* FIXME: If you see that assert, please notify us and we
2177 will clean our mess */
2178 assert(eina_list_count(it->content_objs) == 0);
2180 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2181 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2182 _item_state_realize(it, VIEW(it), &it->states, NULL);
2185 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2186 if (!(it->item->flip_contents))
2187 it->item->flip_contents =
2188 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2189 it->item->flip_content_objs =
2190 _item_mode_content_realize(it, VIEW(it),
2191 &it->item->flip_contents, NULL,
2192 &it->item->flip_content_objs);
2195 if (!it->item->mincalcd)
2197 Evas_Coord mw = -1, mh = -1;
2199 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2200 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2201 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2202 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2204 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2205 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2206 it->item->w = it->item->minw = mw;
2207 it->item->h = it->item->minh = mh;
2208 it->item->mincalcd = EINA_TRUE;
2210 if ((!it->wd->group_item_width) && (it->group))
2212 it->wd->group_item_width = mw;
2213 it->wd->group_item_height = mh;
2215 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2217 it->wd->item_width = mw;
2218 it->wd->item_height = mh;
2221 if (!calc) evas_object_show(VIEW(it));
2224 if (it->tooltip.content_cb)
2226 elm_widget_item_tooltip_content_cb_set(it,
2227 it->tooltip.content_cb,
2228 it->tooltip.data, NULL);
2229 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2230 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2233 if (it->mouse_cursor)
2234 elm_widget_item_cursor_set(it, it->mouse_cursor);
2236 it->realized = EINA_TRUE;
2237 it->want_unrealize = EINA_FALSE;
2239 if (itc) _item_cache_free(itc);
2240 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2241 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2244 if (it->item->tree_effect_hideme)
2246 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2247 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2248 it->item->tree_effect_hideme = EINA_FALSE;
2250 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2253 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2255 if (it->itc->decorate_all_item_style)
2257 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2258 edje_object_message_signal_process(it->deco_all_view);
2261 edje_object_message_signal_process(VIEW(it));
2265 _item_unrealize_cb(Elm_Gen_Item *it)
2267 Evas_Object *content;
2268 elm_widget_stringlist_free(it->item->flip_contents);
2269 it->item->flip_contents = NULL;
2270 EINA_LIST_FREE(it->item->flip_content_objs, content)
2271 evas_object_del(content);
2273 if (it->item->nocache_once || it->item->nocache)
2275 evas_object_del(VIEW(it));
2279 evas_object_del(it->spacer);
2285 edje_object_mirrored_set(VIEW(it),
2286 elm_widget_mirrored_get(WIDGET(it)));
2287 edje_object_scale_set(VIEW(it),
2288 elm_widget_scale_get(WIDGET(it))
2289 * _elm_config->scale);
2290 _item_cache_add(it);
2293 _decorate_item_unrealize(it);
2295 it->realized = EINA_FALSE;
2296 it->want_unrealize = EINA_FALSE;
2297 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2301 _item_block_recalc(Item_Block *itb,
2307 Evas_Coord minw = 0, minh = 0;
2308 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2311 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2313 EINA_LIST_FOREACH(itb->items, l, it)
2315 if (it->generation < it->wd->generation) continue;
2316 showme |= it->item->showme;
2321 if (!it->item->mincalcd) changed = EINA_TRUE;
2324 _item_realize(it, in, EINA_TRUE);
2325 _elm_genlist_item_unrealize(it, EINA_TRUE);
2330 _item_realize(it, in, EINA_TRUE);
2331 _elm_genlist_item_unrealize(it, EINA_TRUE);
2336 if (!it->item->mincalcd) changed = EINA_TRUE;
2337 _item_realize(it, in, EINA_FALSE);
2339 minh += it->item->minh;
2340 if (minw < it->item->minw) minw = it->item->minw;
2346 if (changed) itb->wd->pan_changed = changed;
2349 itb->changed = EINA_FALSE;
2350 itb->position_update = EINA_FALSE;
2351 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2352 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2357 _item_block_realize(Item_Block *itb)
2359 if (itb->realized) return;
2360 itb->realized = EINA_TRUE;
2361 itb->want_unrealize = EINA_FALSE;
2365 _item_block_unrealize(Item_Block *itb)
2369 Eina_Bool dragging = EINA_FALSE;
2371 if (!itb->realized) return;
2372 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2373 EINA_LIST_FOREACH(itb->items, l, it)
2375 if (itb->must_recalc || !it->group)
2379 dragging = EINA_TRUE;
2380 it->want_unrealize = EINA_TRUE;
2383 _elm_genlist_item_unrealize(it, EINA_FALSE);
2388 itb->realized = EINA_FALSE;
2389 itb->want_unrealize = EINA_TRUE;
2392 itb->want_unrealize = EINA_FALSE;
2393 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2394 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2398 _get_space_for_reorder_item(Elm_Gen_Item *it)
2400 Evas_Coord rox, roy, row, roh, oy, oh;
2401 Eina_Bool top = EINA_FALSE;
2402 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2403 if (!reorder_it) return 0;
2405 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2406 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2408 if ((it->wd->reorder_start_y < it->item->block->y) &&
2409 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2411 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2412 if (it->item->block->count == 1)
2413 it->wd->reorder_rel = it;
2415 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2416 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2418 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2421 it->item->block->reorder_offset = 0;
2423 it->item->scrl_y += it->item->block->reorder_offset;
2425 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2426 rox, roy + (roh / 2), row, 1));
2429 it->wd->reorder_rel = it;
2430 it->item->scrl_y += it->wd->reorder_it->item->h;
2431 return it->wd->reorder_it->item->h;
2438 _reorder_move_animator_cb(void *data)
2440 Elm_Gen_Item *it = data;
2441 Eina_Bool down = EINA_FALSE;
2443 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2445 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2447 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2450 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2451 if (diff > it->item->h) y = diff / 2;
2453 if (it->item->old_scrl_y < it->item->scrl_y)
2455 it->item->old_scrl_y += y;
2458 else if (it->item->old_scrl_y > it->item->scrl_y)
2460 it->item->old_scrl_y -= y;
2464 if (it->deco_all_view)
2465 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2467 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2468 _group_items_recalc(it->wd);
2470 if ((it->wd->reorder_pan_move) ||
2471 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2472 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2474 it->item->old_scrl_y = it->item->scrl_y;
2475 it->item->move_effect_enabled = EINA_FALSE;
2476 it->wd->reorder_move_animator = NULL;
2477 return ECORE_CALLBACK_CANCEL;
2479 return ECORE_CALLBACK_RENEW;
2483 _item_position(Elm_Gen_Item *it,
2491 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2492 evas_object_resize(view, it->item->w, it->item->h);
2493 evas_object_move(view, it_x, it_y);
2494 evas_object_show(view);
2495 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2496 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2500 _item_block_position(Item_Block *itb,
2506 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2507 Eina_Bool vis = EINA_FALSE;
2509 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2510 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2511 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2513 EINA_LIST_FOREACH(itb->items, l, it)
2515 if (it->generation < it->wd->generation) continue;
2516 else if (it->wd->reorder_it == it) continue;
2519 it->item->w = itb->w;
2520 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2521 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2523 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2524 cvx, cvy, cvw, cvh));
2527 if ((itb->realized) && (!it->realized))
2529 if (vis) _item_realize(it, in, EINA_FALSE);
2533 if (vis || it->dragging)
2535 if (it->wd->reorder_mode)
2536 y += _get_space_for_reorder_item(it);
2537 git = it->item->group_item;
2540 if (git->item->scrl_y < oy)
2541 git->item->scrl_y = oy;
2542 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2543 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2544 git->item->want_realize = EINA_TRUE;
2546 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2548 if (!it->item->move_effect_enabled)
2550 it->item->move_effect_enabled = EINA_TRUE;
2551 it->wd->reorder_move_animator =
2553 _reorder_move_animator_cb, it);
2556 if (!it->item->move_effect_enabled)
2558 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2559 _decorate_all_item_position(it, it->item->scrl_x,
2563 if (!it->wd->tree_effect_enabled ||
2564 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2565 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2566 (it->item->old_scrl_y == it->item->scrl_y)))
2568 if (it->item->deco_it_view)
2569 _item_position(it, it->item->deco_it_view,
2573 _item_position(it, VIEW(it), it->item->scrl_x,
2577 it->item->old_scrl_y = it->item->scrl_y;
2582 if (!it->wd->tree_effect_animator)
2583 _elm_genlist_item_unrealize(it, EINA_FALSE);
2590 if (vis) it->item->want_realize = EINA_TRUE;
2594 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2595 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2599 _group_items_recalc(void *data)
2601 Widget_Data *wd = data;
2605 evas_event_freeze(evas_object_evas_get(wd->obj));
2606 EINA_LIST_FOREACH(wd->group_items, l, git)
2608 if (git->item->want_realize)
2611 _item_realize(git, 0, EINA_FALSE);
2612 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2613 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2614 evas_object_show(VIEW(git));
2615 evas_object_raise(VIEW(git));
2617 else if (!git->item->want_realize && git->realized)
2620 _elm_genlist_item_unrealize(git, EINA_FALSE);
2623 evas_event_thaw(evas_object_evas_get(wd->obj));
2624 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2628 _must_recalc_idler(void *data)
2630 Widget_Data *wd = data;
2631 if (wd->calc_job) ecore_job_del(wd->calc_job);
2632 wd->calc_job = ecore_job_add(_calc_job, wd);
2633 wd->must_recalc_idler = NULL;
2634 return ECORE_CALLBACK_CANCEL;
2638 _scroll_item(Widget_Data *wd)
2640 Elm_Gen_Item *it = NULL;
2641 Evas_Coord gith = 0;
2642 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2643 if (!wd->show_item) return;
2645 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2647 dx = it->x + it->item->block->x;
2648 dy = it->y + it->item->block->y;
2649 dw = it->item->block->w;
2651 switch (wd->scrollto_type)
2653 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2654 if (it->item->group_item) gith = it->item->group_item->item->h;
2657 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2658 dy += ((it->item->h / 2) - (oh / 2));
2660 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2662 if ((wd->expanded_item) &&
2663 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2664 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2666 it = wd->expanded_item;
2667 if (it->item->group_item) gith = it->item->group_item->item->h;
2668 dx = it->x + it->item->block->x;
2669 dy = it->y + it->item->block->y - gith;
2670 dw = it->item->block->w;
2674 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2675 gith = it->item->group_item->item->h;
2682 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2684 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2686 it->item->showme = EINA_FALSE;
2687 wd->show_item = NULL;
2688 wd->auto_scroll_enabled = EINA_FALSE;
2689 wd->check_scroll = EINA_FALSE;
2693 _calc_job(void *data)
2695 Widget_Data *wd = data;
2696 Item_Block *itb, *chb = NULL;
2697 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2698 Evas_Coord pan_w = 0, pan_h = 0;
2700 Eina_Bool minw_change = EINA_FALSE;
2701 Eina_Bool did_must_recalc = EINA_FALSE;
2704 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2705 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2710 evas_event_freeze(evas_object_evas_get(wd->obj));
2711 EINA_INLIST_FOREACH(wd->blocks, itb)
2713 Eina_Bool showme = EINA_FALSE;
2716 showme = itb->showme;
2717 itb->showme = EINA_FALSE;
2720 if (itb->realized) _item_block_unrealize(itb);
2722 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2724 if (itb->must_recalc)
2728 EINA_LIST_FOREACH(itb->items, l, it)
2729 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2730 itb->changed = EINA_TRUE;
2731 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2732 if (itb->realized) _item_block_unrealize(itb);
2733 itb->must_recalc = EINA_FALSE;
2735 showme = _item_block_recalc(itb, in, EINA_FALSE);
2741 if (minw == -1) minw = itb->minw;
2742 else if ((!itb->must_recalc) && (minw < itb->minw))
2745 minw_change = EINA_TRUE;
2750 minw_change = EINA_TRUE;
2756 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2757 wd->check_scroll = EINA_TRUE;
2761 EINA_INLIST_FOREACH(wd->blocks, itb)
2767 if ((chb) && (EINA_INLIST_GET(chb)->next))
2769 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2771 if (itb->realized) _item_block_unrealize(itb);
2774 wd->realminw = minw;
2775 if (minw < wd->w) minw = wd->w;
2776 if ((minw != wd->minw) || (minh != wd->minh))
2780 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2781 _sizing_eval(wd->obj);
2782 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2787 it = wd->anchor_item;
2788 it_y = wd->anchor_y;
2789 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2790 it->item->block->y + it->y + it_y);
2791 wd->anchor_item = it;
2792 wd->anchor_y = it_y;
2795 if (did_must_recalc)
2797 if (!wd->must_recalc_idler)
2798 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2800 if (wd->check_scroll)
2802 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2803 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2804 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2805 switch (wd->scrollto_type)
2807 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2810 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2813 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2820 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2821 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2827 wd->calc_job = NULL;
2828 evas_object_smart_changed(wd->pan_smart);
2829 evas_event_thaw(evas_object_evas_get(wd->obj));
2830 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2834 _update_job(void *data)
2836 Widget_Data *wd = data;
2840 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2842 wd->update_job = NULL;
2845 evas_event_freeze(evas_object_evas_get(wd->obj));
2846 EINA_INLIST_FOREACH(wd->blocks, itb)
2848 Evas_Coord itminw, itminh;
2855 _item_block_position(itb, num);
2859 recalc = EINA_FALSE;
2860 EINA_LIST_FOREACH(itb->items, l2, it)
2862 if (it->item->updateme)
2864 itminw = it->item->minw;
2865 itminh = it->item->minh;
2867 it->item->updateme = EINA_FALSE;
2870 _elm_genlist_item_unrealize(it, EINA_FALSE);
2871 _item_realize(it, num, EINA_FALSE);
2872 position = EINA_TRUE;
2876 _item_realize(it, num, EINA_TRUE);
2877 _elm_genlist_item_unrealize(it, EINA_TRUE);
2879 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2884 itb->updateme = EINA_FALSE;
2887 position = EINA_TRUE;
2888 itb->changed = EINA_TRUE;
2889 _item_block_recalc(itb, num0, EINA_FALSE);
2890 _item_block_position(itb, num0);
2895 if (wd->calc_job) ecore_job_del(wd->calc_job);
2896 wd->calc_job = ecore_job_add(_calc_job, wd);
2898 evas_event_thaw(evas_object_evas_get(wd->obj));
2899 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2903 _pan_set(Evas_Object *obj,
2907 Pan *sd = evas_object_smart_data_get(obj);
2911 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2915 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2917 if ((itb->y + itb->h) > y)
2922 EINA_LIST_FOREACH(itb->items, l2, it)
2924 if ((itb->y + it->y) >= y)
2926 sd->wd->anchor_item = it;
2927 sd->wd->anchor_y = -(itb->y + it->y - y);
2934 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2938 _pan_get(Evas_Object *obj,
2942 Pan *sd = evas_object_smart_data_get(obj);
2945 if (x) *x = sd->wd->pan_x;
2946 if (y) *y = sd->wd->pan_y;
2950 _pan_max_get(Evas_Object *obj,
2954 Pan *sd = evas_object_smart_data_get(obj);
2958 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2959 ow = sd->wd->minw - ow;
2961 oh = sd->wd->minh - oh;
2968 _pan_min_get(Evas_Object *obj __UNUSED__,
2977 _pan_child_size_get(Evas_Object *obj,
2981 Pan *sd = evas_object_smart_data_get(obj);
2984 if (w) *w = sd->wd->minw;
2985 if (h) *h = sd->wd->minh;
2989 _pan_add(Evas_Object *obj)
2992 Evas_Object_Smart_Clipped_Data *cd;
2995 cd = evas_object_smart_data_get(obj);
2998 sd->__clipped_data = *cd;
3000 evas_object_smart_data_set(obj, sd);
3004 _pan_del(Evas_Object *obj)
3006 Pan *sd = evas_object_smart_data_get(obj);
3011 ecore_job_del(sd->resize_job);
3012 sd->resize_job = NULL;
3018 _pan_resize_job(void *data)
3022 _sizing_eval(sd->wd->obj);
3023 sd->resize_job = NULL;
3027 _pan_resize(Evas_Object *obj,
3031 Pan *sd = evas_object_smart_data_get(obj);
3035 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3036 if ((ow == w) && (oh == h)) return;
3037 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3040 if (sd->resize_job) ecore_job_del(sd->resize_job);
3041 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3043 sd->wd->pan_changed = EINA_TRUE;
3044 evas_object_smart_changed(obj);
3045 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3046 sd->wd->calc_job = NULL;
3050 _pan_calculate(Evas_Object *obj)
3052 Pan *sd = evas_object_smart_data_get(obj);
3054 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3060 evas_event_freeze(evas_object_evas_get(obj));
3062 if (sd->wd->pan_changed)
3065 sd->wd->pan_changed = EINA_FALSE;
3068 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3069 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3070 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3072 git->item->want_realize = EINA_FALSE;
3075 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3077 if (!sd->wd->tree_effect_animator)
3079 _item_tree_effect_before(sd->wd->expanded_item);
3080 evas_object_raise(sd->wd->alpha_bg);
3081 evas_object_show(sd->wd->alpha_bg);
3082 sd->wd->start_time = ecore_time_get();
3083 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3087 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3089 itb->w = sd->wd->minw;
3090 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3091 itb->y - sd->wd->pan_y + oy,
3093 cvx, cvy, cvw, cvh))
3095 if ((!itb->realized) || (itb->changed))
3096 _item_block_realize(itb);
3097 _item_block_position(itb, in);
3101 if (itb->realized) _item_block_unrealize(itb);
3105 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3106 _group_items_recalc(sd->wd);
3107 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3109 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3110 sd->wd->reorder_pan_move = EINA_TRUE;
3111 else sd->wd->reorder_pan_move = EINA_FALSE;
3112 evas_object_raise(sd->wd->VIEW(reorder_it));
3113 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3114 sd->wd->start_time = ecore_loop_time_get();
3117 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3118 _item_auto_scroll(sd->wd);
3120 evas_event_thaw(evas_object_evas_get(obj));
3121 evas_event_thaw_eval(evas_object_evas_get(obj));
3125 _pan_move(Evas_Object *obj,
3126 Evas_Coord x __UNUSED__,
3127 Evas_Coord y __UNUSED__)
3129 Pan *sd = evas_object_smart_data_get(obj);
3133 sd->wd->pan_changed = EINA_TRUE;
3134 evas_object_smart_changed(obj);
3135 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3136 sd->wd->calc_job = NULL;
3140 _hold_on(void *data __UNUSED__,
3142 void *event_info __UNUSED__)
3144 Widget_Data *wd = elm_widget_data_get(obj);
3146 elm_smart_scroller_hold_set(wd->scr, 1);
3150 _hold_off(void *data __UNUSED__,
3152 void *event_info __UNUSED__)
3154 Widget_Data *wd = elm_widget_data_get(obj);
3156 elm_smart_scroller_hold_set(wd->scr, 0);
3160 _freeze_on(void *data __UNUSED__,
3162 void *event_info __UNUSED__)
3164 Widget_Data *wd = elm_widget_data_get(obj);
3166 elm_smart_scroller_freeze_set(wd->scr, 1);
3170 _freeze_off(void *data __UNUSED__,
3172 void *event_info __UNUSED__)
3174 Widget_Data *wd = elm_widget_data_get(obj);
3176 elm_smart_scroller_freeze_set(wd->scr, 0);
3180 _scr_anim_start(void *data,
3181 Evas_Object *obj __UNUSED__,
3182 void *event_info __UNUSED__)
3184 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3188 _scr_anim_stop(void *data,
3189 Evas_Object *obj __UNUSED__,
3190 void *event_info __UNUSED__)
3192 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3196 _scr_drag_start(void *data,
3197 Evas_Object *obj __UNUSED__,
3198 void *event_info __UNUSED__)
3200 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3204 _scr_drag_stop(void *data,
3205 Evas_Object *obj __UNUSED__,
3206 void *event_info __UNUSED__)
3208 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3212 _edge_left(void *data,
3213 Evas_Object *scr __UNUSED__,
3214 void *event_info __UNUSED__)
3216 Evas_Object *obj = data;
3217 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3221 _edge_right(void *data,
3222 Evas_Object *scr __UNUSED__,
3223 void *event_info __UNUSED__)
3225 Evas_Object *obj = data;
3226 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3230 _edge_top(void *data,
3231 Evas_Object *scr __UNUSED__,
3232 void *event_info __UNUSED__)
3234 Evas_Object *obj = data;
3235 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3239 _edge_bottom(void *data,
3240 Evas_Object *scr __UNUSED__,
3241 void *event_info __UNUSED__)
3243 Evas_Object *obj = data;
3244 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3248 _decorate_item_realize(Elm_Gen_Item *it)
3252 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3254 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3255 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3256 edje_object_scale_set(it->item->deco_it_view,
3257 elm_widget_scale_get(WIDGET(it)) *
3258 _elm_config->scale);
3259 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3260 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3262 strncpy(buf, "item", sizeof(buf));
3263 if (it->wd->mode == ELM_LIST_COMPRESS)
3264 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3266 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3267 strncat(buf, "/", sizeof(buf) - strlen(buf));
3268 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3270 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3271 elm_widget_style_get(WIDGET(it)));
3272 edje_object_mirrored_set(it->item->deco_it_view,
3273 elm_widget_mirrored_get(WIDGET(it)));
3275 /* signal callback add */
3276 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3278 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3280 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3283 /* text_get, content_get, state_get */
3284 /* FIXME: If you see that assert, please notify us and we
3285 will clean our mess */
3286 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3288 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3289 if (!it->item->deco_it_contents)
3290 it->item->deco_it_contents =
3291 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3292 it->item->deco_it_content_objs =
3293 _item_mode_content_realize(it, it->item->deco_it_view,
3294 &it->item->deco_it_contents, NULL,
3295 &it->item->deco_it_content_objs);
3296 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3297 edje_object_part_swallow(it->item->deco_it_view,
3298 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3301 it->want_unrealize = EINA_FALSE;
3302 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3303 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3307 _decorate_item_unrealize(Elm_Gen_Item *it)
3309 Widget_Data *wd = it->wd;
3310 Evas_Object *content;
3311 if (!it->item->deco_it_view) return;
3313 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3314 elm_widget_stringlist_free(it->item->deco_it_texts);
3315 it->item->deco_it_texts = NULL;
3316 elm_widget_stringlist_free(it->item->deco_it_contents);
3317 it->item->deco_it_contents = NULL;
3318 elm_widget_stringlist_free(it->item->deco_it_states);
3320 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3321 evas_object_del(content);
3323 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3324 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3325 evas_object_del(it->item->deco_it_view);
3326 it->item->deco_it_view = NULL;
3328 if (wd->mode_item == it)
3329 wd->mode_item = NULL;
3330 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3331 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3335 _decorate_item_set(Elm_Gen_Item *it)
3338 Widget_Data *wd = it->wd;
3343 it->item->nocache_once = EINA_TRUE;
3345 if (wd->scr_hold_timer)
3347 ecore_timer_del(wd->scr_hold_timer);
3348 wd->scr_hold_timer = NULL;
3350 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3351 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3353 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3354 _decorate_item_realize(it);
3355 if (it->item->group_item)
3356 evas_object_raise(it->item->VIEW(group_item));
3357 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3358 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3359 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3361 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3362 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3366 _decorate_item_unset(Widget_Data *wd)
3369 if (!wd->mode_item) return;
3370 char buf[1024], buf2[1024];
3374 it->item->nocache_once = EINA_TRUE;
3376 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3377 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3379 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3380 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3382 wd->mode_item = NULL;
3386 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3388 if ((!it) || (!it->wd->decorate_all_mode)) return;
3389 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3390 evas_object_move(it->deco_all_view, itx, ity);
3394 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3397 const char *stacking_even;
3398 const char *stacking;
3400 if ((!it) || (it->item->decorate_all_item_realized) ||
3401 (it->generation < it->wd->generation))
3404 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3405 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3406 _elm_config->scale);
3407 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3408 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3410 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3411 strncpy(buf, "tree", sizeof(buf));
3412 else strncpy(buf, "item", sizeof(buf));
3413 if (it->wd->mode == ELM_LIST_COMPRESS)
3414 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3416 strncat(buf, "/", sizeof(buf) - strlen(buf));
3417 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3419 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3420 elm_widget_style_get(WIDGET(it)));
3422 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3423 if (!stacking_even) stacking_even = "above";
3424 it->item->stacking_even = !!strcmp("above", stacking_even);
3426 stacking = edje_object_data_get(VIEW(it), "stacking");
3427 if (!stacking) stacking = "yes";
3428 it->item->nostacking = !!strcmp("yes", stacking);
3430 edje_object_mirrored_set(it->deco_all_view,
3431 elm_widget_mirrored_get(WIDGET(it)));
3433 _elm_genlist_item_odd_even_update(it);
3434 _elm_genlist_item_state_update(it, NULL);
3436 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3437 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3439 _item_mouse_callbacks_del(it, VIEW(it));
3440 _item_mouse_callbacks_add(it, it->deco_all_view);
3442 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3443 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3444 if (!it->item->deco_all_contents)
3445 it->item->deco_all_contents =
3446 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "contents"));
3447 it->item->deco_all_content_objs =
3448 _item_mode_content_realize(it, it->deco_all_view,
3449 &it->item->deco_all_contents, NULL,
3450 &it->item->deco_all_content_objs);
3451 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3452 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3454 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3455 evas_object_show(it->deco_all_view);
3457 if (it->selected) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
3459 it->item->decorate_all_item_realized = EINA_TRUE;
3460 it->want_unrealize = EINA_FALSE;
3464 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3467 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3469 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3470 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3471 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3472 _elm_genlist_item_odd_even_update(it);
3473 _elm_genlist_item_state_update(it, NULL);
3475 evas_object_del(it->deco_all_view);
3476 it->deco_all_view = NULL;
3477 elm_widget_stringlist_free(it->item->deco_all_texts);
3478 it->item->deco_all_texts = NULL;
3479 elm_widget_stringlist_free(it->item->deco_all_contents);
3480 it->item->deco_all_contents = NULL;
3481 elm_widget_stringlist_free(it->item->deco_all_states);
3482 it->item->deco_all_states = NULL;
3483 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3484 evas_object_del(icon);
3485 edje_object_message_signal_process(it->deco_all_view);
3486 _item_mouse_callbacks_del(it, it->deco_all_view);
3487 _item_mouse_callbacks_add(it, VIEW(it));
3489 it->item->decorate_all_item_realized = EINA_FALSE;
3493 _item_auto_scroll(Widget_Data *wd)
3496 Elm_Gen_Item *tmp_item = NULL;
3498 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3500 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3501 if (!tmp_item) return;
3502 wd->show_item = tmp_item;
3503 wd->bring_in = EINA_TRUE;
3504 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3505 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3507 wd->show_item->item->showme = EINA_TRUE;
3508 wd->auto_scroll_enabled = EINA_FALSE;
3516 elm_genlist_add(Evas_Object *parent)
3521 Evas_Coord minw, minh;
3522 static Evas_Smart *smart = NULL;
3526 static Evas_Smart_Class sc;
3528 evas_object_smart_clipped_smart_set(&_pan_sc);
3530 sc.name = "elm_genlist_pan";
3531 sc.version = EVAS_SMART_CLASS_VERSION;
3534 sc.resize = _pan_resize;
3535 sc.move = _pan_move;
3536 sc.calculate = _pan_calculate;
3537 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3540 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3542 ELM_SET_WIDTYPE(widtype, "genlist");
3544 elm_widget_type_set(obj, "genlist");
3545 elm_widget_sub_object_add(parent, obj);
3546 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3547 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3548 elm_widget_data_set(obj, wd);
3549 elm_widget_del_hook_set(obj, _del_hook);
3550 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3551 elm_widget_theme_hook_set(obj, _theme_hook);
3552 elm_widget_can_focus_set(obj, EINA_TRUE);
3553 elm_widget_event_hook_set(obj, _event_hook);
3554 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3555 elm_widget_translate_hook_set(obj, _translate_hook);
3558 wd->scr = elm_smart_scroller_add(e);
3559 elm_smart_scroller_widget_set(wd->scr, obj);
3560 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3561 elm_widget_style_get(obj));
3562 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3563 _elm_config->thumbscroll_bounce_enable);
3564 elm_widget_resize_object_set(obj, wd->scr);
3566 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3567 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3568 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3569 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3570 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3571 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3572 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3573 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3576 wd->mode = ELM_LIST_SCROLL;
3577 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3578 wd->item_cache_max = wd->max_items_per_block * 2;
3579 wd->longpress_timeout = _elm_config->longpress_timeout;
3580 wd->highlight = EINA_TRUE;
3582 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3583 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3584 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3585 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3587 wd->pan_smart = evas_object_smart_add(e, smart);
3588 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3591 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3592 _pan_set, _pan_get, _pan_max_get,
3593 _pan_min_get, _pan_child_size_get);
3595 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3597 evas_object_size_hint_min_set(obj, minw, minh);
3599 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3601 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3607 _item_select(Elm_Gen_Item *it)
3609 Evas_Object *obj = WIDGET(it);
3611 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3612 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3613 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3617 it->selected = EINA_TRUE;
3618 it->wd->selected = eina_list_append(it->wd->selected, it);
3620 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3622 evas_object_ref(obj);
3625 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3626 if (it->generation == it->wd->generation)
3627 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3630 if ((it->wd->clear_me) && (!it->wd->walking))
3631 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3634 if ((!it->walking) && (it->generation < it->wd->generation))
3639 elm_widget_item_free(it);
3643 it->wd->last_selected_item = (Elm_Object_Item *)it;
3645 evas_object_unref(obj);
3648 static Evas_Object *
3649 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3651 return edje_object_part_swallow_get(VIEW(it), part);
3655 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
3657 if (!it->itc->func.text_get) return NULL;
3658 return edje_object_part_text_get(VIEW(it), part);
3662 _item_disable_hook(Elm_Object_Item *it)
3666 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3668 if (_it->generation < _it->wd->generation) return;
3671 elm_genlist_item_selected_set(it, EINA_FALSE);
3675 if (elm_widget_item_disabled_get(it))
3677 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
3678 if (_it->deco_all_view)
3679 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
3683 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
3684 if (_it->deco_all_view)
3685 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
3687 EINA_LIST_FOREACH(_it->content_objs, l, obj)
3688 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
3693 _item_del_pre_hook(Elm_Object_Item *it)
3695 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3697 if ((_it->relcount > 0) || (_it->walking > 0))
3699 elm_genlist_item_subitems_clear(it);
3700 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
3701 _elm_genlist_item_del_notserious(_it);
3702 if (_it->item->block)
3704 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
3705 _it->item->block->changed = EINA_TRUE;
3706 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
3707 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
3711 _it->parent->item->items =
3712 eina_list_remove(_it->parent->item->items, it);
3722 _item_signal_emit_hook(Elm_Object_Item *it,
3723 const char *emission,
3726 edje_object_signal_emit(VIEW(it), emission, source);
3730 _elm_genlist_item_new(Widget_Data *wd,
3731 const Elm_Gen_Item_Class *itc,
3733 Elm_Gen_Item *parent,
3735 const void *func_data)
3739 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3740 if (!it) return NULL;
3742 it->generation = wd->generation;
3744 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
3745 it->base.data = data;
3746 it->parent = parent;
3747 it->func.func = func;
3748 it->func.data = func_data;
3749 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3750 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
3751 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3752 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3753 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
3756 it->sel_cb = (Ecore_Cb)_item_select;
3761 static Elm_Gen_Item *
3762 _item_new(Widget_Data *wd,
3763 const Elm_Genlist_Item_Class *itc,
3765 Elm_Gen_Item *parent,
3766 Elm_Genlist_Item_Type type,
3768 const void *func_data)
3770 Elm_Gen_Item *it, *it2;
3773 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3774 if (!it) return NULL;
3775 it->item = ELM_NEW(Elm_Gen_Item_Type);
3776 it->item->type = type;
3777 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
3778 it->item->expanded_depth = 0;
3779 ELM_GEN_ITEM_SETUP(it);
3782 if (it->parent->group)
3783 it->item->group_item = parent;
3784 else if (it->parent->item->group_item)
3785 it->item->group_item = it->parent->item->group_item;
3787 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3789 if (!it2->parent->group) depth += 1;
3791 it->item->expanded_depth = depth;
3797 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3801 itb = calloc(1, sizeof(Item_Block));
3802 if (!itb) return NULL;
3806 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3807 _item_block_position_update(wd->blocks, 0);
3811 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3812 itb->position_update = EINA_TRUE;
3813 if (wd->blocks != EINA_INLIST_GET(itb))
3815 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3826 _item_block_add(Widget_Data *wd,
3829 Item_Block *itb = NULL;
3836 itb = calloc(1, sizeof(Item_Block));
3837 if (!itb) return EINA_FALSE;
3839 if (!it->item->rel->item->block)
3842 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3843 itb->items = eina_list_append(itb->items, it);
3844 itb->position_update = EINA_TRUE;
3845 it->position = eina_list_count(itb->items);
3846 it->position_update = EINA_TRUE;
3848 if (wd->blocks != EINA_INLIST_GET(itb))
3850 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3861 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3862 if (it->item->before)
3864 wd->blocks = eina_inlist_prepend_relative
3865 (wd->blocks, EINA_INLIST_GET(itb),
3866 EINA_INLIST_GET(it->item->rel->item->block));
3868 eina_list_prepend_relative_list(itb->items, it, tmp);
3870 /* Update index from where we prepended */
3871 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3872 _item_block_position_update(EINA_INLIST_GET(itb),
3873 it->item->rel->item->block->position);
3877 wd->blocks = eina_inlist_append_relative
3878 (wd->blocks, EINA_INLIST_GET(itb),
3879 EINA_INLIST_GET(it->item->rel->item->block));
3881 eina_list_append_relative_list(itb->items, it, tmp);
3883 /* Update block index from where we appended */
3884 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3885 _item_block_position_update(EINA_INLIST_GET(itb),
3886 it->item->rel->item->block->position + 1);
3892 if (it->item->before)
3896 itb = (Item_Block *)(wd->blocks);
3897 if (itb->count >= wd->max_items_per_block)
3899 itb = _item_block_new(wd, EINA_TRUE);
3900 if (!itb) return EINA_FALSE;
3905 itb = _item_block_new(wd, EINA_TRUE);
3906 if (!itb) return EINA_FALSE;
3908 itb->items = eina_list_prepend(itb->items, it);
3910 _item_position_update(itb->items, 0);
3916 itb = (Item_Block *)(wd->blocks->last);
3917 if (itb->count >= wd->max_items_per_block)
3919 itb = _item_block_new(wd, EINA_FALSE);
3920 if (!itb) return EINA_FALSE;
3925 itb = _item_block_new(wd, EINA_FALSE);
3926 if (!itb) return EINA_FALSE;
3928 itb->items = eina_list_append(itb->items, it);
3929 it->position = eina_list_count(itb->items);
3937 if (it->item->rel->item->queued)
3939 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3940 on sorted insertion order, so the queue is not always ordered like the item list.
3941 This lead to issue where we depend on an item that is not yet created. As a quick
3942 work around, we reschedule the calc of the item and stop reordering the list to
3943 prevent any nasty issue to show up here.
3945 wd->queue = eina_list_append(wd->queue, it);
3946 wd->requeued = EINA_TRUE;
3947 it->item->queued = EINA_TRUE;
3950 itb = it->item->rel->item->block;
3951 if (!itb) goto newblock;
3952 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3953 if (it->item->before)
3955 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3956 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3960 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3961 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3965 itb->changed = EINA_TRUE;
3966 it->item->block = itb;
3967 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3968 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3971 it->item->rel->relcount--;
3972 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3974 _item_del(it->item->rel);
3975 elm_widget_item_free(it->item->rel);
3977 it->item->rel = NULL;
3979 if (itb->count > itb->wd->max_items_per_block)
3984 Eina_Bool done = EINA_FALSE;
3986 newc = itb->count / 2;
3988 if (EINA_INLIST_GET(itb)->prev)
3990 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3992 if (itbp->count + newc < wd->max_items_per_block / 2)
3994 /* moving items to previous block */
3995 while ((itb->count > newc) && (itb->items))
3997 it2 = eina_list_data_get(itb->items);
3998 itb->items = eina_list_remove_list(itb->items, itb->items);
4001 itbp->items = eina_list_append(itbp->items, it2);
4002 it2->item->block = itbp;
4010 if (!done && EINA_INLIST_GET(itb)->next)
4012 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4014 if (itbn->count + newc < wd->max_items_per_block / 2)
4016 /* moving items to next block */
4017 while ((itb->count > newc) && (itb->items))
4021 l = eina_list_last(itb->items);
4022 it2 = eina_list_data_get(l);
4023 itb->items = eina_list_remove_list(itb->items, l);
4026 itbn->items = eina_list_prepend(itbn->items, it2);
4027 it2->item->block = itbn;
4037 /* moving items to new block */
4038 itb2 = calloc(1, sizeof(Item_Block));
4039 if (!itb2) return EINA_FALSE;
4042 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4043 EINA_INLIST_GET(itb));
4044 itb2->changed = EINA_TRUE;
4045 while ((itb->count > newc) && (itb->items))
4049 l = eina_list_last(itb->items);
4051 itb->items = eina_list_remove_list(itb->items, l);
4054 itb2->items = eina_list_prepend(itb2->items, it2);
4055 it2->item->block = itb2;
4065 _queue_process(Widget_Data *wd)
4068 Eina_Bool showme = EINA_FALSE;
4071 t0 = ecore_loop_time_get();
4072 //evas_event_freeze(evas_object_evas_get(wd->obj));
4073 for (n = 0; (wd->queue) && (n < 128); n++)
4077 it = eina_list_data_get(wd->queue);
4078 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4079 it->item->queued = EINA_FALSE;
4080 if (!_item_block_add(wd, it)) continue;
4082 _item_block_realize(it->item->block);
4083 t = ecore_time_get();
4084 if (it->item->block->changed)
4086 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4087 it->item->block->changed = 0;
4088 if (wd->pan_changed)
4090 if (wd->calc_job) ecore_job_del(wd->calc_job);
4091 wd->calc_job = NULL;
4093 wd->pan_changed = EINA_FALSE;
4096 if (showme) it->item->block->showme = EINA_TRUE;
4097 /* same as eina_inlist_count > 1 */
4098 if (wd->blocks && wd->blocks->next)
4100 if ((t - t0) > (ecore_animator_frametime_get())) break;
4103 //evas_event_thaw(evas_object_evas_get(wd->obj));
4104 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4109 _idle_process(void *data, Eina_Bool *wakeup)
4111 Widget_Data *wd = data;
4114 //static double q_start = 0.0;
4115 //if (q_start == 0.0) q_start = ecore_time_get();
4117 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4121 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4123 return ECORE_CALLBACK_CANCEL;
4125 return ECORE_CALLBACK_RENEW;
4129 _item_idle_enterer(void *data)
4131 Widget_Data *wd = data;
4132 Eina_Bool wakeup = EINA_FALSE;
4133 Eina_Bool ok = _idle_process(data, &wakeup);
4138 if (wd->calc_job) ecore_job_del(wd->calc_job);
4139 wd->calc_job = ecore_job_add(_calc_job, wd);
4141 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4146 _item_queue(Widget_Data *wd,
4150 if (it->item->queued) return;
4151 it->item->queued = EINA_TRUE;
4152 if (cb && !wd->requeued)
4153 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4155 wd->queue = eina_list_append(wd->queue, it);
4156 // FIXME: why does a freeze then thaw here cause some genlist
4157 // elm_genlist_item_append() to be much much slower?
4158 // evas_event_freeze(evas_object_evas_get(wd->obj));
4159 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4161 if (wd->queue_idle_enterer)
4163 ecore_idle_enterer_del(wd->queue_idle_enterer);
4164 wd->queue_idle_enterer = NULL;
4168 // evas_event_thaw(evas_object_evas_get(wd->obj));
4169 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4170 if (!wd->queue_idle_enterer)
4171 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4175 _elm_genlist_item_compare(const void *data, const void *data1)
4177 const Elm_Gen_Item *it, *item1;
4178 it = ELM_GEN_ITEM_FROM_INLIST(data);
4179 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4180 return it->wd->item_compare_cb(it, item1);
4184 _elm_genlist_item_list_compare(const void *data, const void *data1)
4186 const Elm_Gen_Item *it = data;
4187 const Elm_Gen_Item *item1 = data1;
4188 return it->wd->item_compare_cb(it, item1);
4191 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4193 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4198 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4199 _item_block_del(it);
4201 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4202 it->item->rel = after;
4203 it->item->rel->relcount++;
4204 it->item->before = EINA_FALSE;
4205 if (after->item->group_item) it->item->group_item = after->item->group_item;
4206 _item_queue(it->wd, it, NULL);
4208 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4211 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4213 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4216 if (!before) return;
4218 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4219 _item_block_del(it);
4220 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4221 it->item->rel = before;
4222 it->item->rel->relcount++;
4223 it->item->before = EINA_TRUE;
4224 if (before->item->group_item) it->item->group_item = before->item->group_item;
4225 _item_queue(it->wd, it, NULL);
4227 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4231 elm_genlist_items_count(const Evas_Object *obj)
4233 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4234 Widget_Data *wd = elm_widget_data_get(obj);
4236 return wd->item_count;
4239 EAPI Elm_Object_Item *
4240 elm_genlist_item_append(Evas_Object *obj,
4241 const Elm_Genlist_Item_Class *itc,
4243 Elm_Object_Item *parent,
4244 Elm_Genlist_Item_Type type,
4246 const void *func_data)
4248 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4249 Widget_Data *wd = elm_widget_data_get(obj);
4250 if (!wd) return NULL;
4251 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4253 if (!it) return NULL;
4257 wd->group_items = eina_list_append(wd->group_items, it);
4258 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4259 it->item->rel = NULL;
4263 Elm_Gen_Item *it2 = NULL;
4264 Eina_List *ll = eina_list_last(it->parent->item->items);
4265 if (ll) it2 = ll->data;
4266 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4267 if (!it2) it2 = it->parent;
4269 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4270 EINA_INLIST_GET(it2));
4271 it->item->rel = it2;
4272 it->item->rel->relcount++;
4274 it->item->before = EINA_FALSE;
4275 _item_queue(wd, it, NULL);
4276 return (Elm_Object_Item *)it;
4279 EAPI Elm_Object_Item *
4280 elm_genlist_item_prepend(Evas_Object *obj,
4281 const Elm_Genlist_Item_Class *itc,
4283 Elm_Object_Item *parent,
4284 Elm_Genlist_Item_Type type,
4286 const void *func_data)
4288 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4289 Widget_Data *wd = elm_widget_data_get(obj);
4290 if (!wd) return NULL;
4291 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4293 if (!it) return NULL;
4297 wd->group_items = eina_list_prepend(wd->group_items, it);
4298 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4299 it->item->rel = NULL;
4303 Elm_Gen_Item *it2 = NULL;
4304 Eina_List *ll = it->parent->item->items;
4305 if (ll) it2 = ll->data;
4306 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4307 if (!it2) it2 = it->parent;
4309 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4310 EINA_INLIST_GET(it2));
4311 it->item->rel = it2;
4312 it->item->rel->relcount++;
4314 it->item->before = EINA_TRUE;
4315 _item_queue(wd, it, NULL);
4316 return (Elm_Object_Item *)it;
4319 EAPI Elm_Object_Item *
4320 elm_genlist_item_insert_after(Evas_Object *obj,
4321 const Elm_Genlist_Item_Class *itc,
4323 Elm_Object_Item *parent,
4324 Elm_Object_Item *after,
4325 Elm_Genlist_Item_Type type,
4327 const void *func_data)
4329 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4330 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4331 Widget_Data *wd = elm_widget_data_get(obj);
4332 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4333 if (!wd) return NULL;
4334 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4335 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4337 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4339 if (!it) return NULL;
4342 if ((it->group) && (_after->group))
4343 wd->group_items = eina_list_append_relative(wd->group_items, it,
4348 it->parent->item->items =
4349 eina_list_append_relative(it->parent->item->items, it, _after);
4351 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4352 EINA_INLIST_GET(_after));
4353 it->item->rel = _after;
4354 it->item->rel->relcount++;
4355 it->item->before = EINA_FALSE;
4356 _item_queue(wd, it, NULL);
4357 return (Elm_Object_Item *)it;
4360 EAPI Elm_Object_Item *
4361 elm_genlist_item_insert_before(Evas_Object *obj,
4362 const Elm_Genlist_Item_Class *itc,
4364 Elm_Object_Item *parent,
4365 Elm_Object_Item *before,
4366 Elm_Genlist_Item_Type type,
4368 const void *func_data)
4370 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4371 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4372 Widget_Data *wd = elm_widget_data_get(obj);
4373 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4374 if (!wd) return NULL;
4375 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4376 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4378 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4380 if (!it) return NULL;
4383 if (it->group && _before->group)
4384 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4389 it->parent->item->items =
4390 eina_list_prepend_relative(it->parent->item->items, it, _before);
4392 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4393 EINA_INLIST_GET(_before));
4394 it->item->rel = _before;
4395 it->item->rel->relcount++;
4396 it->item->before = EINA_TRUE;
4397 _item_queue(wd, it, NULL);
4398 return (Elm_Object_Item *)it;
4401 EAPI Elm_Object_Item *
4402 elm_genlist_item_sorted_insert(Evas_Object *obj,
4403 const Elm_Genlist_Item_Class *itc,
4405 Elm_Object_Item *parent,
4406 Elm_Genlist_Item_Type type,
4407 Eina_Compare_Cb comp,
4409 const void *func_data)
4411 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4412 Widget_Data *wd = elm_widget_data_get(obj);
4413 if (!wd) return NULL;
4414 Elm_Gen_Item *rel = NULL;
4415 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4417 if (!it) return NULL;
4419 wd->item_compare_cb = comp;
4426 l = eina_list_search_sorted_near_list(it->parent->item->items,
4427 _elm_genlist_item_list_compare,
4431 rel = eina_list_data_get(l);
4435 if (cmp_result >= 0)
4437 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4438 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4439 it->item->before = EINA_FALSE;
4441 else if (cmp_result < 0)
4443 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4444 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4445 it->item->before = EINA_TRUE;
4452 wd->state = eina_inlist_sorted_state_new();
4453 eina_inlist_sorted_state_init(wd->state, wd->items);
4454 wd->requeued = EINA_FALSE;
4458 wd->group_items = eina_list_append(wd->group_items, it);
4460 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4461 _elm_genlist_item_compare, wd->state);
4463 if (EINA_INLIST_GET(it)->next)
4465 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4466 it->item->before = EINA_TRUE;
4468 else if (EINA_INLIST_GET(it)->prev)
4470 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4471 it->item->before = EINA_FALSE;
4477 it->item->rel = rel;
4478 it->item->rel->relcount++;
4481 _item_queue(wd, it, _elm_genlist_item_list_compare);
4483 return (Elm_Object_Item *)it;
4487 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4489 Eina_Inlist *next, *l;
4490 Widget_Data *wd = elm_widget_data_get(obj);
4493 if (!standby) wd->generation++;
4497 eina_inlist_sorted_state_free(wd->state);
4501 if (wd->walking > 0)
4503 wd->clear_me = EINA_TRUE;
4506 evas_event_freeze(evas_object_evas_get(wd->obj));
4507 for (l = wd->items, next = l ? l->next : NULL;
4509 l = next, next = next ? next->next : NULL)
4511 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4513 if (it->generation < wd->generation)
4515 Elm_Gen_Item *itn = NULL;
4517 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4518 if (itn) itn->walking++; /* prevent early death of subitem */
4520 elm_widget_item_free(it);
4521 if (itn) itn->walking--;
4524 wd->clear_me = EINA_FALSE;
4525 wd->pan_changed = EINA_TRUE;
4528 ecore_job_del(wd->calc_job);
4529 wd->calc_job = NULL;
4531 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4532 if (wd->clear_cb) wd->clear_cb(wd);
4538 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4539 wd->alpha_bg = NULL;
4543 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4544 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4546 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4547 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4548 evas_event_thaw(evas_object_evas_get(wd->obj));
4549 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4553 elm_genlist_clear(Evas_Object *obj)
4555 ELM_CHECK_WIDTYPE(obj, widtype);
4556 _elm_genlist_clear(obj, EINA_FALSE);
4560 elm_genlist_multi_select_set(Evas_Object *obj,
4563 ELM_CHECK_WIDTYPE(obj, widtype);
4564 Widget_Data *wd = elm_widget_data_get(obj);
4566 wd->multi = !!multi;
4570 elm_genlist_multi_select_get(const Evas_Object *obj)
4572 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4573 Widget_Data *wd = elm_widget_data_get(obj);
4574 if (!wd) return EINA_FALSE;
4578 EAPI Elm_Object_Item *
4579 elm_genlist_selected_item_get(const Evas_Object *obj)
4581 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4582 Widget_Data *wd = elm_widget_data_get(obj);
4583 if (!wd) return NULL;
4584 if (wd->selected) return wd->selected->data;
4588 EAPI const Eina_List *
4589 elm_genlist_selected_items_get(const Evas_Object *obj)
4591 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4592 Widget_Data *wd = elm_widget_data_get(obj);
4593 if (!wd) return NULL;
4594 return wd->selected;
4598 elm_genlist_realized_items_get(const Evas_Object *obj)
4600 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4601 Widget_Data *wd = elm_widget_data_get(obj);
4602 Eina_List *list = NULL;
4604 Eina_Bool done = EINA_FALSE;
4605 if (!wd) return NULL;
4606 EINA_INLIST_FOREACH(wd->blocks, itb)
4614 EINA_LIST_FOREACH(itb->items, l, it)
4616 if (it->realized) list = eina_list_append(list, it);
4627 EAPI Elm_Object_Item *
4628 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4633 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4634 Widget_Data *wd = elm_widget_data_get(obj);
4635 Evas_Coord ox, oy, ow, oh;
4638 if (!wd) return NULL;
4639 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4641 EINA_INLIST_FOREACH(wd->blocks, itb)
4646 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4647 oy + itb->y - itb->wd->pan_y,
4648 itb->w, itb->h, x, y, 1, 1))
4650 EINA_LIST_FOREACH(itb->items, l, it)
4652 Evas_Coord itx, ity;
4654 itx = ox + itb->x + it->x - itb->wd->pan_x;
4655 ity = oy + itb->y + it->y - itb->wd->pan_y;
4656 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4660 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4661 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4665 return (Elm_Object_Item *)it;
4667 lasty = ity + it->item->h;
4672 if (y > lasty) *posret = 1;
4678 EAPI Elm_Object_Item *
4679 elm_genlist_first_item_get(const Evas_Object *obj)
4681 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4682 Widget_Data *wd = elm_widget_data_get(obj);
4683 if (!wd) return NULL;
4684 if (!wd->items) return NULL;
4685 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4686 while ((it) && (it->generation < wd->generation))
4687 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4688 return (Elm_Object_Item *)it;
4691 EAPI Elm_Object_Item *
4692 elm_genlist_last_item_get(const Evas_Object *obj)
4694 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4695 Widget_Data *wd = elm_widget_data_get(obj);
4696 if (!wd) return NULL;
4697 if (!wd->items) return NULL;
4698 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4699 while ((it) && (it->generation < wd->generation))
4700 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4701 return (Elm_Object_Item *)it;
4704 EAPI Elm_Object_Item *
4705 elm_genlist_item_next_get(const Elm_Object_Item *it)
4707 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4708 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4711 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
4712 if ((_it) && (_it->generation == _it->wd->generation)) break;
4714 return (Elm_Object_Item *) _it;
4717 EAPI Elm_Object_Item *
4718 elm_genlist_item_prev_get(const Elm_Object_Item *it)
4720 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4721 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4724 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
4725 if ((_it) && (_it->generation == _it->wd->generation)) break;
4727 return (Elm_Object_Item *) _it;
4730 EAPI Elm_Object_Item *
4731 elm_genlist_item_parent_get(const Elm_Object_Item *it)
4733 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4734 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
4738 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
4740 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4741 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
4743 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4745 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
4746 _item_subitems_clear(_it);
4749 if (!wd->tree_effect_animator)
4751 wd->expanded_item = _it;
4752 _item_tree_effect_before(_it);
4753 evas_object_raise(wd->alpha_bg);
4754 evas_object_show(wd->alpha_bg);
4755 wd->start_time = ecore_time_get();
4756 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
4759 _item_subitems_clear(_it);
4764 elm_genlist_item_selected_set(Elm_Object_Item *it,
4767 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4768 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4769 Widget_Data *wd = _it->wd;
4771 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
4773 selected = !!selected;
4774 if (_it->selected == selected) return;
4780 while (wd->selected)
4782 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
4783 _it->unsel_cb(wd->selected->data);
4786 _it->highlight_cb(_it);
4790 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
4795 elm_genlist_item_selected_get(const Elm_Object_Item *it)
4797 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4798 return ((Elm_Gen_Item *)it)->selected;
4802 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
4805 if (it->item->expanded)
4807 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4811 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4814 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
4815 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4822 _elm_genlist_move_items_set(Elm_Gen_Item *it)
4825 Elm_Gen_Item *it2 = NULL;
4826 Evas_Coord ox, oy, ow, oh, dh = 0;
4828 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
4830 if (it->item->expanded)
4832 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
4833 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
4835 if (it2 == it->wd->expanded_next_item) break;
4836 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
4841 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
4842 it2 = it->wd->expanded_next_item;
4843 while (it2 && (dh < oy + oh))
4846 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
4847 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4853 elm_genlist_item_expanded_set(Elm_Object_Item *it,
4856 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4857 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4858 expanded = !!expanded;
4859 if (_it->item->expanded == expanded) return;
4860 _it->item->expanded = expanded;
4861 _it->wd->expanded_item = _it;
4862 _elm_genlist_move_items_set(_it);
4864 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
4865 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
4867 if (_it->item->expanded)
4869 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
4871 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
4872 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
4873 _it->wd->auto_scroll_enabled = EINA_TRUE;
4877 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
4879 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
4880 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
4881 _it->wd->auto_scroll_enabled = EINA_FALSE;
4886 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
4888 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4889 return ((Elm_Gen_Item *)it)->item->expanded;
4893 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
4895 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
4896 return ((Elm_Gen_Item *)it)->item->expanded_depth;
4900 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
4901 Elm_Genlist_Item_Scrollto_Type type,
4908 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4909 Evas_Coord gith = 0;
4910 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4911 if ((_it->item->queued) || (!_it->item->mincalcd))
4913 _it->wd->show_item = _it;
4914 _it->wd->bring_in = bring_in;
4915 _it->wd->scrollto_type = type;
4916 _it->item->showme = EINA_TRUE;
4919 if (_it->wd->show_item)
4921 _it->wd->show_item->item->showme = EINA_FALSE;
4922 _it->wd->show_item = NULL;
4925 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
4928 case ELM_GENLIST_ITEM_SCROLLTO_IN:
4929 if ((_it->item->group_item) &&
4930 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4931 gith = _it->item->group_item->item->h;
4933 *y = _it->y + _it->item->block->y - gith;
4935 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
4936 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4937 *y = _it->y + _it->item->block->y - gith;
4939 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
4940 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
4946 *x = _it->x + _it->item->block->x;
4947 *w = _it->item->block->w;
4952 elm_genlist_item_promote(Elm_Object_Item *it)
4954 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4955 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4956 if (_it->generation < _it->wd->generation) return;
4957 _item_move_before(_it,
4958 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
4962 elm_genlist_item_demote(Elm_Object_Item *it)
4964 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4965 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4966 if (_it->generation < _it->wd->generation) return;
4967 _item_move_after(_it,
4968 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
4972 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4974 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4975 Evas_Coord x, y, w, h;
4976 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4978 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
4979 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
4983 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4986 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4987 Evas_Coord x, y, w, h;
4988 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4990 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
4991 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
4995 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
4997 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4999 Evas_Object *content;
5000 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5002 elm_widget_sub_object_del(WIDGET(it), content);
5003 evas_object_smart_member_del(content);
5004 evas_object_hide(content);
5005 if (l) *l = eina_list_append(*l, content);
5010 elm_genlist_item_update(Elm_Object_Item *it)
5012 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5013 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5015 if (!_it->item->block) return;
5016 if (_it->generation < _it->wd->generation) return;
5017 _it->item->mincalcd = EINA_FALSE;
5018 _it->item->updateme = EINA_TRUE;
5019 _it->item->block->updateme = EINA_TRUE;
5020 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5021 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5025 elm_genlist_item_fields_update(Elm_Object_Item *it,
5027 Elm_Genlist_Item_Field_Type itf)
5029 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5030 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5032 if (!_it->item->block) return;
5033 if (_it->generation < _it->wd->generation) return;
5035 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5036 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5037 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5039 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5040 &_it->contents, parts);
5041 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5042 &_it->contents, parts);
5046 _it->item->flip_content_objs =
5047 _item_mode_content_unrealize(_it, VIEW(_it),
5048 &_it->item->flip_contents, parts,
5049 &_it->item->flip_content_objs);
5050 _it->item->flip_content_objs =
5051 _item_mode_content_realize(_it, VIEW(_it),
5052 &_it->item->flip_contents, parts,
5053 &_it->item->flip_content_objs);
5055 if (_it->item->deco_it_view)
5057 _it->item->deco_it_content_objs =
5058 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5059 &_it->item->deco_it_contents, parts,
5060 &_it->item->deco_it_content_objs);
5061 _it->item->deco_it_content_objs =
5062 _item_mode_content_realize(_it, _it->item->deco_it_view,
5063 &_it->item->deco_it_contents, parts,
5064 &_it->item->deco_it_content_objs);
5066 if (_it->wd->decorate_all_mode)
5068 _it->item->deco_all_content_objs =
5069 _item_mode_content_unrealize(_it, _it->deco_all_view,
5070 &_it->item->deco_all_contents, parts,
5071 &_it->item->deco_all_content_objs);
5072 _it->item->deco_all_content_objs =
5073 _item_mode_content_realize(_it, _it->deco_all_view,
5074 &_it->item->deco_all_contents, parts,
5075 &_it->item->deco_all_content_objs);
5078 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5079 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5083 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5084 const Elm_Genlist_Item_Class *itc)
5086 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5087 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5089 if (!_it->item->block) return;
5090 EINA_SAFETY_ON_NULL_RETURN(itc);
5091 if (_it->generation < _it->wd->generation) return;
5093 _it->item->nocache_once = EINA_TRUE;
5095 elm_widget_stringlist_free(_it->texts);
5097 elm_widget_stringlist_free(_it->contents);
5098 _it->contents = NULL;
5099 elm_widget_stringlist_free(_it->states);
5104 elm_widget_stringlist_free(_it->item->flip_contents);
5105 _it->item->flip_contents = NULL;
5107 if (_it->item->deco_it_view)
5109 elm_widget_stringlist_free(_it->item->deco_it_texts);
5110 _it->item->deco_it_texts = NULL;
5111 elm_widget_stringlist_free(_it->item->deco_it_contents);
5112 _it->item->deco_it_contents = NULL;
5114 if (_it->wd->decorate_all_mode)
5116 elm_widget_stringlist_free(_it->item->deco_all_texts);
5117 _it->item->deco_all_texts = NULL;
5118 elm_widget_stringlist_free(_it->item->deco_all_contents);
5119 _it->item->deco_all_contents = NULL;
5122 elm_genlist_item_update(it);
5125 EAPI const Elm_Genlist_Item_Class *
5126 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5128 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5129 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5130 if (_it->generation < _it->wd->generation) return NULL;
5134 static Evas_Object *
5135 _elm_genlist_item_label_create(void *data,
5136 Evas_Object *obj __UNUSED__,
5137 Evas_Object *tooltip,
5138 void *it __UNUSED__)
5140 Evas_Object *label = elm_label_add(tooltip);
5143 elm_object_style_set(label, "tooltip");
5144 elm_object_text_set(label, data);
5149 _elm_genlist_item_label_del_cb(void *data,
5150 Evas_Object *obj __UNUSED__,
5151 void *event_info __UNUSED__)
5153 eina_stringshare_del(data);
5157 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5160 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5161 text = eina_stringshare_add(text);
5162 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5164 _elm_genlist_item_label_del_cb);
5168 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5169 Elm_Tooltip_Item_Content_Cb func,
5171 Evas_Smart_Cb del_cb)
5173 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5174 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5176 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5179 if (_it->tooltip.del_cb)
5180 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5182 _it->tooltip.content_cb = func;
5183 _it->tooltip.data = data;
5184 _it->tooltip.del_cb = del_cb;
5188 elm_widget_item_tooltip_content_cb_set(_it,
5189 _it->tooltip.content_cb,
5190 _it->tooltip.data, NULL);
5191 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5192 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5198 if (del_cb) del_cb((void *)data, NULL, NULL);
5202 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5204 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5205 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5207 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5208 elm_widget_item_tooltip_unset(_it);
5210 if (_it->tooltip.del_cb)
5211 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5212 _it->tooltip.del_cb = NULL;
5213 _it->tooltip.content_cb = NULL;
5214 _it->tooltip.data = NULL;
5215 _it->tooltip.free_size = EINA_FALSE;
5216 if (_it->tooltip.style)
5217 elm_genlist_item_tooltip_style_set(it, NULL);
5221 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5224 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5225 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5227 eina_stringshare_replace(&_it->tooltip.style, style);
5228 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5232 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5234 return elm_object_item_tooltip_style_get(it);
5238 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5241 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5242 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5244 _it->tooltip.free_size = disable;
5245 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5250 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5252 return elm_object_tooltip_window_mode_get(VIEW(it));
5256 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5259 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5260 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5261 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5262 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5266 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5268 return elm_widget_item_cursor_get(it);
5272 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5274 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5275 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5277 if (!_it->mouse_cursor) return;
5279 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5281 eina_stringshare_del(_it->mouse_cursor);
5282 _it->mouse_cursor = NULL;
5286 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5289 elm_widget_item_cursor_style_set(it, style);
5293 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5295 return elm_widget_item_cursor_style_get(it);
5299 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5300 Eina_Bool engine_only)
5302 elm_widget_item_cursor_engine_only_set(it, engine_only);
5306 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5308 return elm_widget_item_cursor_engine_only_get(it);
5312 elm_genlist_item_index_get(const Elm_Object_Item *it)
5314 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5315 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5317 if (_it->item->block)
5318 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5323 elm_genlist_mode_set(Evas_Object *obj,
5326 ELM_CHECK_WIDTYPE(obj, widtype);
5327 Widget_Data *wd = elm_widget_data_get(obj);
5329 if (wd->mode == mode) return;
5331 if (wd->mode == ELM_LIST_COMPRESS)
5332 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5338 elm_genlist_mode_get(const Evas_Object *obj)
5340 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5341 Widget_Data *wd = elm_widget_data_get(obj);
5342 if (!wd) return ELM_LIST_LAST;
5347 elm_genlist_bounce_set(Evas_Object *obj,
5351 ELM_CHECK_WIDTYPE(obj, widtype);
5352 Widget_Data *wd = elm_widget_data_get(obj);
5354 wd->h_bounce = !!h_bounce;
5355 wd->v_bounce = !!v_bounce;
5356 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5360 elm_genlist_bounce_get(const Evas_Object *obj,
5361 Eina_Bool *h_bounce,
5362 Eina_Bool *v_bounce)
5364 ELM_CHECK_WIDTYPE(obj, widtype);
5365 Widget_Data *wd = elm_widget_data_get(obj);
5367 if (h_bounce) *h_bounce = wd->h_bounce;
5368 if (v_bounce) *v_bounce = wd->v_bounce;
5372 elm_genlist_homogeneous_set(Evas_Object *obj,
5373 Eina_Bool homogeneous)
5375 ELM_CHECK_WIDTYPE(obj, widtype);
5376 Widget_Data *wd = elm_widget_data_get(obj);
5378 wd->homogeneous = !!homogeneous;
5382 elm_genlist_homogeneous_get(const Evas_Object *obj)
5384 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5385 Widget_Data *wd = elm_widget_data_get(obj);
5386 if (!wd) return EINA_FALSE;
5387 return wd->homogeneous;
5391 elm_genlist_block_count_set(Evas_Object *obj,
5394 ELM_CHECK_WIDTYPE(obj, widtype);
5395 Widget_Data *wd = elm_widget_data_get(obj);
5397 wd->max_items_per_block = count;
5398 wd->item_cache_max = wd->max_items_per_block * 2;
5399 _item_cache_clean(wd);
5403 elm_genlist_block_count_get(const Evas_Object *obj)
5405 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5406 Widget_Data *wd = elm_widget_data_get(obj);
5408 return wd->max_items_per_block;
5412 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5415 ELM_CHECK_WIDTYPE(obj, widtype);
5416 Widget_Data *wd = elm_widget_data_get(obj);
5418 wd->longpress_timeout = timeout;
5422 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5424 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5425 Widget_Data *wd = elm_widget_data_get(obj);
5427 return wd->longpress_timeout;
5431 elm_genlist_scroller_policy_set(Evas_Object *obj,
5432 Elm_Scroller_Policy policy_h,
5433 Elm_Scroller_Policy policy_v)
5435 ELM_CHECK_WIDTYPE(obj, widtype);
5436 Widget_Data *wd = elm_widget_data_get(obj);
5437 if ((!wd) || (!wd->scr)) return;
5438 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5439 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5441 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5445 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5446 Elm_Scroller_Policy *policy_h,
5447 Elm_Scroller_Policy *policy_v)
5449 ELM_CHECK_WIDTYPE(obj, widtype);
5450 Widget_Data *wd = elm_widget_data_get(obj);
5451 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5452 if ((!wd) || (!wd->scr)) return;
5453 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5454 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5455 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5459 elm_genlist_realized_items_update(Evas_Object *obj)
5461 ELM_CHECK_WIDTYPE(obj, widtype);
5463 Eina_List *list, *l;
5464 Elm_Object_Item *it;
5466 list = elm_genlist_realized_items_get(obj);
5467 EINA_LIST_FOREACH(list, l, it)
5468 elm_genlist_item_update(it);
5472 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5473 const char *decorate_it_type,
5474 Eina_Bool decorate_it_set)
5476 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5477 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5479 Widget_Data *wd = _it->wd;
5481 Elm_Object_Item *it2;
5484 if (!decorate_it_type) return;
5485 if ((_it->generation < _it->wd->generation) ||
5486 elm_widget_item_disabled_get(_it)) return;
5487 if (wd->decorate_all_mode) return;
5489 if ((wd->mode_item == _it) &&
5490 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5493 if (!_it->itc->decorate_item_style) return;
5494 _it->decorate_it_set = decorate_it_set;
5498 EINA_LIST_FOREACH(wd->selected, l, it2)
5499 if (((Elm_Gen_Item *)it2)->realized)
5500 elm_genlist_item_selected_set(it2, EINA_FALSE);
5504 it2 = elm_genlist_selected_item_get(wd->obj);
5505 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5506 elm_genlist_item_selected_set(it2, EINA_FALSE);
5509 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5510 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5511 _decorate_item_unset(wd);
5513 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5514 if (decorate_it_set) _decorate_item_set(_it);
5518 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5520 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5521 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5522 return _it->wd->decorate_it_type;
5525 EAPI const Elm_Object_Item *
5526 elm_genlist_decorated_item_get(const Evas_Object *obj)
5528 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5529 Widget_Data *wd = elm_widget_data_get(obj);
5530 if (!wd) return NULL;
5531 return (Elm_Object_Item *) wd->mode_item;
5535 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5537 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5538 Widget_Data *wd = elm_widget_data_get(obj);
5539 if (!wd) return EINA_FALSE;
5541 return wd->decorate_all_mode;
5545 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5547 ELM_CHECK_WIDTYPE(obj, widtype);
5548 Eina_List *list, *l;
5551 Widget_Data *wd = elm_widget_data_get(obj);
5553 decorated = !!decorated;
5554 if (wd->decorate_all_mode == decorated) return;
5555 wd->decorate_all_mode = decorated;
5557 list = elm_genlist_realized_items_get(obj);
5558 if (!wd->decorate_all_mode)
5560 EINA_LIST_FOREACH(list, l, it)
5562 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5563 _decorate_all_item_unrealize(it);
5565 _item_cache_zero(wd);
5569 EINA_LIST_FOREACH(list, l, it)
5571 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5573 if (it->itc->decorate_all_item_style)
5574 _decorate_all_item_realize(it, EINA_TRUE);
5578 if (wd->calc_job) ecore_job_del(wd->calc_job);
5579 wd->calc_job = ecore_job_add(_calc_job, wd);
5583 elm_genlist_reorder_mode_set(Evas_Object *obj,
5584 Eina_Bool reorder_mode)
5586 ELM_CHECK_WIDTYPE(obj, widtype);
5587 Widget_Data *wd = elm_widget_data_get(obj);
5589 wd->reorder_mode = !!reorder_mode;
5593 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5595 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5596 Widget_Data *wd = elm_widget_data_get(obj);
5597 if (!wd) return EINA_FALSE;
5598 return wd->reorder_mode;
5601 EAPI Elm_Genlist_Item_Type
5602 elm_genlist_item_type_get(const Elm_Object_Item *it)
5604 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5605 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5606 return _it->item->type;
5609 EAPI Elm_Genlist_Item_Class *
5610 elm_genlist_item_class_new(void)
5612 Elm_Genlist_Item_Class *itc;
5614 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5617 itc->version = CLASS_ALLOCATED;
5619 itc->delete_me = EINA_FALSE;
5625 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5627 if (itc && (itc->version == CLASS_ALLOCATED))
5629 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5630 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5640 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5642 if (itc && (itc->version == CLASS_ALLOCATED))
5645 if (itc->refcount == 0) itc->refcount--;
5650 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5652 if (itc && (itc->version == CLASS_ALLOCATED))
5654 if (itc->refcount > 0) itc->refcount--;
5655 if (itc->delete_me && (!itc->refcount))
5656 elm_genlist_item_class_free(itc);
5660 void _flip_job(void *data)
5662 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
5663 _item_unhighlight(it);
5665 _elm_genlist_item_unrealize(it, EINA_FALSE);
5666 it->flipped = EINA_TRUE;
5667 it->item->nocache = EINA_TRUE;
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 elm_genlist_item_flip_set(Elm_Object_Item *it,
5676 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5677 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5680 if (_it->flipped == flip) return;
5684 ecore_job_add(_flip_job, _it);
5688 _it->flipped = flip;
5689 _item_cache_zero(_it->wd);
5690 elm_genlist_item_update(it);
5691 _it->item->nocache = EINA_FALSE;
5696 elm_genlist_item_flip_get(const Elm_Object_Item *it)
5698 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5699 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5700 return _it->flipped;
5704 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
5706 ELM_CHECK_WIDTYPE(obj, widtype);
5707 Widget_Data *wd = elm_widget_data_get(obj);
5709 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5711 if (wd->select_mode != mode)
5712 wd->select_mode = mode;
5715 EAPI Elm_Object_Select_Mode
5716 elm_genlist_select_mode_get(const Evas_Object *obj)
5718 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
5719 Widget_Data *wd = elm_widget_data_get(obj);
5720 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
5721 return wd->select_mode;
5725 elm_genlist_highlight_mode_set(Evas_Object *obj,
5726 Eina_Bool highlight)
5728 ELM_CHECK_WIDTYPE(obj, widtype);
5729 Widget_Data *wd = elm_widget_data_get(obj);
5731 wd->highlight = !!highlight;
5735 elm_genlist_highlight_mode_get(const Evas_Object *obj)
5737 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5738 Widget_Data *wd = elm_widget_data_get(obj);
5739 if (!wd) return EINA_FALSE;
5740 return wd->highlight;
5744 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
5745 Elm_Object_Select_Mode mode)
5747 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5748 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5750 if (_it->generation < _it->wd->generation) return;
5751 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5753 if (_it->select_mode != mode)
5754 _it->select_mode = mode;
5756 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5758 _it->item->mincalcd = EINA_FALSE;
5759 _it->item->updateme = EINA_TRUE;
5760 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
5761 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5762 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5766 EAPI Elm_Object_Select_Mode
5767 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
5769 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
5770 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5771 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
5772 return _it->select_mode;
5775 /* for gengrid as of now */
5777 _elm_genlist_page_relative_set(Evas_Object *obj,
5781 Evas_Coord pagesize_h;
5782 Evas_Coord pagesize_v;
5784 ELM_CHECK_WIDTYPE(obj, widtype);
5785 Widget_Data *wd = elm_widget_data_get(obj);
5788 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5789 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5793 /* for gengrid as of now */
5795 _elm_genlist_page_relative_get(const Evas_Object *obj,
5799 ELM_CHECK_WIDTYPE(obj, widtype);
5800 Widget_Data *wd = elm_widget_data_get(obj);
5803 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5806 /* for gengrid as of now */
5808 _elm_genlist_page_size_set(Evas_Object *obj,
5809 Evas_Coord h_pagesize,
5810 Evas_Coord v_pagesize)
5815 ELM_CHECK_WIDTYPE(obj, widtype);
5816 Widget_Data *wd = elm_widget_data_get(obj);
5818 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5819 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5823 /* for gengrid as of now */
5825 _elm_genlist_current_page_get(const Evas_Object *obj,
5829 ELM_CHECK_WIDTYPE(obj, widtype);
5830 Widget_Data *wd = elm_widget_data_get(obj);
5832 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5835 /* for gengrid as of now */
5837 _elm_genlist_last_page_get(const Evas_Object *obj,
5841 ELM_CHECK_WIDTYPE(obj, widtype);
5842 Widget_Data *wd = elm_widget_data_get(obj);
5844 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5847 /* for gengrid as of now */
5849 _elm_genlist_page_show(const Evas_Object *obj,
5853 ELM_CHECK_WIDTYPE(obj, widtype);
5854 Widget_Data *wd = elm_widget_data_get(obj);
5856 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5859 /* for gengrid as of now */
5861 _elm_genlist_page_bring_in(const Evas_Object *obj,
5865 ELM_CHECK_WIDTYPE(obj, widtype);
5866 Widget_Data *wd = elm_widget_data_get(obj);
5868 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5872 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5875 Evas_Object *content;
5877 if (!it->realized) return;
5878 if (it->wd->reorder_it == it) return;
5880 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5882 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5885 ecore_timer_del(it->long_timer);
5886 it->long_timer = NULL;
5889 elm_widget_stringlist_free(it->texts);
5891 elm_widget_stringlist_free(it->contents);
5892 it->contents = NULL;
5893 elm_widget_stringlist_free(it->states);
5895 EINA_LIST_FREE(it->content_objs, content)
5896 evas_object_del(content);
5898 it->unrealize_cb(it);
5900 it->realized = EINA_FALSE;
5901 it->want_unrealize = EINA_FALSE;
5902 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5903 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5907 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5909 elm_widget_item_pre_notify_del(it);
5910 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5912 if ((it->relcount > 0) || (it->walking > 0)) return;
5914 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5916 if (it->itc->func.del)
5917 it->itc->func.del((void *)it->base.data, WIDGET(it));
5921 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5923 _elm_genlist_item_del_notserious(it);
5924 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5925 if (it->tooltip.del_cb)
5926 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5927 it->wd->walking -= it->walking;
5930 ecore_timer_del(it->long_timer);
5931 it->long_timer = NULL;
5934 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5938 eina_inlist_sorted_state_free(it->wd->state);
5939 it->wd->state = NULL;
5941 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5942 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5946 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
5947 it->wd->last_selected_item = NULL;
5948 it->wd->item_count--;
5952 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
5954 ELM_CHECK_WIDTYPE(obj, widtype);
5955 Widget_Data *wd = elm_widget_data_get(obj);
5957 wd->tree_effect_enabled = !!enabled;
5961 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
5963 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5964 Widget_Data *wd = elm_widget_data_get(obj);
5965 if (!wd) return EINA_FALSE;
5966 return wd->tree_effect_enabled;
5970 _create_tray_alpha_bg(const Evas_Object *obj)
5972 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5973 Widget_Data *wd = elm_widget_data_get(obj);
5974 if (!wd) return NULL;
5976 Evas_Object *bg = NULL;
5977 Evas_Coord ox, oy, ow, oh;
5979 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5980 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
5981 evas_object_color_set(bg,0,0,0,0);
5982 evas_object_resize(bg , ow, oh);
5983 evas_object_move(bg , ox, oy);
5988 _item_contract_emit(Elm_Gen_Item *it)
5993 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
5994 it->item->tree_effect_finished = EINA_FALSE;
5996 EINA_LIST_FOREACH(it->item->items, l, it2)
5997 if (it2) _item_contract_emit(it2);
6001 _item_tree_effect_before(Elm_Gen_Item *it)
6006 EINA_LIST_FOREACH(it->item->items, l, it2)
6008 if (it2->parent && (it == it2->parent))
6011 it2->item->tree_effect_hideme = EINA_TRUE;
6012 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6013 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6014 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6015 _item_contract_emit(it2);
6018 return ECORE_CALLBACK_CANCEL;
6022 _item_tree_effect(Widget_Data *wd, int y)
6024 Elm_Gen_Item *it = NULL, *expanded_next_it;
6026 expanded_next_it = wd->expanded_next_item;
6028 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6030 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6033 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6034 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6035 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6037 if (!it->item->tree_effect_finished)
6039 edje_object_signal_emit(VIEW(it), "flip_item", "");
6040 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6041 it->item->tree_effect_finished = EINA_TRUE;
6044 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6047 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6049 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6052 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6053 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6055 if (!it->item->tree_effect_finished)
6057 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6058 it->item->tree_effect_finished = EINA_TRUE;
6063 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6069 _item_tree_effect_finish(Widget_Data *wd)
6071 Elm_Gen_Item *it = NULL;
6074 if (wd->tree_effect_animator)
6076 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6077 _item_subitems_clear(wd->expanded_item);
6078 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6080 it->item->tree_effect_finished = EINA_TRUE;
6081 it->item->old_scrl_y = it->item->scrl_y;
6082 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6083 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6086 _item_auto_scroll(wd);
6087 evas_object_lower(wd->alpha_bg);
6088 evas_object_hide(wd->alpha_bg);
6089 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6090 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6092 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6093 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6094 evas_object_smart_changed(wd->pan_smart);
6096 wd->tree_effect_animator = NULL;
6100 _tree_effect_animator_cb(void *data)
6102 Widget_Data *wd = data;
6103 if (!wd) return ECORE_CALLBACK_CANCEL;
6104 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6105 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6107 double effect_duration = 0.3, t;
6108 int y = 0, dy = 0, dh = 0;
6109 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6112 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6113 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6114 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6115 if (t > effect_duration) end = EINA_TRUE;
6117 // Below while statement is needed, when the genlist is resized.
6118 it2 = wd->expanded_item;
6121 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6122 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6123 cvx, cvy, cvw, cvh));
6124 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6127 if (wd->expanded_next_item)
6129 expanded_next_it = wd->expanded_next_item;
6132 EINA_LIST_FOREACH(wd->move_items, l, it)
6134 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6136 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6137 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6138 expanded_next_it->item->scrl_y = cvy + cvh;
6140 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6141 cvy + cvh : expanded_next_it->item->scrl_y) -
6142 expanded_next_it->item->old_scrl_y;
6144 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6146 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6147 expanded_next_it->item->old_scrl_y = cvy + cvh;
6149 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6151 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6153 expanded_next_it->item->old_scrl_y = cvy + cvh;
6157 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6158 expanded_next_it->item->old_scrl_y;
6162 if (t <= effect_duration)
6164 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6174 _item_realize(it, in, 0);
6178 if (it != expanded_next_it)
6180 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6184 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6185 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6188 _item_tree_effect(wd, y);
6192 int expanded_item_num = 0;
6195 if (wd->expanded_item)
6196 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6201 expanded_item_num++;
6202 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6208 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6209 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6211 if (!it->item->tree_effect_finished)
6213 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6215 edje_object_signal_emit(VIEW(it), "flip_item", "");
6216 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6217 it->item->tree_effect_finished = EINA_TRUE;
6221 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6227 _item_tree_effect_finish(wd);
6228 return ECORE_CALLBACK_CANCEL;
6230 return ECORE_CALLBACK_RENEW;