3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.h"
9 // internally allocated
10 #define CLASS_ALLOCATED 0x3a70f11f
12 #define MAX_ITEMS_PER_BLOCK 32
13 #define REORDER_EFFECT_TIME 0.5
15 #define ELM_GEN_SETUP(wd) \
16 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
17 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
18 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
32 ERR("Genlist_Item_Class(itc) is NULL"); \
35 if ((itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) && \
36 (itc->version != CLASS_ALLOCATED)) \
38 ERR("Genlist_Item_Class version mismatched! current = (%d), required = (%d) or (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION, CLASS_ALLOCATED); \
44 typedef struct _Item_Block Item_Block;
45 typedef struct _Item_Cache Item_Cache;
47 struct Elm_Gen_Item_Type
52 Evas_Coord w, h, minw, minh;
53 Elm_Gen_Item *group_item;
54 Elm_Genlist_Item_Type type;
55 Eina_List *deco_it_texts, *deco_it_contents, *deco_it_states, *deco_it_content_objs;
56 Eina_List *deco_all_texts, *deco_all_contents, *deco_all_states, *deco_all_content_objs;
57 Eina_List *flip_contents, *flip_content_objs;
58 Ecore_Timer *swipe_timer;
59 Evas_Coord scrl_x, scrl_y, old_scrl_y;
62 Evas_Object *deco_it_view;
68 Eina_Bool want_realize : 1;
69 Eina_Bool expanded : 1;
70 Eina_Bool mincalcd : 1;
73 Eina_Bool updateme : 1;
74 Eina_Bool nocache : 1; /* do not use cache for this item */
75 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
76 Eina_Bool stacking_even : 1;
77 Eina_Bool nostacking : 1;
78 Eina_Bool move_effect_enabled : 1;
79 Eina_Bool decorate_all_item_realized : 1;
80 Eina_Bool tree_effect_finished : 1; /* tree effect */
81 Eina_Bool tree_effect_hideme : 1; /* item hide for tree effect */
92 Evas_Coord x, y, w, h, minw, minh;
94 int item_position_stamp;
96 Eina_Bool position_update : 1;
97 Eina_Bool want_unrealize : 1;
98 Eina_Bool realized : 1;
99 Eina_Bool changed : 1;
100 Eina_Bool updateme : 1;
101 Eina_Bool showme : 1;
102 Eina_Bool must_recalc : 1;
109 Evas_Object *base_view, *spacer;
111 const char *item_style; // it->itc->item_style
112 Eina_Bool tree : 1; // it->group
114 Eina_Bool selected : 1; // it->selected
115 Eina_Bool disabled : 1; // it->disabled
116 Eina_Bool expanded : 1; // it->item->expanded
119 static const char *widtype = NULL;
120 static void _item_cache_zero(Widget_Data *wd);
121 static void _del_hook(Evas_Object *obj);
122 static void _mirrored_set(Evas_Object *obj,
124 static void _theme_hook(Evas_Object *obj);
125 static void _show_region_hook(void *data,
127 static void _sizing_eval(Evas_Object *obj);
128 static void _item_realize(Elm_Gen_Item *it,
131 static void _item_unrealize_cb(Elm_Gen_Item *it);
132 static void _item_block_unrealize(Item_Block *itb);
133 static void _calc_job(void *data);
134 static void _on_focus_hook(void *data,
136 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
137 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
138 static Eina_Bool _item_single_select_up(Widget_Data *wd);
139 static Eina_Bool _item_single_select_down(Widget_Data *wd);
140 static Eina_Bool _event_hook(Evas_Object *obj,
142 Evas_Callback_Type type,
144 static void _signal_emit_hook(Evas_Object *obj,
145 const char *emission,
147 static Eina_Bool _deselect_all_items(Widget_Data *wd);
148 static void _pan_calculate(Evas_Object *obj);
149 static void _pan_max_get(Evas_Object *obj,
152 static void _item_position(Elm_Gen_Item *it,
156 static void _decorate_item_realize(Elm_Gen_Item *it);
157 static void _decorate_item_unrealize(Elm_Gen_Item *it);
158 static void _decorate_item_set(Elm_Gen_Item *it);
159 static void _decorate_item_unset(Widget_Data *wd);
160 static void _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity);
161 static void _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
162 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
163 static void _group_items_recalc(void *data);
164 static void _item_move_after(Elm_Gen_Item *it,
165 Elm_Gen_Item *after);
166 static void _item_move_before(Elm_Gen_Item *it,
167 Elm_Gen_Item *before);
168 static void _item_auto_scroll(Widget_Data *wd);
169 static void _elm_genlist_clear(Evas_Object *obj,
171 static void _pan_child_size_get(Evas_Object *obj,
174 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
175 static void _item_contract_emit(Elm_Gen_Item *it);
176 static int _item_tree_effect_before(Elm_Gen_Item *it);
177 static void _item_tree_effect(Widget_Data *wd, int y);
178 static void _item_tree_effect_finish(Widget_Data *wd);
179 static Eina_Bool _tree_effect_animator_cb(void *data);
181 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
183 static const char SIG_ACTIVATED[] = "activated";
184 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
185 static const char SIG_SELECTED[] = "selected";
186 static const char SIG_UNSELECTED[] = "unselected";
187 static const char SIG_EXPANDED[] = "expanded";
188 static const char SIG_CONTRACTED[] = "contracted";
189 static const char SIG_EXPAND_REQUEST[] = "expand,request";
190 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
191 static const char SIG_REALIZED[] = "realized";
192 static const char SIG_UNREALIZED[] = "unrealized";
193 static const char SIG_DRAG_START_UP[] = "drag,start,up";
194 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
195 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
196 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
197 static const char SIG_DRAG_STOP[] = "drag,stop";
198 static const char SIG_DRAG[] = "drag";
199 static const char SIG_LONGPRESSED[] = "longpressed";
200 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
201 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
202 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
203 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
204 static const char SIG_EDGE_TOP[] = "edge,top";
205 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
206 static const char SIG_EDGE_LEFT[] = "edge,left";
207 static const char SIG_EDGE_RIGHT[] = "edge,right";
208 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
209 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
210 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
211 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
212 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
213 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
214 static const char SIG_SWIPE[] = "swipe";
215 static const char SIG_MOVED[] = "moved";
216 static const char SIG_MOVED_AFTER[] = "moved,after";
217 static const char SIG_MOVED_BEFORE[] = "moved,before";
218 static const char SIG_INDEX_UPDATE[] = "index,update";
219 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
221 static const Evas_Smart_Cb_Description _signals[] = {
222 {SIG_CLICKED_DOUBLE, ""},
225 {SIG_UNSELECTED, ""},
227 {SIG_CONTRACTED, ""},
228 {SIG_EXPAND_REQUEST, ""},
229 {SIG_CONTRACT_REQUEST, ""},
231 {SIG_UNREALIZED, ""},
232 {SIG_DRAG_START_UP, ""},
233 {SIG_DRAG_START_DOWN, ""},
234 {SIG_DRAG_START_LEFT, ""},
235 {SIG_DRAG_START_RIGHT, ""},
238 {SIG_LONGPRESSED, ""},
239 {SIG_SCROLL_ANIM_START, ""},
240 {SIG_SCROLL_ANIM_STOP, ""},
241 {SIG_SCROLL_DRAG_START, ""},
242 {SIG_SCROLL_DRAG_STOP, ""},
244 {SIG_EDGE_BOTTOM, ""},
246 {SIG_EDGE_RIGHT, ""},
247 {SIG_MULTI_SWIPE_LEFT, ""},
248 {SIG_MULTI_SWIPE_RIGHT, ""},
249 {SIG_MULTI_SWIPE_UP, ""},
250 {SIG_MULTI_SWIPE_DOWN, ""},
251 {SIG_MULTI_PINCH_OUT, ""},
252 {SIG_MULTI_PINCH_IN, ""},
255 {SIG_MOVED_AFTER, ""},
256 {SIG_MOVED_BEFORE, ""},
257 {SIG_TREE_EFFECT_FINISHED, ""},
262 #undef ELM_CHECK_WIDTYPE
263 #define ELM_CHECK_WIDTYPE(obj, widtype) \
264 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
265 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
266 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
267 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
268 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
270 static const char *_gengrid = NULL;
271 static const char *_genlist = NULL;
273 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
275 elm_genlist_type_check(const Evas_Object *obj,
278 const char *provided, *expected = "(unknown)";
279 static int abort_on_warn = -1;
280 provided = elm_widget_type_get(obj);
281 if (!_genlist) _genlist = eina_stringshare_add("genlist");
282 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
283 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
285 if ((!provided) || (!provided[0]))
287 provided = evas_object_type_get(obj);
288 if ((!provided) || (!provided[0]))
289 provided = "(unknown)";
291 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
292 if (abort_on_warn == -1)
294 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
295 else abort_on_warn = 0;
297 if (abort_on_warn == 1) abort();
302 _event_hook(Evas_Object *obj,
303 Evas_Object *src __UNUSED__,
304 Evas_Callback_Type type,
307 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
308 Evas_Event_Key_Down *ev = event_info;
309 Widget_Data *wd = elm_widget_data_get(obj);
310 Evas_Coord pan_max_x = 0, pan_max_y = 0;
311 if (!wd) return EINA_FALSE;
312 if (!wd->items) return EINA_FALSE;
313 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
314 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
316 Elm_Object_Item *it = NULL;
319 Evas_Coord step_x = 0;
320 Evas_Coord step_y = 0;
323 Evas_Coord page_x = 0;
324 Evas_Coord page_y = 0;
326 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
327 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
328 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
329 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
331 if ((!strcmp(ev->keyname, "Left")) ||
332 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
336 else if ((!strcmp(ev->keyname, "Right")) ||
337 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
341 else if ((!strcmp(ev->keyname, "Up")) ||
342 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
344 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
345 (_item_multi_select_up(wd)))
346 || (_item_single_select_up(wd)))
348 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
354 else if ((!strcmp(ev->keyname, "Down")) ||
355 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
357 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
358 (_item_multi_select_down(wd)))
359 || (_item_single_select_down(wd)))
361 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
367 else if ((!strcmp(ev->keyname, "Home")) ||
368 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
370 it = elm_genlist_first_item_get(obj);
371 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
372 elm_genlist_item_selected_set(it, EINA_TRUE);
373 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
376 else if ((!strcmp(ev->keyname, "End")) ||
377 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
379 it = elm_genlist_last_item_get(obj);
380 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
381 elm_genlist_item_selected_set(it, EINA_TRUE);
382 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
385 else if ((!strcmp(ev->keyname, "Prior")) ||
386 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
389 y -= -(page_y * v_h) / 100;
393 else if ((!strcmp(ev->keyname, "Next")) ||
394 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
397 y += -(page_y * v_h) / 100;
401 else if (!strcmp(ev->keyname, "Escape"))
403 if (!_deselect_all_items(wd)) return EINA_FALSE;
404 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
407 else if (((!strcmp(ev->keyname, "Return")) ||
408 (!strcmp(ev->keyname, "KP_Enter")) ||
409 (!strcmp(ev->keyname, "space")))
410 && (!wd->multi) && (wd->selected))
412 it = elm_genlist_selected_item_get(obj);
413 elm_genlist_item_expanded_set(it,
414 !elm_genlist_item_expanded_get(it));
415 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
417 else return EINA_FALSE;
419 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
420 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
422 if (x > pan_max_x) x = pan_max_x;
424 if (y > pan_max_y) y = pan_max_y;
425 elm_smart_scroller_child_pos_set(wd->scr, x, y);
430 _deselect_all_items(Widget_Data *wd)
432 if (!wd->selected) return EINA_FALSE;
434 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
440 _item_multi_select_up(Widget_Data *wd)
442 if (!wd->selected) return EINA_FALSE;
443 if (!wd->multi) return EINA_FALSE;
445 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
446 if (!prev) return EINA_TRUE;
448 if (elm_genlist_item_selected_get(prev))
450 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
451 wd->last_selected_item = prev;
452 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
456 elm_genlist_item_selected_set(prev, EINA_TRUE);
457 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
463 _item_multi_select_down(Widget_Data *wd)
465 if (!wd->selected) return EINA_FALSE;
466 if (!wd->multi) return EINA_FALSE;
468 Elm_Object_Item *next;
469 next = elm_genlist_item_next_get(wd->last_selected_item);
470 if (!next) return EINA_TRUE;
472 if (elm_genlist_item_selected_get(next))
474 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
475 wd->last_selected_item = next;
476 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
480 elm_genlist_item_selected_set(next, EINA_TRUE);
481 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
487 _item_single_select_up(Widget_Data *wd)
492 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
493 while ((prev) && (prev->generation < wd->generation))
494 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
496 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
498 if (!prev) return EINA_FALSE;
500 _deselect_all_items(wd);
502 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
503 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
508 _item_single_select_down(Widget_Data *wd)
513 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
514 while ((next) && (next->generation < wd->generation))
515 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
517 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
519 if (!next) return EINA_FALSE;
521 _deselect_all_items(wd);
523 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
524 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
529 _on_focus_hook(void *data __UNUSED__,
532 Widget_Data *wd = elm_widget_data_get(obj);
534 if (elm_widget_focus_get(obj))
536 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
537 evas_object_focus_set(wd->obj, EINA_TRUE);
538 if ((wd->selected) && (!wd->last_selected_item))
539 wd->last_selected_item = eina_list_data_get(wd->selected);
543 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
544 evas_object_focus_set(wd->obj, EINA_FALSE);
549 _del_hook(Evas_Object *obj)
551 Widget_Data *wd = elm_widget_data_get(obj);
553 _item_cache_zero(wd);
554 if (wd->calc_job) ecore_job_del(wd->calc_job);
555 if (wd->update_job) ecore_job_del(wd->update_job);
556 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
557 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
558 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
559 if (wd->decorate_it_type) eina_stringshare_del(wd->decorate_it_type);
560 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
561 if (wd->tree_effect_animator) ecore_animator_del(wd->tree_effect_animator);
566 _del_pre_hook(Evas_Object *obj)
568 Widget_Data *wd = elm_widget_data_get(obj);
570 if (wd->decorate_all_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
571 elm_genlist_clear(obj);
572 evas_object_del(wd->pan_smart);
573 wd->pan_smart = NULL;
577 _mirrored_set(Evas_Object *obj,
580 Widget_Data *wd = elm_widget_data_get(obj);
582 _item_cache_zero(wd);
583 elm_smart_scroller_mirrored_set(wd->scr, rtl);
587 _theme_hook(Evas_Object *obj)
589 Widget_Data *wd = elm_widget_data_get(obj);
592 evas_event_freeze(evas_object_evas_get(wd->obj));
593 _item_cache_zero(wd);
594 _elm_widget_mirrored_reload(obj);
595 _mirrored_set(obj, elm_widget_mirrored_get(obj));
596 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
597 elm_widget_style_get(obj));
598 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
599 wd->item_width = wd->item_height = 0;
600 wd->group_item_width = wd->group_item_height = 0;
601 wd->minw = wd->minh = wd->realminw = 0;
602 EINA_INLIST_FOREACH(wd->blocks, itb)
607 if (itb->realized) _item_block_unrealize(itb);
608 EINA_LIST_FOREACH(itb->items, l, it)
609 it->item->mincalcd = EINA_FALSE;
611 itb->changed = EINA_TRUE;
613 if (wd->calc_job) ecore_job_del(wd->calc_job);
614 wd->calc_job = ecore_job_add(_calc_job, wd);
616 evas_event_thaw(evas_object_evas_get(wd->obj));
617 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
621 _show_region_hook(void *data,
624 Widget_Data *wd = elm_widget_data_get(data);
625 Evas_Coord x, y, w, h;
627 elm_widget_show_region_get(obj, &x, &y, &w, &h);
628 //x & y are screen coordinates, Add with pan coordinates
631 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
635 _translate_hook(Evas_Object *obj)
637 evas_object_smart_callback_call(obj, "language,changed", NULL);
641 _sizing_eval(Evas_Object *obj)
643 Widget_Data *wd = elm_widget_data_get(obj);
644 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
645 Evas_Coord vmw = 0, vmh = 0;
648 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
649 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
651 edje_object_size_min_calc
652 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
654 if (wd->mode == ELM_LIST_COMPRESS)
658 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
659 if ((vw != 0) && (vw != wd->prev_viewport_w))
663 wd->prev_viewport_w = vw;
664 EINA_INLIST_FOREACH(wd->blocks, itb)
666 itb->must_recalc = EINA_TRUE;
668 if (wd->calc_job) ecore_job_del(wd->calc_job);
669 wd->calc_job = ecore_job_add(_calc_job, wd);
674 else if (wd->mode == ELM_LIST_LIMIT)
685 evas_object_size_hint_min_set(obj, minw, minh);
686 evas_object_size_hint_max_set(obj, maxw, maxh);
690 _signal_emit_hook(Evas_Object *obj,
691 const char *emission,
694 Widget_Data *wd = elm_widget_data_get(obj);
695 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
700 _item_highlight(Elm_Gen_Item *it)
702 const char *selectraise;
703 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
704 (!it->wd->highlight) ||
705 (it->generation < it->wd->generation) ||
706 (it->highlighted) || elm_widget_item_disabled_get(it) ||
707 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->deco_it_view) ||
708 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
710 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
711 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
712 selectraise = edje_object_data_get(VIEW(it), "selectraise");
713 if ((selectraise) && (!strcmp(selectraise, "on")))
715 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
716 else evas_object_raise(VIEW(it));
717 if ((it->item->group_item) && (it->item->group_item->realized))
718 evas_object_raise(it->item->VIEW(group_item));
720 it->highlighted = EINA_TRUE;
724 _item_unhighlight(Elm_Gen_Item *it)
726 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
727 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
728 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
729 if (!it->item->nostacking)
731 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
733 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
734 else evas_object_lower(VIEW(it));
738 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
739 else evas_object_raise(VIEW(it));
742 it->highlighted = EINA_FALSE;
746 _item_block_position_update(Eina_Inlist *list, int idx)
750 EINA_INLIST_FOREACH(list, tmp)
752 tmp->position = idx++;
753 tmp->position_update = EINA_TRUE;
758 _item_position_update(Eina_List *list, int idx)
763 EINA_LIST_FOREACH(list, l, it)
765 it->position = idx++;
766 it->position_update = EINA_TRUE;
771 _item_block_del(Elm_Gen_Item *it)
774 Item_Block *itb = it->item->block;
776 itb->items = eina_list_remove(itb->items, it);
778 itb->changed = EINA_TRUE;
779 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
780 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
783 il = EINA_INLIST_GET(itb);
784 Item_Block *itbn = (Item_Block *)(il->next);
786 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
789 _item_block_position_update(il->next, itb->position);
790 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
793 if (itbn) itbn->changed = EINA_TRUE;
797 if (itb->count < itb->wd->max_items_per_block/2)
799 il = EINA_INLIST_GET(itb);
800 Item_Block *itbp = (Item_Block *)(il->prev);
801 Item_Block *itbn = (Item_Block *)(il->next);
802 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
806 EINA_LIST_FREE(itb->items, it2)
808 it2->item->block = itbp;
809 itbp->items = eina_list_append(itbp->items, it2);
811 itbp->changed = EINA_TRUE;
813 _item_block_position_update(EINA_INLIST_GET(itb)->next,
815 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
816 EINA_INLIST_GET(itb));
819 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
823 Eina_List *last = eina_list_last(itb->items);
824 Elm_Gen_Item *it2 = last->data;
826 it2->item->block = itbn;
827 itb->items = eina_list_remove_list(itb->items, last);
828 itbn->items = eina_list_prepend(itbn->items, it2);
830 itbn->changed = EINA_TRUE;
832 _item_block_position_update(EINA_INLIST_GET(itb)->next,
835 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
843 _item_subitems_clear(Elm_Gen_Item *it)
845 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
846 Eina_List *tl = NULL, *l;
847 Elm_Object_Item *it2;
849 EINA_LIST_FOREACH(it->item->items, l, it2)
850 tl = eina_list_append(tl, it2);
851 EINA_LIST_FREE(tl, it2)
852 elm_object_item_del(it2);
856 _item_del(Elm_Gen_Item *it)
858 Evas_Object *obj = WIDGET(it);
860 evas_event_freeze(evas_object_evas_get(obj));
861 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
862 if (it->wd->show_item == it) it->wd->show_item = NULL;
863 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
864 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
865 if (it->item->block) _item_block_del(it);
866 if (it->item->queued)
867 it->wd->queue = eina_list_remove(it->wd->queue, it);
868 if (it->wd->anchor_item == it)
870 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
871 if (!it->wd->anchor_item)
872 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
874 if (it->wd->expanded_item == it) it->wd->expanded_item = NULL;
875 if (it->wd->expanded_next_item == it) it->wd->expanded_next_item = NULL;
877 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
878 if (it->item->swipe_timer)
880 ecore_timer_del(it->item->swipe_timer);
881 it->item->swipe_timer = NULL;
883 _elm_genlist_item_del_serious(it);
884 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
885 evas_event_thaw(evas_object_evas_get(obj));
886 evas_event_thaw_eval(evas_object_evas_get(obj));
890 _clear_cb(Widget_Data *wd)
892 wd->anchor_item = NULL;
893 if (wd->queue_idle_enterer)
895 ecore_idle_enterer_del(wd->queue_idle_enterer);
896 wd->queue_idle_enterer = NULL;
898 if (wd->must_recalc_idler)
900 ecore_idler_del(wd->must_recalc_idler);
901 wd->must_recalc_idler = NULL;
903 if (wd->queue) wd->queue = eina_list_free(wd->queue);
904 if (wd->reorder_move_animator)
906 ecore_animator_del(wd->reorder_move_animator);
907 wd->reorder_move_animator = NULL;
909 wd->show_item = NULL;
910 wd->reorder_old_pan_y = 0;
914 _item_unselect(Elm_Gen_Item *it)
916 if ((it->generation < it->wd->generation) || (!it->selected)) return;
917 it->selected = EINA_FALSE;
918 it->wd->selected = eina_list_remove(it->wd->selected, it);
919 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
923 _mouse_move(void *data,
924 Evas *evas __UNUSED__,
928 Elm_Gen_Item *it = data;
929 Evas_Event_Mouse_Move *ev = event_info;
930 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
931 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
933 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
935 if (!it->wd->on_hold)
937 it->wd->on_hold = EINA_TRUE;
938 if ((!it->wd->wasselected) && (!it->flipped))
940 _item_unhighlight(it);
945 if (it->wd->multitouched)
947 it->wd->cur_x = ev->cur.canvas.x;
948 it->wd->cur_y = ev->cur.canvas.y;
951 if ((it->dragging) && (it->down))
953 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
956 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
957 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
958 if (abs((it->wd->history[it->wd->movements].x -
959 it->wd->history[0].x)) > 40)
960 it->wd->swipe = EINA_TRUE;
966 ecore_timer_del(it->long_timer);
967 it->long_timer = NULL;
969 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
972 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
976 ecore_timer_del(it->long_timer);
977 it->long_timer = NULL;
979 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
981 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
982 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
984 if (!it->wd->reorder_start_y)
985 it->wd->reorder_start_y = it->item->block->y + it->y;
989 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
990 y_pos = oy + oh - it->wd->reorder_it->item->h;
994 if (it->deco_all_view)
995 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
997 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
999 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1000 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1004 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1005 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1006 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1007 x = ev->cur.canvas.x - x;
1008 y = ev->cur.canvas.y - y;
1011 if (adx < 0) adx = -dx;
1014 if (ady < 0) ady = -dy;
1017 if ((adx > minw) || (ady > minh))
1019 it->dragging = EINA_TRUE;
1022 ecore_timer_del(it->long_timer);
1023 it->long_timer = NULL;
1025 if (!it->wd->wasselected)
1027 _item_unhighlight(it);
1033 evas_object_smart_callback_call(WIDGET(it),
1034 SIG_DRAG_START_UP, it);
1038 evas_object_smart_callback_call(WIDGET(it),
1039 SIG_DRAG_START_LEFT, it);
1041 evas_object_smart_callback_call(WIDGET(it),
1042 SIG_DRAG_START_RIGHT, it);
1048 evas_object_smart_callback_call(WIDGET(it),
1049 SIG_DRAG_START_DOWN, it);
1053 evas_object_smart_callback_call(WIDGET(it),
1054 SIG_DRAG_START_LEFT, it);
1056 evas_object_smart_callback_call(WIDGET(it),
1057 SIG_DRAG_START_RIGHT, it);
1064 _long_press(void *data)
1066 Elm_Gen_Item *it = data, *it_tmp;
1067 Eina_List *list, *l;
1069 it->long_timer = NULL;
1070 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1071 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1072 return ECORE_CALLBACK_CANCEL;
1073 it->wd->longpressed = EINA_TRUE;
1074 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1075 if ((it->wd->reorder_mode) && (!it->group))
1077 it->wd->reorder_it = it;
1078 it->wd->reorder_start_y = 0;
1079 if (it->deco_all_view)
1080 evas_object_raise(it->deco_all_view);
1082 evas_object_raise(VIEW(it));
1084 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1085 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1087 list = elm_genlist_realized_items_get(it->wd->obj);
1088 EINA_LIST_FOREACH(list, l, it_tmp)
1090 if (it != it_tmp) _item_unselect(it_tmp);
1092 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1094 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1095 return ECORE_CALLBACK_RENEW;
1098 if (!it->wd->decorate_all_mode)
1099 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1101 return ECORE_CALLBACK_CANCEL;
1105 _swipe(Elm_Gen_Item *it)
1110 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1111 elm_widget_item_disabled_get(it)) return;
1112 it->wd->swipe = EINA_FALSE;
1113 for (i = 0; i < it->wd->movements; i++)
1115 sum += it->wd->history[i].x;
1116 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1119 sum /= it->wd->movements;
1120 if (abs(sum - it->wd->history[0].x) <= 10) return;
1121 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1125 _swipe_cancel(void *data)
1127 Elm_Gen_Item *it = data;
1129 if (!it) return ECORE_CALLBACK_CANCEL;
1130 it->wd->swipe = EINA_FALSE;
1131 it->wd->movements = 0;
1132 return ECORE_CALLBACK_RENEW;
1136 _multi_cancel(void *data)
1138 Widget_Data *wd = data;
1140 if (!wd) return ECORE_CALLBACK_CANCEL;
1141 wd->multi_timeout = EINA_TRUE;
1142 return ECORE_CALLBACK_RENEW;
1146 _multi_touch_gesture_eval(void *data)
1148 Elm_Gen_Item *it = data;
1150 it->wd->multitouched = EINA_FALSE;
1151 if (it->wd->multi_timer)
1153 ecore_timer_del(it->wd->multi_timer);
1154 it->wd->multi_timer = NULL;
1156 if (it->wd->multi_timeout)
1158 it->wd->multi_timeout = EINA_FALSE;
1162 Evas_Coord minw = 0, minh = 0;
1163 Evas_Coord off_x, off_y, off_mx, off_my;
1165 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1166 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1167 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1168 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1169 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1171 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1173 if ((off_x + off_mx) > (off_y + off_my))
1175 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1176 evas_object_smart_callback_call(WIDGET(it),
1177 SIG_MULTI_SWIPE_RIGHT, it);
1178 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1179 evas_object_smart_callback_call(WIDGET(it),
1180 SIG_MULTI_SWIPE_LEFT, it);
1181 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1182 evas_object_smart_callback_call(WIDGET(it),
1183 SIG_MULTI_PINCH_OUT, it);
1185 evas_object_smart_callback_call(WIDGET(it),
1186 SIG_MULTI_PINCH_IN, it);
1190 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1191 evas_object_smart_callback_call(WIDGET(it),
1192 SIG_MULTI_SWIPE_DOWN, it);
1193 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1194 evas_object_smart_callback_call(WIDGET(it),
1195 SIG_MULTI_SWIPE_UP, it);
1196 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1197 evas_object_smart_callback_call(WIDGET(it),
1198 SIG_MULTI_PINCH_OUT, it);
1200 evas_object_smart_callback_call(WIDGET(it),
1201 SIG_MULTI_PINCH_IN, it);
1204 it->wd->multi_timeout = EINA_FALSE;
1208 _multi_down(void *data,
1209 Evas *evas __UNUSED__,
1210 Evas_Object *obj __UNUSED__,
1213 Elm_Gen_Item *it = data;
1214 Evas_Event_Multi_Down *ev = event_info;
1216 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1217 it->wd->multi_device = ev->device;
1218 it->wd->multi_down = EINA_TRUE;
1219 it->wd->multitouched = EINA_TRUE;
1220 it->wd->prev_mx = ev->canvas.x;
1221 it->wd->prev_my = ev->canvas.y;
1222 if (!it->wd->wasselected)
1224 _item_unhighlight(it);
1227 it->wd->wasselected = EINA_FALSE;
1228 it->wd->longpressed = EINA_FALSE;
1231 ecore_timer_del(it->long_timer);
1232 it->long_timer = NULL;
1236 it->dragging = EINA_FALSE;
1237 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1239 if (it->item->swipe_timer)
1241 ecore_timer_del(it->item->swipe_timer);
1242 it->item->swipe_timer = NULL;
1244 if (it->wd->on_hold)
1246 it->wd->swipe = EINA_FALSE;
1247 it->wd->movements = 0;
1248 it->wd->on_hold = EINA_FALSE;
1253 _multi_up(void *data,
1254 Evas *evas __UNUSED__,
1255 Evas_Object *obj __UNUSED__,
1258 Elm_Gen_Item *it = data;
1259 Evas_Event_Multi_Up *ev = event_info;
1261 if (it->wd->multi_device != ev->device) return;
1262 it->wd->multi_device = 0;
1263 it->wd->multi_down = EINA_FALSE;
1264 if (it->wd->mouse_down) return;
1265 _multi_touch_gesture_eval(data);
1269 _multi_move(void *data,
1270 Evas *evas __UNUSED__,
1271 Evas_Object *obj __UNUSED__,
1274 Elm_Gen_Item *it = data;
1275 Evas_Event_Multi_Move *ev = event_info;
1277 if (it->wd->multi_device != ev->device) return;
1278 it->wd->cur_mx = ev->cur.canvas.x;
1279 it->wd->cur_my = ev->cur.canvas.y;
1283 _mouse_down(void *data,
1284 Evas *evas __UNUSED__,
1288 Elm_Gen_Item *it = data;
1289 Evas_Event_Mouse_Down *ev = event_info;
1292 if (ev->button != 1) return;
1293 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1295 it->wd->on_hold = EINA_TRUE;
1298 it->down = EINA_TRUE;
1299 it->dragging = EINA_FALSE;
1300 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1301 it->dx = ev->canvas.x - x;
1302 it->dy = ev->canvas.y - y;
1303 it->wd->mouse_down = EINA_TRUE;
1304 if (!it->wd->multitouched)
1306 it->wd->prev_x = ev->canvas.x;
1307 it->wd->prev_y = ev->canvas.y;
1308 it->wd->multi_timeout = EINA_FALSE;
1309 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1310 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1312 it->wd->longpressed = EINA_FALSE;
1313 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1314 else it->wd->on_hold = EINA_FALSE;
1315 if (it->wd->on_hold) return;
1316 it->wd->wasselected = it->selected;
1317 _item_highlight(it);
1318 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1319 if ((!elm_widget_item_disabled_get(it)) &&
1320 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1322 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1323 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1325 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1326 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1327 if (it->long_timer) ecore_timer_del(it->long_timer);
1329 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1332 it->long_timer = NULL;
1333 it->wd->swipe = EINA_FALSE;
1334 it->wd->movements = 0;
1338 _mouse_up(void *data,
1339 Evas *evas __UNUSED__,
1340 Evas_Object *obj __UNUSED__,
1343 Elm_Gen_Item *it = data;
1344 Evas_Event_Mouse_Up *ev = event_info;
1345 Eina_Bool dragged = EINA_FALSE;
1347 if (ev->button != 1) return;
1348 it->down = EINA_FALSE;
1349 it->wd->mouse_down = EINA_FALSE;
1350 if (it->wd->multitouched)
1352 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1353 if (it->wd->multi_down) return;
1354 _multi_touch_gesture_eval(data);
1357 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1358 else it->wd->on_hold = EINA_FALSE;
1361 ecore_timer_del(it->long_timer);
1362 it->long_timer = NULL;
1366 it->dragging = EINA_FALSE;
1367 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1370 if (it->item->swipe_timer)
1372 ecore_timer_del(it->item->swipe_timer);
1373 it->item->swipe_timer = NULL;
1375 if (it->wd->multi_timer)
1377 ecore_timer_del(it->wd->multi_timer);
1378 it->wd->multi_timer = NULL;
1379 it->wd->multi_timeout = EINA_FALSE;
1381 if (it->wd->on_hold)
1383 if (it->wd->swipe) _swipe(data);
1384 it->wd->longpressed = EINA_FALSE;
1385 it->wd->on_hold = EINA_FALSE;
1388 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1390 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1392 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1394 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1395 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1397 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1398 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1402 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1403 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1405 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1406 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1407 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1408 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1410 if (it->wd->longpressed)
1412 it->wd->longpressed = EINA_FALSE;
1413 if ((!it->wd->wasselected) && (!it->flipped))
1415 _item_unhighlight(it);
1418 it->wd->wasselected = EINA_FALSE;
1423 if (it->want_unrealize)
1425 _elm_genlist_item_unrealize(it, EINA_FALSE);
1426 if (it->item->block->want_unrealize)
1427 _item_block_unrealize(it->item->block);
1430 if (elm_widget_item_disabled_get(it) || (dragged) ||
1431 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1433 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1438 _item_highlight(it);
1443 _item_unhighlight(it);
1451 Widget_Data *wd = it->wd;
1454 while (wd->selected)
1456 _item_unhighlight(wd->selected->data);
1457 _item_unselect(wd->selected->data);
1463 const Eina_List *l, *l_next;
1466 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1469 _item_unhighlight(it2);
1470 _item_unselect(it2);
1472 //_item_highlight(it);
1475 _item_highlight(it);
1481 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1483 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1485 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1487 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1489 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1491 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1493 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1498 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1500 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1502 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1504 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1506 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1508 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1510 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1515 _signal_expand_toggle(void *data,
1516 Evas_Object *obj __UNUSED__,
1517 const char *emission __UNUSED__,
1518 const char *source __UNUSED__)
1520 Elm_Gen_Item *it = data;
1522 if (it->item->expanded)
1523 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1525 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1529 _signal_expand(void *data,
1530 Evas_Object *obj __UNUSED__,
1531 const char *emission __UNUSED__,
1532 const char *source __UNUSED__)
1534 Elm_Gen_Item *it = data;
1536 if (!it->item->expanded)
1537 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1541 _signal_contract(void *data,
1542 Evas_Object *obj __UNUSED__,
1543 const char *emission __UNUSED__,
1544 const char *source __UNUSED__)
1546 Elm_Gen_Item *it = data;
1548 if (it->item->expanded)
1549 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1553 _scr_hold_timer_cb(void *data)
1555 if (!data) return ECORE_CALLBACK_CANCEL;
1556 Widget_Data *wd = data;
1557 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1558 wd->scr_hold_timer = NULL;
1559 return ECORE_CALLBACK_CANCEL;
1563 _decorate_item_finished_signal_cb(void *data,
1565 const char *emission __UNUSED__,
1566 const char *source __UNUSED__)
1570 Elm_Gen_Item *it = data;
1571 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1573 Evas *te = evas_object_evas_get(obj);
1575 evas_event_freeze(te);
1576 it->item->nocache_once = EINA_FALSE;
1577 _decorate_item_unrealize(it);
1578 if (it->item->group_item)
1579 evas_object_raise(it->item->VIEW(group_item));
1580 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1581 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1582 evas_event_thaw(te);
1583 evas_event_thaw_eval(te);
1587 _item_cache_clean(Widget_Data *wd)
1589 evas_event_freeze(evas_object_evas_get(wd->obj));
1590 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1594 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1595 wd->item_cache = eina_inlist_remove(wd->item_cache,
1596 wd->item_cache->last);
1597 wd->item_cache_count--;
1598 if (itc->spacer) evas_object_del(itc->spacer);
1599 if (itc->base_view) evas_object_del(itc->base_view);
1600 eina_stringshare_del(itc->item_style);
1603 evas_event_thaw(evas_object_evas_get(wd->obj));
1604 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1608 _item_cache_zero(Widget_Data *wd)
1610 int pmax = wd->item_cache_max;
1611 wd->item_cache_max = 0;
1612 _item_cache_clean(wd);
1613 wd->item_cache_max = pmax;
1617 _item_cache_add(Elm_Gen_Item *it)
1621 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1622 if (it->wd->item_cache_max <= 0)
1624 evas_object_del(VIEW(it));
1628 evas_object_del(it->spacer);
1631 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1632 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1636 it->wd->item_cache_count++;
1637 itc = calloc(1, sizeof(Item_Cache));
1640 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1641 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1644 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1645 EINA_INLIST_GET(itc));
1646 itc->spacer = it->spacer;
1648 itc->base_view = VIEW(it);
1650 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1651 evas_object_hide(itc->base_view);
1652 evas_object_move(itc->base_view, -9999, -9999);
1653 itc->item_style = eina_stringshare_add(it->itc->item_style);
1654 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1655 itc->selected = it->selected;
1656 itc->disabled = elm_widget_item_disabled_get(it);
1657 itc->expanded = it->item->expanded;
1660 ecore_timer_del(it->long_timer);
1661 it->long_timer = NULL;
1663 if (it->item->swipe_timer)
1665 ecore_timer_del(it->item->swipe_timer);
1666 it->item->swipe_timer = NULL;
1668 // FIXME: other callbacks?
1669 edje_object_signal_callback_del_full(itc->base_view,
1670 "elm,action,expand,toggle",
1671 "elm", _signal_expand_toggle, it);
1672 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1674 _signal_expand, it);
1675 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1676 "elm", _signal_contract, it);
1677 _item_mouse_callbacks_del(it, itc->base_view);
1678 _item_cache_clean(it->wd);
1679 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1680 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1684 _item_cache_find(Elm_Gen_Item *it)
1689 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1690 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1692 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1694 if ((itc->tree == tree) &&
1695 (((!it->itc->item_style) && (!itc->item_style)) ||
1696 (it->itc->item_style && itc->item_style &&
1697 (!strcmp(it->itc->item_style, itc->item_style)))))
1699 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1700 EINA_INLIST_GET(itc));
1701 it->wd->item_cache_count--;
1709 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1711 if (it->position_update || it->item->block->position_update)
1713 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1714 it->position_update = EINA_FALSE;
1719 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1721 if (!it->item->nostacking)
1723 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1725 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1726 else evas_object_lower(VIEW(it));
1730 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1731 else evas_object_raise(VIEW(it));
1735 if (it->item->order_num_in & 0x1)
1737 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1738 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1742 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1743 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1748 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1752 if (it->selected != itc->selected)
1756 edje_object_signal_emit(VIEW(it),
1757 "elm,state,selected", "elm");
1759 if (it->deco_all_view)
1760 edje_object_signal_emit(it->deco_all_view,
1761 "elm,state,selected", "elm");
1764 if (elm_widget_item_disabled_get(it) != itc->disabled)
1766 if (elm_widget_item_disabled_get(it))
1767 edje_object_signal_emit(VIEW(it),
1768 "elm,state,disabled", "elm");
1769 if (it->deco_all_view)
1770 edje_object_signal_emit(it->deco_all_view,
1771 "elm,state,disabled", "elm");
1773 if (it->item->expanded != itc->expanded)
1775 if (it->item->expanded)
1776 edje_object_signal_emit(VIEW(it),
1777 "elm,state,expanded", "elm");
1778 if (it->deco_all_view)
1779 edje_object_signal_emit(it->deco_all_view,
1780 "elm,state,expanded", "elm");
1787 edje_object_signal_emit(VIEW(it),
1788 "elm,state,selected", "elm");
1789 if (it->deco_all_view)
1790 edje_object_signal_emit(it->deco_all_view,
1791 "elm,state,selected", "elm");
1794 if (elm_widget_item_disabled_get(it))
1796 edje_object_signal_emit(VIEW(it),
1797 "elm,state,disabled", "elm");
1798 if (it->deco_all_view)
1799 edje_object_signal_emit(it->deco_all_view,
1800 "elm,state,disabled", "elm");
1802 if (it->item->expanded)
1804 edje_object_signal_emit(VIEW(it),
1805 "elm,state,expanded", "elm");
1806 if (it->deco_all_view)
1807 edje_object_signal_emit(it->deco_all_view,
1808 "elm,state,expanded", "elm");
1814 _item_mode_content_realize(Elm_Gen_Item *it,
1815 Evas_Object *target,
1818 Eina_List **contents_list)
1820 Eina_List *res = *contents_list;
1822 if (it->itc->func.content_get)
1827 EINA_LIST_FOREACH(*source, l, key)
1829 if (parts && fnmatch(parts, key, FNM_PERIOD))
1832 Evas_Object *ic = it->itc->func.content_get
1833 ((void *)it->base.data, WIDGET(it), l->data);
1837 res = eina_list_append(res, ic);
1838 edje_object_part_swallow(target, key, ic);
1839 evas_object_show(ic);
1840 elm_widget_sub_object_add(WIDGET(it), ic);
1841 if (it->item->deco_it_view || it->wd->decorate_all_mode)
1843 if (elm_widget_item_disabled_get(it))
1844 elm_widget_disabled_set(ic, EINA_TRUE);
1854 _item_mode_content_unrealize(Elm_Gen_Item *it,
1855 Evas_Object *target,
1858 Eina_List **contents_list)
1860 Eina_List *res = *contents_list;
1862 if (it->itc->func.content_get)
1866 Evas_Object *ic = NULL;
1868 EINA_LIST_FOREACH(*source, l, key)
1870 if (parts && fnmatch(parts, key, FNM_PERIOD))
1873 ic = edje_object_part_swallow_get(target, key);
1876 res = eina_list_remove(res, ic);
1877 edje_object_part_unswallow(target, ic);
1878 evas_object_del(ic);
1887 _item_cache_free(Item_Cache *itc)
1889 if (itc->spacer) evas_object_del(itc->spacer);
1890 if (itc->base_view) evas_object_del(itc->base_view);
1891 eina_stringshare_del(itc->item_style);
1896 _item_text_realize(Elm_Gen_Item *it,
1897 Evas_Object *target,
1901 if (it->itc->func.text_get)
1907 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1908 EINA_LIST_FOREACH(*source, l, key)
1910 if (parts && fnmatch(parts, key, FNM_PERIOD))
1913 char *s = it->itc->func.text_get
1914 ((void *)it->base.data, WIDGET(it), key);
1918 edje_object_part_text_set(target, key, s);
1923 edje_object_part_text_set(target, key, "");
1930 _item_content_unrealize(Elm_Gen_Item *it,
1931 Evas_Object *target,
1935 Eina_List *res = it->content_objs;
1937 if (it->itc->func.content_get)
1941 Evas_Object *ic = NULL;
1943 EINA_LIST_FOREACH(*source, l, key)
1945 if (parts && fnmatch(parts, key, FNM_PERIOD))
1948 ic = edje_object_part_swallow_get(target, key);
1951 res = eina_list_remove(res, ic);
1952 edje_object_part_unswallow(target, ic);
1953 evas_object_del(ic);
1962 _item_content_realize(Elm_Gen_Item *it,
1963 Evas_Object *target,
1967 Eina_List *res = it->content_objs;
1969 if (it->itc->func.content_get)
1973 Evas_Object *ic = NULL;
1976 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1978 EINA_LIST_FOREACH(*source, l, key)
1980 if (parts && fnmatch(parts, key, FNM_PERIOD))
1983 if (it->itc->func.content_get)
1984 ic = it->itc->func.content_get
1985 ((void *)it->base.data, WIDGET(it), key);
1988 res = eina_list_append(res, ic);
1989 edje_object_part_swallow(target, key, ic);
1990 evas_object_show(ic);
1991 elm_widget_sub_object_add(WIDGET(it), ic);
1992 if (elm_widget_item_disabled_get(it))
1993 elm_widget_disabled_set(ic, EINA_TRUE);
2002 _item_state_realize(Elm_Gen_Item *it,
2003 Evas_Object *target,
2007 if (it->itc->func.state_get)
2014 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2015 EINA_LIST_FOREACH(*source, l, key)
2017 if (parts && fnmatch(parts, key, FNM_PERIOD))
2020 Eina_Bool on = it->itc->func.state_get
2021 ((void *)it->base.data, WIDGET(it), key);
2025 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2026 edje_object_signal_emit(target, buf, "elm");
2030 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2031 edje_object_signal_emit(target, buf, "elm");
2038 _item_realize(Elm_Gen_Item *it,
2042 const char *treesize;
2045 Item_Cache *itc = NULL;
2047 if (it->generation < it->wd->generation) return;
2048 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2051 if (it->item->order_num_in != in)
2053 it->item->order_num_in = in;
2054 _elm_genlist_item_odd_even_update(it);
2055 _elm_genlist_item_state_update(it, NULL);
2056 _elm_genlist_item_index_update(it);
2058 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2059 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2062 it->item->order_num_in = in;
2064 if (it->item->nocache_once)
2065 it->item->nocache_once = EINA_FALSE;
2066 else if (!it->item->nocache)
2067 itc = _item_cache_find(it);
2068 if (itc && (!it->wd->tree_effect_enabled))
2070 VIEW(it) = itc->base_view;
2071 itc->base_view = NULL;
2072 it->spacer = itc->spacer;
2077 const char *stacking_even;
2078 const char *stacking;
2080 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2081 edje_object_scale_set(VIEW(it),
2082 elm_widget_scale_get(WIDGET(it)) *
2083 _elm_config->scale);
2084 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2085 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2087 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2088 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2090 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2092 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2093 elm_widget_style_get(WIDGET(it)));
2095 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2096 if (!stacking_even) stacking_even = "above";
2097 it->item->stacking_even = !!strcmp("above", stacking_even);
2099 stacking = edje_object_data_get(VIEW(it), "stacking");
2100 if (!stacking) stacking = "yes";
2101 it->item->nostacking = !!strcmp("yes", stacking);
2103 edje_object_mirrored_set(VIEW(it),
2104 elm_widget_mirrored_get(WIDGET(it)));
2107 _elm_genlist_item_odd_even_update(it);
2109 treesize = edje_object_data_get(VIEW(it), "treesize");
2110 if (treesize) tsize = atoi(treesize);
2111 if (!it->spacer && treesize)
2114 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2115 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2116 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2120 evas_object_size_hint_min_set(it->spacer,
2121 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2122 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2126 edje_object_signal_callback_add(VIEW(it),
2127 "elm,action,expand,toggle",
2128 "elm", _signal_expand_toggle, it);
2129 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2130 "elm", _signal_expand, it);
2131 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2132 "elm", _signal_contract, it);
2133 _item_mouse_callbacks_add(it, VIEW(it));
2135 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2136 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2137 _decorate_all_item_realize(it, EINA_FALSE);
2139 _elm_genlist_item_state_update(it, itc);
2140 _elm_genlist_item_index_update(it);
2143 if ((calc) && (it->wd->homogeneous) &&
2144 ((it->wd->item_width) ||
2145 ((it->wd->item_width) && (it->wd->group_item_width))))
2147 /* homogenous genlist shortcut */
2148 if (!it->item->mincalcd)
2152 it->item->w = it->item->minw = it->wd->group_item_width;
2153 it->item->h = it->item->minh = it->wd->group_item_height;
2157 it->item->w = it->item->minw = it->wd->item_width;
2158 it->item->h = it->item->minh = it->wd->item_height;
2160 it->item->mincalcd = EINA_TRUE;
2165 /* FIXME: If you see that assert, please notify us and we
2166 will clean our mess */
2167 assert(eina_list_count(it->content_objs) == 0);
2169 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2170 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2171 _item_state_realize(it, VIEW(it), &it->states, NULL);
2174 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2175 if (!(it->item->flip_contents))
2176 it->item->flip_contents =
2177 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2178 it->item->flip_content_objs =
2179 _item_mode_content_realize(it, VIEW(it),
2180 &it->item->flip_contents, NULL,
2181 &it->item->flip_content_objs);
2184 if (!it->item->mincalcd)
2186 Evas_Coord mw = -1, mh = -1;
2188 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2189 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2190 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2191 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2193 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2194 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2195 it->item->w = it->item->minw = mw;
2196 it->item->h = it->item->minh = mh;
2197 it->item->mincalcd = EINA_TRUE;
2199 if ((!it->wd->group_item_width) && (it->group))
2201 it->wd->group_item_width = mw;
2202 it->wd->group_item_height = mh;
2204 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2206 it->wd->item_width = mw;
2207 it->wd->item_height = mh;
2210 if (!calc) evas_object_show(VIEW(it));
2213 if (it->tooltip.content_cb)
2215 elm_widget_item_tooltip_content_cb_set(it,
2216 it->tooltip.content_cb,
2217 it->tooltip.data, NULL);
2218 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2219 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2222 if (it->mouse_cursor)
2223 elm_widget_item_cursor_set(it, it->mouse_cursor);
2225 it->realized = EINA_TRUE;
2226 it->want_unrealize = EINA_FALSE;
2228 if (itc) _item_cache_free(itc);
2229 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2230 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2233 if (it->item->tree_effect_hideme)
2235 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2236 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2237 it->item->tree_effect_hideme = EINA_FALSE;
2239 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2242 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2244 if (it->itc->decorate_all_item_style)
2246 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2247 edje_object_message_signal_process(it->deco_all_view);
2250 edje_object_message_signal_process(VIEW(it));
2254 _item_unrealize_cb(Elm_Gen_Item *it)
2256 if (it->item->nocache_once || it->item->nocache)
2258 evas_object_del(VIEW(it));
2262 evas_object_del(it->spacer);
2268 edje_object_mirrored_set(VIEW(it),
2269 elm_widget_mirrored_get(WIDGET(it)));
2270 edje_object_scale_set(VIEW(it),
2271 elm_widget_scale_get(WIDGET(it))
2272 * _elm_config->scale);
2273 _item_cache_add(it);
2276 _decorate_item_unrealize(it);
2278 it->realized = EINA_FALSE;
2279 it->want_unrealize = EINA_FALSE;
2280 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2284 _item_block_recalc(Item_Block *itb,
2290 Evas_Coord minw = 0, minh = 0;
2291 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2294 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2296 EINA_LIST_FOREACH(itb->items, l, it)
2298 if (it->generation < it->wd->generation) continue;
2299 showme |= it->item->showme;
2304 if (!it->item->mincalcd) changed = EINA_TRUE;
2307 _item_realize(it, in, EINA_TRUE);
2308 _elm_genlist_item_unrealize(it, EINA_TRUE);
2313 _item_realize(it, in, EINA_TRUE);
2314 _elm_genlist_item_unrealize(it, EINA_TRUE);
2319 if (!it->item->mincalcd) changed = EINA_TRUE;
2320 _item_realize(it, in, EINA_FALSE);
2322 minh += it->item->minh;
2323 if (minw < it->item->minw) minw = it->item->minw;
2329 if (changed) itb->wd->pan_changed = changed;
2332 itb->changed = EINA_FALSE;
2333 itb->position_update = EINA_FALSE;
2334 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2335 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2340 _item_block_realize(Item_Block *itb)
2342 if (itb->realized) return;
2343 itb->realized = EINA_TRUE;
2344 itb->want_unrealize = EINA_FALSE;
2348 _item_block_unrealize(Item_Block *itb)
2352 Eina_Bool dragging = EINA_FALSE;
2354 if (!itb->realized) return;
2355 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2356 EINA_LIST_FOREACH(itb->items, l, it)
2358 if (itb->must_recalc || !it->group)
2362 dragging = EINA_TRUE;
2363 it->want_unrealize = EINA_TRUE;
2366 _elm_genlist_item_unrealize(it, EINA_FALSE);
2371 itb->realized = EINA_FALSE;
2372 itb->want_unrealize = EINA_TRUE;
2375 itb->want_unrealize = EINA_FALSE;
2376 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2377 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2381 _get_space_for_reorder_item(Elm_Gen_Item *it)
2383 Evas_Coord rox, roy, row, roh, oy, oh;
2384 Eina_Bool top = EINA_FALSE;
2385 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2386 if (!reorder_it) return 0;
2388 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2389 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2391 if ((it->wd->reorder_start_y < it->item->block->y) &&
2392 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2394 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2395 if (it->item->block->count == 1)
2396 it->wd->reorder_rel = it;
2398 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2399 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2401 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2404 it->item->block->reorder_offset = 0;
2406 it->item->scrl_y += it->item->block->reorder_offset;
2408 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2409 rox, roy + (roh / 2), row, 1));
2412 it->wd->reorder_rel = it;
2413 it->item->scrl_y += it->wd->reorder_it->item->h;
2414 return it->wd->reorder_it->item->h;
2421 _reorder_move_animator_cb(void *data)
2423 Elm_Gen_Item *it = data;
2424 Eina_Bool down = EINA_FALSE;
2426 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2428 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2430 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2433 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2434 if (diff > it->item->h) y = diff / 2;
2436 if (it->item->old_scrl_y < it->item->scrl_y)
2438 it->item->old_scrl_y += y;
2441 else if (it->item->old_scrl_y > it->item->scrl_y)
2443 it->item->old_scrl_y -= y;
2447 if (it->deco_all_view)
2448 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2450 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2451 _group_items_recalc(it->wd);
2453 if ((it->wd->reorder_pan_move) ||
2454 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2455 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2457 it->item->old_scrl_y = it->item->scrl_y;
2458 it->item->move_effect_enabled = EINA_FALSE;
2459 it->wd->reorder_move_animator = NULL;
2460 return ECORE_CALLBACK_CANCEL;
2462 return ECORE_CALLBACK_RENEW;
2466 _item_position(Elm_Gen_Item *it,
2474 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2475 evas_object_resize(view, it->item->w, it->item->h);
2476 evas_object_move(view, it_x, it_y);
2477 evas_object_show(view);
2478 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2479 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2483 _item_block_position(Item_Block *itb,
2489 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2490 Eina_Bool vis = EINA_FALSE;
2492 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2493 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2494 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2496 EINA_LIST_FOREACH(itb->items, l, it)
2498 if (it->generation < it->wd->generation) continue;
2499 else if (it->wd->reorder_it == it) continue;
2502 it->item->w = itb->w;
2503 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2504 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2506 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2507 cvx, cvy, cvw, cvh));
2510 if ((itb->realized) && (!it->realized))
2512 if (vis) _item_realize(it, in, EINA_FALSE);
2516 if (vis || it->dragging)
2518 if (it->wd->reorder_mode)
2519 y += _get_space_for_reorder_item(it);
2520 git = it->item->group_item;
2523 if (git->item->scrl_y < oy)
2524 git->item->scrl_y = oy;
2525 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2526 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2527 git->item->want_realize = EINA_TRUE;
2529 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2531 if (!it->item->move_effect_enabled)
2533 it->item->move_effect_enabled = EINA_TRUE;
2534 it->wd->reorder_move_animator =
2536 _reorder_move_animator_cb, it);
2539 if (!it->item->move_effect_enabled)
2541 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2542 _decorate_all_item_position(it, it->item->scrl_x,
2546 if (!it->wd->tree_effect_enabled ||
2547 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2548 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2549 (it->item->old_scrl_y == it->item->scrl_y)))
2551 if (it->item->deco_it_view)
2552 _item_position(it, it->item->deco_it_view,
2556 _item_position(it, VIEW(it), it->item->scrl_x,
2560 it->item->old_scrl_y = it->item->scrl_y;
2565 if (!it->wd->tree_effect_animator)
2566 _elm_genlist_item_unrealize(it, EINA_FALSE);
2573 if (vis) it->item->want_realize = EINA_TRUE;
2577 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2578 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2582 _group_items_recalc(void *data)
2584 Widget_Data *wd = data;
2588 evas_event_freeze(evas_object_evas_get(wd->obj));
2589 EINA_LIST_FOREACH(wd->group_items, l, git)
2591 if (git->item->want_realize)
2594 _item_realize(git, 0, EINA_FALSE);
2595 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2596 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2597 evas_object_show(VIEW(git));
2598 evas_object_raise(VIEW(git));
2600 else if (!git->item->want_realize && git->realized)
2603 _elm_genlist_item_unrealize(git, EINA_FALSE);
2606 evas_event_thaw(evas_object_evas_get(wd->obj));
2607 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2611 _must_recalc_idler(void *data)
2613 Widget_Data *wd = data;
2614 if (wd->calc_job) ecore_job_del(wd->calc_job);
2615 wd->calc_job = ecore_job_add(_calc_job, wd);
2616 wd->must_recalc_idler = NULL;
2617 return ECORE_CALLBACK_CANCEL;
2621 _scroll_item(Widget_Data *wd)
2623 Elm_Gen_Item *it = NULL;
2624 Evas_Coord gith = 0;
2625 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2626 if (!wd->show_item) return;
2628 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2630 dx = it->x + it->item->block->x;
2631 dy = it->y + it->item->block->y;
2632 dw = it->item->block->w;
2634 switch (wd->scrollto_type)
2636 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2637 if (it->item->group_item) gith = it->item->group_item->item->h;
2640 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2641 dy += ((it->item->h / 2) - (oh / 2));
2643 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2645 if ((wd->expanded_item) &&
2646 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2647 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2649 it = wd->expanded_item;
2650 if (it->item->group_item) gith = it->item->group_item->item->h;
2651 dx = it->x + it->item->block->x;
2652 dy = it->y + it->item->block->y - gith;
2653 dw = it->item->block->w;
2657 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2658 gith = it->item->group_item->item->h;
2665 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2667 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2669 it->item->showme = EINA_FALSE;
2670 wd->show_item = NULL;
2671 wd->auto_scroll_enabled = EINA_FALSE;
2672 wd->check_scroll = EINA_FALSE;
2676 _calc_job(void *data)
2678 Widget_Data *wd = data;
2679 Item_Block *itb, *chb = NULL;
2680 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2681 Evas_Coord pan_w = 0, pan_h = 0;
2683 Eina_Bool minw_change = EINA_FALSE;
2684 Eina_Bool did_must_recalc = EINA_FALSE;
2687 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2688 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2693 evas_event_freeze(evas_object_evas_get(wd->obj));
2694 EINA_INLIST_FOREACH(wd->blocks, itb)
2696 Eina_Bool showme = EINA_FALSE;
2699 showme = itb->showme;
2700 itb->showme = EINA_FALSE;
2703 if (itb->realized) _item_block_unrealize(itb);
2705 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2707 if (itb->must_recalc)
2711 EINA_LIST_FOREACH(itb->items, l, it)
2712 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2713 itb->changed = EINA_TRUE;
2714 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2715 if (itb->realized) _item_block_unrealize(itb);
2716 itb->must_recalc = EINA_FALSE;
2718 showme = _item_block_recalc(itb, in, EINA_FALSE);
2724 if (minw == -1) minw = itb->minw;
2725 else if ((!itb->must_recalc) && (minw < itb->minw))
2728 minw_change = EINA_TRUE;
2733 minw_change = EINA_TRUE;
2739 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2740 wd->check_scroll = EINA_TRUE;
2744 EINA_INLIST_FOREACH(wd->blocks, itb)
2750 if ((chb) && (EINA_INLIST_GET(chb)->next))
2752 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2754 if (itb->realized) _item_block_unrealize(itb);
2757 wd->realminw = minw;
2758 if (minw < wd->w) minw = wd->w;
2759 if ((minw != wd->minw) || (minh != wd->minh))
2763 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2764 _sizing_eval(wd->obj);
2765 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2770 it = wd->anchor_item;
2771 it_y = wd->anchor_y;
2772 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2773 it->item->block->y + it->y + it_y);
2774 wd->anchor_item = it;
2775 wd->anchor_y = it_y;
2778 if (did_must_recalc)
2780 if (!wd->must_recalc_idler)
2781 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2783 if (wd->check_scroll)
2785 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2786 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2787 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2788 switch (wd->scrollto_type)
2790 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2793 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2796 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2803 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2804 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2810 wd->calc_job = NULL;
2811 evas_object_smart_changed(wd->pan_smart);
2812 evas_event_thaw(evas_object_evas_get(wd->obj));
2813 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2817 _update_job(void *data)
2819 Widget_Data *wd = data;
2823 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2825 wd->update_job = NULL;
2828 evas_event_freeze(evas_object_evas_get(wd->obj));
2829 EINA_INLIST_FOREACH(wd->blocks, itb)
2831 Evas_Coord itminw, itminh;
2838 _item_block_position(itb, num);
2842 recalc = EINA_FALSE;
2843 EINA_LIST_FOREACH(itb->items, l2, it)
2845 if (it->item->updateme)
2847 itminw = it->item->minw;
2848 itminh = it->item->minh;
2850 it->item->updateme = EINA_FALSE;
2853 _elm_genlist_item_unrealize(it, EINA_FALSE);
2854 _item_realize(it, num, EINA_FALSE);
2855 position = EINA_TRUE;
2859 _item_realize(it, num, EINA_TRUE);
2860 _elm_genlist_item_unrealize(it, EINA_TRUE);
2862 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2867 itb->updateme = EINA_FALSE;
2870 position = EINA_TRUE;
2871 itb->changed = EINA_TRUE;
2872 _item_block_recalc(itb, num0, EINA_FALSE);
2873 _item_block_position(itb, num0);
2878 if (wd->calc_job) ecore_job_del(wd->calc_job);
2879 wd->calc_job = ecore_job_add(_calc_job, wd);
2881 evas_event_thaw(evas_object_evas_get(wd->obj));
2882 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2886 _pan_set(Evas_Object *obj,
2890 Pan *sd = evas_object_smart_data_get(obj);
2894 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2898 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2900 if ((itb->y + itb->h) > y)
2905 EINA_LIST_FOREACH(itb->items, l2, it)
2907 if ((itb->y + it->y) >= y)
2909 sd->wd->anchor_item = it;
2910 sd->wd->anchor_y = -(itb->y + it->y - y);
2917 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2921 _pan_get(Evas_Object *obj,
2925 Pan *sd = evas_object_smart_data_get(obj);
2928 if (x) *x = sd->wd->pan_x;
2929 if (y) *y = sd->wd->pan_y;
2933 _pan_max_get(Evas_Object *obj,
2937 Pan *sd = evas_object_smart_data_get(obj);
2941 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2942 ow = sd->wd->minw - ow;
2944 oh = sd->wd->minh - oh;
2951 _pan_min_get(Evas_Object *obj __UNUSED__,
2960 _pan_child_size_get(Evas_Object *obj,
2964 Pan *sd = evas_object_smart_data_get(obj);
2967 if (w) *w = sd->wd->minw;
2968 if (h) *h = sd->wd->minh;
2972 _pan_add(Evas_Object *obj)
2975 Evas_Object_Smart_Clipped_Data *cd;
2978 cd = evas_object_smart_data_get(obj);
2981 sd->__clipped_data = *cd;
2983 evas_object_smart_data_set(obj, sd);
2987 _pan_del(Evas_Object *obj)
2989 Pan *sd = evas_object_smart_data_get(obj);
2994 ecore_job_del(sd->resize_job);
2995 sd->resize_job = NULL;
3001 _pan_resize_job(void *data)
3005 _sizing_eval(sd->wd->obj);
3006 sd->resize_job = NULL;
3010 _pan_resize(Evas_Object *obj,
3014 Pan *sd = evas_object_smart_data_get(obj);
3018 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3019 if ((ow == w) && (oh == h)) return;
3020 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3023 if (sd->resize_job) ecore_job_del(sd->resize_job);
3024 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3026 sd->wd->pan_changed = EINA_TRUE;
3027 evas_object_smart_changed(obj);
3028 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3029 sd->wd->calc_job = NULL;
3033 _pan_calculate(Evas_Object *obj)
3035 Pan *sd = evas_object_smart_data_get(obj);
3037 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3043 evas_event_freeze(evas_object_evas_get(obj));
3045 if (sd->wd->pan_changed)
3048 sd->wd->pan_changed = EINA_FALSE;
3051 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3052 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3053 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3055 git->item->want_realize = EINA_FALSE;
3058 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3060 if (!sd->wd->tree_effect_animator)
3062 _item_tree_effect_before(sd->wd->expanded_item);
3063 evas_object_raise(sd->wd->alpha_bg);
3064 evas_object_show(sd->wd->alpha_bg);
3065 sd->wd->start_time = ecore_time_get();
3066 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3070 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3072 itb->w = sd->wd->minw;
3073 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3074 itb->y - sd->wd->pan_y + oy,
3076 cvx, cvy, cvw, cvh))
3078 if ((!itb->realized) || (itb->changed))
3079 _item_block_realize(itb);
3080 _item_block_position(itb, in);
3084 if (itb->realized) _item_block_unrealize(itb);
3088 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3089 _group_items_recalc(sd->wd);
3090 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3092 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3093 sd->wd->reorder_pan_move = EINA_TRUE;
3094 else sd->wd->reorder_pan_move = EINA_FALSE;
3095 evas_object_raise(sd->wd->VIEW(reorder_it));
3096 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3097 sd->wd->start_time = ecore_loop_time_get();
3100 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3101 _item_auto_scroll(sd->wd);
3103 evas_event_thaw(evas_object_evas_get(obj));
3104 evas_event_thaw_eval(evas_object_evas_get(obj));
3108 _pan_move(Evas_Object *obj,
3109 Evas_Coord x __UNUSED__,
3110 Evas_Coord y __UNUSED__)
3112 Pan *sd = evas_object_smart_data_get(obj);
3116 sd->wd->pan_changed = EINA_TRUE;
3117 evas_object_smart_changed(obj);
3118 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3119 sd->wd->calc_job = NULL;
3123 _hold_on(void *data __UNUSED__,
3125 void *event_info __UNUSED__)
3127 Widget_Data *wd = elm_widget_data_get(obj);
3129 elm_smart_scroller_hold_set(wd->scr, 1);
3133 _hold_off(void *data __UNUSED__,
3135 void *event_info __UNUSED__)
3137 Widget_Data *wd = elm_widget_data_get(obj);
3139 elm_smart_scroller_hold_set(wd->scr, 0);
3143 _freeze_on(void *data __UNUSED__,
3145 void *event_info __UNUSED__)
3147 Widget_Data *wd = elm_widget_data_get(obj);
3149 elm_smart_scroller_freeze_set(wd->scr, 1);
3153 _freeze_off(void *data __UNUSED__,
3155 void *event_info __UNUSED__)
3157 Widget_Data *wd = elm_widget_data_get(obj);
3159 elm_smart_scroller_freeze_set(wd->scr, 0);
3163 _scr_anim_start(void *data,
3164 Evas_Object *obj __UNUSED__,
3165 void *event_info __UNUSED__)
3167 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3171 _scr_anim_stop(void *data,
3172 Evas_Object *obj __UNUSED__,
3173 void *event_info __UNUSED__)
3175 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3179 _scr_drag_start(void *data,
3180 Evas_Object *obj __UNUSED__,
3181 void *event_info __UNUSED__)
3183 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3187 _scr_drag_stop(void *data,
3188 Evas_Object *obj __UNUSED__,
3189 void *event_info __UNUSED__)
3191 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3195 _edge_left(void *data,
3196 Evas_Object *scr __UNUSED__,
3197 void *event_info __UNUSED__)
3199 Evas_Object *obj = data;
3200 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3204 _edge_right(void *data,
3205 Evas_Object *scr __UNUSED__,
3206 void *event_info __UNUSED__)
3208 Evas_Object *obj = data;
3209 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3213 _edge_top(void *data,
3214 Evas_Object *scr __UNUSED__,
3215 void *event_info __UNUSED__)
3217 Evas_Object *obj = data;
3218 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3222 _edge_bottom(void *data,
3223 Evas_Object *scr __UNUSED__,
3224 void *event_info __UNUSED__)
3226 Evas_Object *obj = data;
3227 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3231 _decorate_item_realize(Elm_Gen_Item *it)
3235 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3237 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3238 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3239 edje_object_scale_set(it->item->deco_it_view,
3240 elm_widget_scale_get(WIDGET(it)) *
3241 _elm_config->scale);
3242 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3243 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3245 strncpy(buf, "item", sizeof(buf));
3246 if (it->wd->mode == ELM_LIST_COMPRESS)
3247 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3249 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3250 strncat(buf, "/", sizeof(buf) - strlen(buf));
3251 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3253 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3254 elm_widget_style_get(WIDGET(it)));
3255 edje_object_mirrored_set(it->item->deco_it_view,
3256 elm_widget_mirrored_get(WIDGET(it)));
3258 /* signal callback add */
3259 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3261 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3263 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3266 /* text_get, content_get, state_get */
3267 /* FIXME: If you see that assert, please notify us and we
3268 will clean our mess */
3269 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3271 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3272 if (!it->item->deco_it_contents)
3273 it->item->deco_it_contents =
3274 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3275 it->item->deco_it_content_objs =
3276 _item_mode_content_realize(it, it->item->deco_it_view,
3277 &it->item->deco_it_contents, NULL,
3278 &it->item->deco_it_content_objs);
3279 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3280 edje_object_part_swallow(it->item->deco_it_view,
3281 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3284 it->want_unrealize = EINA_FALSE;
3285 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3286 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3290 _decorate_item_unrealize(Elm_Gen_Item *it)
3292 Widget_Data *wd = it->wd;
3293 Evas_Object *content;
3294 if (!it->item->deco_it_view) return;
3296 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3297 elm_widget_stringlist_free(it->item->deco_it_texts);
3298 it->item->deco_it_texts = NULL;
3299 elm_widget_stringlist_free(it->item->deco_it_contents);
3300 it->item->deco_it_contents = NULL;
3301 elm_widget_stringlist_free(it->item->deco_it_states);
3303 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3304 evas_object_del(content);
3306 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3307 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3308 evas_object_del(it->item->deco_it_view);
3309 it->item->deco_it_view = NULL;
3311 if (wd->mode_item == it)
3312 wd->mode_item = NULL;
3313 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3314 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3318 _decorate_item_set(Elm_Gen_Item *it)
3321 Widget_Data *wd = it->wd;
3326 it->item->nocache_once = EINA_TRUE;
3328 if (wd->scr_hold_timer)
3330 ecore_timer_del(wd->scr_hold_timer);
3331 wd->scr_hold_timer = NULL;
3333 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3334 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3336 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3337 _decorate_item_realize(it);
3338 if (it->item->group_item)
3339 evas_object_raise(it->item->VIEW(group_item));
3340 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3341 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3342 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3344 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3345 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3349 _decorate_item_unset(Widget_Data *wd)
3352 if (!wd->mode_item) return;
3353 char buf[1024], buf2[1024];
3357 it->item->nocache_once = EINA_TRUE;
3359 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3360 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3362 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3363 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3365 wd->mode_item = NULL;
3369 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3371 if ((!it) || (!it->wd->decorate_all_mode)) return;
3372 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3373 evas_object_move(it->deco_all_view, itx, ity);
3377 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3380 const char *stacking_even;
3381 const char *stacking;
3383 if ((!it) || (it->item->decorate_all_item_realized) ||
3384 (it->generation < it->wd->generation))
3387 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3388 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3389 _elm_config->scale);
3390 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3391 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3393 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3394 strncpy(buf, "tree", sizeof(buf));
3395 else strncpy(buf, "item", sizeof(buf));
3396 if (it->wd->mode == ELM_LIST_COMPRESS)
3397 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3399 strncat(buf, "/", sizeof(buf) - strlen(buf));
3400 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3402 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3403 elm_widget_style_get(WIDGET(it)));
3405 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3406 if (!stacking_even) stacking_even = "above";
3407 it->item->stacking_even = !!strcmp("above", stacking_even);
3409 stacking = edje_object_data_get(VIEW(it), "stacking");
3410 if (!stacking) stacking = "yes";
3411 it->item->nostacking = !!strcmp("yes", stacking);
3413 edje_object_mirrored_set(it->deco_all_view,
3414 elm_widget_mirrored_get(WIDGET(it)));
3416 _elm_genlist_item_odd_even_update(it);
3417 _elm_genlist_item_state_update(it, NULL);
3419 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3420 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3422 _item_mouse_callbacks_del(it, VIEW(it));
3423 _item_mouse_callbacks_add(it, it->deco_all_view);
3425 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3426 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3427 if (!it->item->deco_all_contents)
3428 it->item->deco_all_contents =
3429 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "contents"));
3430 it->item->deco_all_content_objs =
3431 _item_mode_content_realize(it, it->deco_all_view,
3432 &it->item->deco_all_contents, NULL,
3433 &it->item->deco_all_content_objs);
3434 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3435 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3437 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3438 evas_object_show(it->deco_all_view);
3440 it->item->decorate_all_item_realized = EINA_TRUE;
3441 it->want_unrealize = EINA_FALSE;
3445 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3448 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3450 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3451 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3452 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3453 _elm_genlist_item_odd_even_update(it);
3454 _elm_genlist_item_state_update(it, NULL);
3456 evas_object_del(it->deco_all_view);
3457 it->deco_all_view = NULL;
3458 elm_widget_stringlist_free(it->item->deco_all_texts);
3459 it->item->deco_all_texts = NULL;
3460 elm_widget_stringlist_free(it->item->deco_all_contents);
3461 it->item->deco_all_contents = NULL;
3462 elm_widget_stringlist_free(it->item->deco_all_states);
3463 it->item->deco_all_states = NULL;
3464 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3465 evas_object_del(icon);
3466 edje_object_message_signal_process(it->deco_all_view);
3467 _item_mouse_callbacks_del(it, it->deco_all_view);
3468 _item_mouse_callbacks_add(it, VIEW(it));
3470 it->item->decorate_all_item_realized = EINA_FALSE;
3474 _item_auto_scroll(Widget_Data *wd)
3477 Elm_Gen_Item *tmp_item = NULL;
3479 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3481 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3482 if (!tmp_item) return;
3483 wd->show_item = tmp_item;
3484 wd->bring_in = EINA_TRUE;
3485 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3486 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3488 wd->show_item->item->showme = EINA_TRUE;
3489 wd->auto_scroll_enabled = EINA_FALSE;
3497 elm_genlist_add(Evas_Object *parent)
3502 Evas_Coord minw, minh;
3503 static Evas_Smart *smart = NULL;
3507 static Evas_Smart_Class sc;
3509 evas_object_smart_clipped_smart_set(&_pan_sc);
3511 sc.name = "elm_genlist_pan";
3512 sc.version = EVAS_SMART_CLASS_VERSION;
3515 sc.resize = _pan_resize;
3516 sc.move = _pan_move;
3517 sc.calculate = _pan_calculate;
3518 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3521 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3523 ELM_SET_WIDTYPE(widtype, "genlist");
3525 elm_widget_type_set(obj, "genlist");
3526 elm_widget_sub_object_add(parent, obj);
3527 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3528 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3529 elm_widget_data_set(obj, wd);
3530 elm_widget_del_hook_set(obj, _del_hook);
3531 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3532 elm_widget_theme_hook_set(obj, _theme_hook);
3533 elm_widget_can_focus_set(obj, EINA_TRUE);
3534 elm_widget_event_hook_set(obj, _event_hook);
3535 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3536 elm_widget_translate_hook_set(obj, _translate_hook);
3539 wd->scr = elm_smart_scroller_add(e);
3540 elm_smart_scroller_widget_set(wd->scr, obj);
3541 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3542 elm_widget_style_get(obj));
3543 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3544 _elm_config->thumbscroll_bounce_enable);
3545 elm_widget_resize_object_set(obj, wd->scr);
3547 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3548 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3549 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3550 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3551 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3552 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3553 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3554 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3557 wd->mode = ELM_LIST_SCROLL;
3558 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3559 wd->item_cache_max = wd->max_items_per_block * 2;
3560 wd->longpress_timeout = _elm_config->longpress_timeout;
3561 wd->highlight = EINA_TRUE;
3563 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3564 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3565 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3566 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3568 wd->pan_smart = evas_object_smart_add(e, smart);
3569 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3572 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3573 _pan_set, _pan_get, _pan_max_get,
3574 _pan_min_get, _pan_child_size_get);
3576 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3578 evas_object_size_hint_min_set(obj, minw, minh);
3580 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3582 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3588 _item_select(Elm_Gen_Item *it)
3590 Evas_Object *obj = WIDGET(it);
3592 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3593 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3594 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3598 it->selected = EINA_TRUE;
3599 it->wd->selected = eina_list_append(it->wd->selected, it);
3601 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3603 evas_object_ref(obj);
3606 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3607 if (it->generation == it->wd->generation)
3608 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3611 if ((it->wd->clear_me) && (!it->wd->walking))
3612 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3615 if ((!it->walking) && (it->generation < it->wd->generation))
3620 elm_widget_item_free(it);
3624 it->wd->last_selected_item = (Elm_Object_Item *)it;
3626 evas_object_unref(obj);
3629 static Evas_Object *
3630 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3632 return edje_object_part_swallow_get(VIEW(it), part);
3636 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
3638 if (!it->itc->func.text_get) return NULL;
3639 return edje_object_part_text_get(VIEW(it), part);
3643 _item_disable_hook(Elm_Object_Item *it)
3647 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3649 if (_it->generation < _it->wd->generation) return;
3652 elm_genlist_item_selected_set(it, EINA_FALSE);
3656 if (elm_widget_item_disabled_get(it))
3658 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
3659 if (_it->deco_all_view)
3660 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
3664 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
3665 if (_it->deco_all_view)
3666 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
3668 EINA_LIST_FOREACH(_it->content_objs, l, obj)
3669 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
3674 _item_del_pre_hook(Elm_Object_Item *it)
3676 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3678 if ((_it->relcount > 0) || (_it->walking > 0))
3680 elm_genlist_item_subitems_clear(it);
3681 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
3682 _elm_genlist_item_del_notserious(_it);
3683 if (_it->item->block)
3685 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
3686 _it->item->block->changed = EINA_TRUE;
3687 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
3688 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
3692 _it->parent->item->items =
3693 eina_list_remove(_it->parent->item->items, it);
3703 _item_signal_emit_hook(Elm_Object_Item *it,
3704 const char *emission,
3707 edje_object_signal_emit(VIEW(it), emission, source);
3711 _elm_genlist_item_new(Widget_Data *wd,
3712 const Elm_Gen_Item_Class *itc,
3714 Elm_Gen_Item *parent,
3716 const void *func_data)
3720 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3721 if (!it) return NULL;
3723 it->generation = wd->generation;
3725 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
3726 it->base.data = data;
3727 it->parent = parent;
3728 it->func.func = func;
3729 it->func.data = func_data;
3730 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3731 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
3732 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3733 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3734 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
3737 it->sel_cb = (Ecore_Cb)_item_select;
3742 static Elm_Gen_Item *
3743 _item_new(Widget_Data *wd,
3744 const Elm_Genlist_Item_Class *itc,
3746 Elm_Gen_Item *parent,
3747 Elm_Genlist_Item_Type type,
3749 const void *func_data)
3751 Elm_Gen_Item *it, *it2;
3754 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3755 if (!it) return NULL;
3756 it->item = ELM_NEW(Elm_Gen_Item_Type);
3757 it->item->type = type;
3758 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
3759 it->item->expanded_depth = 0;
3760 ELM_GEN_ITEM_SETUP(it);
3763 if (it->parent->group)
3764 it->item->group_item = parent;
3765 else if (it->parent->item->group_item)
3766 it->item->group_item = it->parent->item->group_item;
3768 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3770 if (!it2->parent->group) depth += 1;
3772 it->item->expanded_depth = depth;
3778 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3782 itb = calloc(1, sizeof(Item_Block));
3783 if (!itb) return NULL;
3787 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3788 _item_block_position_update(wd->blocks, 0);
3792 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3793 itb->position_update = EINA_TRUE;
3794 if (wd->blocks != EINA_INLIST_GET(itb))
3796 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3807 _item_block_add(Widget_Data *wd,
3810 Item_Block *itb = NULL;
3817 itb = calloc(1, sizeof(Item_Block));
3818 if (!itb) return EINA_FALSE;
3820 if (!it->item->rel->item->block)
3823 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3824 itb->items = eina_list_append(itb->items, it);
3825 itb->position_update = EINA_TRUE;
3826 it->position = eina_list_count(itb->items);
3827 it->position_update = EINA_TRUE;
3829 if (wd->blocks != EINA_INLIST_GET(itb))
3831 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3842 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3843 if (it->item->before)
3845 wd->blocks = eina_inlist_prepend_relative
3846 (wd->blocks, EINA_INLIST_GET(itb),
3847 EINA_INLIST_GET(it->item->rel->item->block));
3849 eina_list_prepend_relative_list(itb->items, it, tmp);
3851 /* Update index from where we prepended */
3852 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3853 _item_block_position_update(EINA_INLIST_GET(itb),
3854 it->item->rel->item->block->position);
3858 wd->blocks = eina_inlist_append_relative
3859 (wd->blocks, EINA_INLIST_GET(itb),
3860 EINA_INLIST_GET(it->item->rel->item->block));
3862 eina_list_append_relative_list(itb->items, it, tmp);
3864 /* Update block index from where we appended */
3865 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3866 _item_block_position_update(EINA_INLIST_GET(itb),
3867 it->item->rel->item->block->position + 1);
3873 if (it->item->before)
3877 itb = (Item_Block *)(wd->blocks);
3878 if (itb->count >= wd->max_items_per_block)
3880 itb = _item_block_new(wd, EINA_TRUE);
3881 if (!itb) return EINA_FALSE;
3886 itb = _item_block_new(wd, EINA_TRUE);
3887 if (!itb) return EINA_FALSE;
3889 itb->items = eina_list_prepend(itb->items, it);
3891 _item_position_update(itb->items, 0);
3897 itb = (Item_Block *)(wd->blocks->last);
3898 if (itb->count >= wd->max_items_per_block)
3900 itb = _item_block_new(wd, EINA_FALSE);
3901 if (!itb) return EINA_FALSE;
3906 itb = _item_block_new(wd, EINA_FALSE);
3907 if (!itb) return EINA_FALSE;
3909 itb->items = eina_list_append(itb->items, it);
3910 it->position = eina_list_count(itb->items);
3918 if (it->item->rel->item->queued)
3920 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3921 on sorted insertion order, so the queue is not always ordered like the item list.
3922 This lead to issue where we depend on an item that is not yet created. As a quick
3923 work around, we reschedule the calc of the item and stop reordering the list to
3924 prevent any nasty issue to show up here.
3926 wd->queue = eina_list_append(wd->queue, it);
3927 wd->requeued = EINA_TRUE;
3928 it->item->queued = EINA_TRUE;
3931 itb = it->item->rel->item->block;
3932 if (!itb) goto newblock;
3933 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3934 if (it->item->before)
3936 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3937 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3941 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3942 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3946 itb->changed = EINA_TRUE;
3947 it->item->block = itb;
3948 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3949 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3952 it->item->rel->relcount--;
3953 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3955 _item_del(it->item->rel);
3956 elm_widget_item_free(it->item->rel);
3958 it->item->rel = NULL;
3960 if (itb->count > itb->wd->max_items_per_block)
3965 Eina_Bool done = EINA_FALSE;
3967 newc = itb->count / 2;
3969 if (EINA_INLIST_GET(itb)->prev)
3971 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3973 if (itbp->count + newc < wd->max_items_per_block / 2)
3975 /* moving items to previous block */
3976 while ((itb->count > newc) && (itb->items))
3978 it2 = eina_list_data_get(itb->items);
3979 itb->items = eina_list_remove_list(itb->items, itb->items);
3982 itbp->items = eina_list_append(itbp->items, it2);
3983 it2->item->block = itbp;
3991 if (!done && EINA_INLIST_GET(itb)->next)
3993 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3995 if (itbn->count + newc < wd->max_items_per_block / 2)
3997 /* moving items to next block */
3998 while ((itb->count > newc) && (itb->items))
4002 l = eina_list_last(itb->items);
4003 it2 = eina_list_data_get(l);
4004 itb->items = eina_list_remove_list(itb->items, l);
4007 itbn->items = eina_list_prepend(itbn->items, it2);
4008 it2->item->block = itbn;
4018 /* moving items to new block */
4019 itb2 = calloc(1, sizeof(Item_Block));
4020 if (!itb2) return EINA_FALSE;
4023 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4024 EINA_INLIST_GET(itb));
4025 itb2->changed = EINA_TRUE;
4026 while ((itb->count > newc) && (itb->items))
4030 l = eina_list_last(itb->items);
4032 itb->items = eina_list_remove_list(itb->items, l);
4035 itb2->items = eina_list_prepend(itb2->items, it2);
4036 it2->item->block = itb2;
4046 _queue_process(Widget_Data *wd)
4049 Eina_Bool showme = EINA_FALSE;
4052 t0 = ecore_loop_time_get();
4053 //evas_event_freeze(evas_object_evas_get(wd->obj));
4054 for (n = 0; (wd->queue) && (n < 128); n++)
4058 it = eina_list_data_get(wd->queue);
4059 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4060 it->item->queued = EINA_FALSE;
4061 if (!_item_block_add(wd, it)) continue;
4063 _item_block_realize(it->item->block);
4064 t = ecore_time_get();
4065 if (it->item->block->changed)
4067 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4068 it->item->block->changed = 0;
4069 if (wd->pan_changed)
4071 if (wd->calc_job) ecore_job_del(wd->calc_job);
4072 wd->calc_job = NULL;
4074 wd->pan_changed = EINA_FALSE;
4077 if (showme) it->item->block->showme = EINA_TRUE;
4078 /* same as eina_inlist_count > 1 */
4079 if (wd->blocks && wd->blocks->next)
4081 if ((t - t0) > (ecore_animator_frametime_get())) break;
4084 //evas_event_thaw(evas_object_evas_get(wd->obj));
4085 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4090 _idle_process(void *data, Eina_Bool *wakeup)
4092 Widget_Data *wd = data;
4095 //static double q_start = 0.0;
4096 //if (q_start == 0.0) q_start = ecore_time_get();
4098 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4102 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4104 return ECORE_CALLBACK_CANCEL;
4106 return ECORE_CALLBACK_RENEW;
4110 _item_idle_enterer(void *data)
4112 Widget_Data *wd = data;
4113 Eina_Bool wakeup = EINA_FALSE;
4114 Eina_Bool ok = _idle_process(data, &wakeup);
4119 if (wd->calc_job) ecore_job_del(wd->calc_job);
4120 wd->calc_job = ecore_job_add(_calc_job, wd);
4122 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4127 _item_queue(Widget_Data *wd,
4131 if (it->item->queued) return;
4132 it->item->queued = EINA_TRUE;
4133 if (cb && !wd->requeued)
4134 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4136 wd->queue = eina_list_append(wd->queue, it);
4137 // FIXME: why does a freeze then thaw here cause some genlist
4138 // elm_genlist_item_append() to be much much slower?
4139 // evas_event_freeze(evas_object_evas_get(wd->obj));
4140 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4142 if (wd->queue_idle_enterer)
4144 ecore_idle_enterer_del(wd->queue_idle_enterer);
4145 wd->queue_idle_enterer = NULL;
4149 // evas_event_thaw(evas_object_evas_get(wd->obj));
4150 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4151 if (!wd->queue_idle_enterer)
4152 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4156 _elm_genlist_item_compare(const void *data, const void *data1)
4158 const Elm_Gen_Item *it, *item1;
4159 it = ELM_GEN_ITEM_FROM_INLIST(data);
4160 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4161 return it->wd->item_compare_cb(it, item1);
4165 _elm_genlist_item_list_compare(const void *data, const void *data1)
4167 const Elm_Gen_Item *it = data;
4168 const Elm_Gen_Item *item1 = data1;
4169 return it->wd->item_compare_cb(it, item1);
4172 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4174 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4179 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4180 _item_block_del(it);
4182 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4183 it->item->rel = after;
4184 it->item->rel->relcount++;
4185 it->item->before = EINA_FALSE;
4186 if (after->item->group_item) it->item->group_item = after->item->group_item;
4187 _item_queue(it->wd, it, NULL);
4189 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4192 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4194 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4197 if (!before) return;
4199 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4200 _item_block_del(it);
4201 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4202 it->item->rel = before;
4203 it->item->rel->relcount++;
4204 it->item->before = EINA_TRUE;
4205 if (before->item->group_item) it->item->group_item = before->item->group_item;
4206 _item_queue(it->wd, it, NULL);
4208 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4212 elm_genlist_items_count(const Evas_Object *obj)
4214 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4215 Widget_Data *wd = elm_widget_data_get(obj);
4217 return wd->item_count;
4220 EAPI Elm_Object_Item *
4221 elm_genlist_item_append(Evas_Object *obj,
4222 const Elm_Genlist_Item_Class *itc,
4224 Elm_Object_Item *parent,
4225 Elm_Genlist_Item_Type type,
4227 const void *func_data)
4229 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4230 Widget_Data *wd = elm_widget_data_get(obj);
4231 if (!wd) return NULL;
4232 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4234 if (!it) return NULL;
4238 wd->group_items = eina_list_append(wd->group_items, it);
4239 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4240 it->item->rel = NULL;
4244 Elm_Gen_Item *it2 = NULL;
4245 Eina_List *ll = eina_list_last(it->parent->item->items);
4246 if (ll) it2 = ll->data;
4247 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4248 if (!it2) it2 = it->parent;
4250 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4251 EINA_INLIST_GET(it2));
4252 it->item->rel = it2;
4253 it->item->rel->relcount++;
4255 it->item->before = EINA_FALSE;
4256 _item_queue(wd, it, NULL);
4257 return (Elm_Object_Item *)it;
4260 EAPI Elm_Object_Item *
4261 elm_genlist_item_prepend(Evas_Object *obj,
4262 const Elm_Genlist_Item_Class *itc,
4264 Elm_Object_Item *parent,
4265 Elm_Genlist_Item_Type type,
4267 const void *func_data)
4269 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4270 Widget_Data *wd = elm_widget_data_get(obj);
4271 if (!wd) return NULL;
4272 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4274 if (!it) return NULL;
4278 wd->group_items = eina_list_prepend(wd->group_items, it);
4279 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4280 it->item->rel = NULL;
4284 Elm_Gen_Item *it2 = NULL;
4285 Eina_List *ll = it->parent->item->items;
4286 if (ll) it2 = ll->data;
4287 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4288 if (!it2) it2 = it->parent;
4290 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4291 EINA_INLIST_GET(it2));
4292 it->item->rel = it2;
4293 it->item->rel->relcount++;
4295 it->item->before = EINA_TRUE;
4296 _item_queue(wd, it, NULL);
4297 return (Elm_Object_Item *)it;
4300 EAPI Elm_Object_Item *
4301 elm_genlist_item_insert_after(Evas_Object *obj,
4302 const Elm_Genlist_Item_Class *itc,
4304 Elm_Object_Item *parent,
4305 Elm_Object_Item *after,
4306 Elm_Genlist_Item_Type type,
4308 const void *func_data)
4310 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4311 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4312 Widget_Data *wd = elm_widget_data_get(obj);
4313 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4314 if (!wd) return NULL;
4315 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4316 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4318 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4320 if (!it) return NULL;
4323 if ((it->group) && (_after->group))
4324 wd->group_items = eina_list_append_relative(wd->group_items, it,
4329 it->parent->item->items =
4330 eina_list_append_relative(it->parent->item->items, it, _after);
4332 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4333 EINA_INLIST_GET(_after));
4334 it->item->rel = _after;
4335 it->item->rel->relcount++;
4336 it->item->before = EINA_FALSE;
4337 _item_queue(wd, it, NULL);
4338 return (Elm_Object_Item *)it;
4341 EAPI Elm_Object_Item *
4342 elm_genlist_item_insert_before(Evas_Object *obj,
4343 const Elm_Genlist_Item_Class *itc,
4345 Elm_Object_Item *parent,
4346 Elm_Object_Item *before,
4347 Elm_Genlist_Item_Type type,
4349 const void *func_data)
4351 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4352 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4353 Widget_Data *wd = elm_widget_data_get(obj);
4354 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4355 if (!wd) return NULL;
4356 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4357 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4359 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4361 if (!it) return NULL;
4364 if (it->group && _before->group)
4365 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4370 it->parent->item->items =
4371 eina_list_prepend_relative(it->parent->item->items, it, _before);
4373 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4374 EINA_INLIST_GET(_before));
4375 it->item->rel = _before;
4376 it->item->rel->relcount++;
4377 it->item->before = EINA_TRUE;
4378 _item_queue(wd, it, NULL);
4379 return (Elm_Object_Item *)it;
4382 EAPI Elm_Object_Item *
4383 elm_genlist_item_sorted_insert(Evas_Object *obj,
4384 const Elm_Genlist_Item_Class *itc,
4386 Elm_Object_Item *parent,
4387 Elm_Genlist_Item_Type type,
4388 Eina_Compare_Cb comp,
4390 const void *func_data)
4392 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4393 Widget_Data *wd = elm_widget_data_get(obj);
4394 if (!wd) return NULL;
4395 Elm_Gen_Item *rel = NULL;
4396 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4398 if (!it) return NULL;
4400 wd->item_compare_cb = comp;
4407 l = eina_list_search_sorted_near_list(it->parent->item->items,
4408 _elm_genlist_item_list_compare,
4412 rel = eina_list_data_get(l);
4416 if (cmp_result >= 0)
4418 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4419 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4420 it->item->before = EINA_FALSE;
4422 else if (cmp_result < 0)
4424 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4425 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4426 it->item->before = EINA_TRUE;
4433 wd->state = eina_inlist_sorted_state_new();
4434 eina_inlist_sorted_state_init(wd->state, wd->items);
4435 wd->requeued = EINA_FALSE;
4439 wd->group_items = eina_list_append(wd->group_items, it);
4441 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4442 _elm_genlist_item_compare, wd->state);
4444 if (EINA_INLIST_GET(it)->next)
4446 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4447 it->item->before = EINA_TRUE;
4449 else if (EINA_INLIST_GET(it)->prev)
4451 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4452 it->item->before = EINA_FALSE;
4458 it->item->rel = rel;
4459 it->item->rel->relcount++;
4462 _item_queue(wd, it, _elm_genlist_item_list_compare);
4464 return (Elm_Object_Item *)it;
4468 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4470 Eina_Inlist *next, *l;
4471 Widget_Data *wd = elm_widget_data_get(obj);
4474 if (!standby) wd->generation++;
4478 eina_inlist_sorted_state_free(wd->state);
4482 if (wd->walking > 0)
4484 wd->clear_me = EINA_TRUE;
4487 evas_event_freeze(evas_object_evas_get(wd->obj));
4488 for (l = wd->items, next = l ? l->next : NULL;
4490 l = next, next = next ? next->next : NULL)
4492 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4494 if (it->generation < wd->generation)
4496 Elm_Gen_Item *itn = NULL;
4498 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4499 if (itn) itn->walking++; /* prevent early death of subitem */
4501 elm_widget_item_free(it);
4502 if (itn) itn->walking--;
4505 wd->clear_me = EINA_FALSE;
4506 wd->pan_changed = EINA_TRUE;
4509 ecore_job_del(wd->calc_job);
4510 wd->calc_job = NULL;
4512 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4513 if (wd->clear_cb) wd->clear_cb(wd);
4519 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4520 wd->alpha_bg = NULL;
4524 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4525 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4527 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4528 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4529 evas_event_thaw(evas_object_evas_get(wd->obj));
4530 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4534 elm_genlist_clear(Evas_Object *obj)
4536 ELM_CHECK_WIDTYPE(obj, widtype);
4537 _elm_genlist_clear(obj, EINA_FALSE);
4541 elm_genlist_multi_select_set(Evas_Object *obj,
4544 ELM_CHECK_WIDTYPE(obj, widtype);
4545 Widget_Data *wd = elm_widget_data_get(obj);
4547 wd->multi = !!multi;
4551 elm_genlist_multi_select_get(const Evas_Object *obj)
4553 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4554 Widget_Data *wd = elm_widget_data_get(obj);
4555 if (!wd) return EINA_FALSE;
4559 EAPI Elm_Object_Item *
4560 elm_genlist_selected_item_get(const Evas_Object *obj)
4562 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4563 Widget_Data *wd = elm_widget_data_get(obj);
4564 if (!wd) return NULL;
4565 if (wd->selected) return wd->selected->data;
4569 EAPI const Eina_List *
4570 elm_genlist_selected_items_get(const Evas_Object *obj)
4572 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4573 Widget_Data *wd = elm_widget_data_get(obj);
4574 if (!wd) return NULL;
4575 return wd->selected;
4579 elm_genlist_realized_items_get(const Evas_Object *obj)
4581 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4582 Widget_Data *wd = elm_widget_data_get(obj);
4583 Eina_List *list = NULL;
4585 Eina_Bool done = EINA_FALSE;
4586 if (!wd) return NULL;
4587 EINA_INLIST_FOREACH(wd->blocks, itb)
4595 EINA_LIST_FOREACH(itb->items, l, it)
4597 if (it->realized) list = eina_list_append(list, it);
4608 EAPI Elm_Object_Item *
4609 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4614 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4615 Widget_Data *wd = elm_widget_data_get(obj);
4616 Evas_Coord ox, oy, ow, oh;
4619 if (!wd) return NULL;
4620 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4622 EINA_INLIST_FOREACH(wd->blocks, itb)
4627 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4628 oy + itb->y - itb->wd->pan_y,
4629 itb->w, itb->h, x, y, 1, 1))
4631 EINA_LIST_FOREACH(itb->items, l, it)
4633 Evas_Coord itx, ity;
4635 itx = ox + itb->x + it->x - itb->wd->pan_x;
4636 ity = oy + itb->y + it->y - itb->wd->pan_y;
4637 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4641 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4642 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4646 return (Elm_Object_Item *)it;
4648 lasty = ity + it->item->h;
4653 if (y > lasty) *posret = 1;
4659 EAPI Elm_Object_Item *
4660 elm_genlist_first_item_get(const Evas_Object *obj)
4662 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4663 Widget_Data *wd = elm_widget_data_get(obj);
4664 if (!wd) return NULL;
4665 if (!wd->items) return NULL;
4666 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4667 while ((it) && (it->generation < wd->generation))
4668 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4669 return (Elm_Object_Item *)it;
4672 EAPI Elm_Object_Item *
4673 elm_genlist_last_item_get(const Evas_Object *obj)
4675 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4676 Widget_Data *wd = elm_widget_data_get(obj);
4677 if (!wd) return NULL;
4678 if (!wd->items) return NULL;
4679 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4680 while ((it) && (it->generation < wd->generation))
4681 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4682 return (Elm_Object_Item *)it;
4685 EAPI Elm_Object_Item *
4686 elm_genlist_item_next_get(const Elm_Object_Item *it)
4688 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4689 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4692 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
4693 if ((_it) && (_it->generation == _it->wd->generation)) break;
4695 return (Elm_Object_Item *) _it;
4698 EAPI Elm_Object_Item *
4699 elm_genlist_item_prev_get(const Elm_Object_Item *it)
4701 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4702 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4705 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
4706 if ((_it) && (_it->generation == _it->wd->generation)) break;
4708 return (Elm_Object_Item *) _it;
4711 EAPI Elm_Object_Item *
4712 elm_genlist_item_parent_get(const Elm_Object_Item *it)
4714 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4715 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
4719 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
4721 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4722 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
4724 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4726 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
4727 _item_subitems_clear(_it);
4730 if (!wd->tree_effect_animator)
4732 wd->expanded_item = _it;
4733 _item_tree_effect_before(_it);
4734 evas_object_raise(wd->alpha_bg);
4735 evas_object_show(wd->alpha_bg);
4736 wd->start_time = ecore_time_get();
4737 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
4740 _item_subitems_clear(_it);
4745 elm_genlist_item_selected_set(Elm_Object_Item *it,
4748 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4749 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4750 Widget_Data *wd = _it->wd;
4752 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
4754 selected = !!selected;
4755 if (_it->selected == selected) return;
4761 while (wd->selected)
4763 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
4764 _it->unsel_cb(wd->selected->data);
4767 _it->highlight_cb(_it);
4771 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
4776 elm_genlist_item_selected_get(const Elm_Object_Item *it)
4778 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4779 return ((Elm_Gen_Item *)it)->selected;
4783 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
4786 if (it->item->expanded)
4788 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4792 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4795 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
4796 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4803 _elm_genlist_move_items_set(Elm_Gen_Item *it)
4806 Elm_Gen_Item *it2 = NULL;
4807 Evas_Coord ox, oy, ow, oh, dh = 0;
4809 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
4811 if (it->item->expanded)
4813 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
4814 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
4816 if (it2 == it->wd->expanded_next_item) break;
4817 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
4822 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
4823 it2 = it->wd->expanded_next_item;
4824 while (it2 && (dh < oy + oh))
4827 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
4828 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4834 elm_genlist_item_expanded_set(Elm_Object_Item *it,
4837 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4838 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4839 expanded = !!expanded;
4840 if (_it->item->expanded == expanded) return;
4841 _it->item->expanded = expanded;
4842 _it->wd->expanded_item = _it;
4843 _elm_genlist_move_items_set(_it);
4845 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
4846 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
4848 if (_it->item->expanded)
4850 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
4852 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
4853 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
4854 _it->wd->auto_scroll_enabled = EINA_TRUE;
4858 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
4860 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
4861 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
4862 _it->wd->auto_scroll_enabled = EINA_FALSE;
4867 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
4869 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4870 return ((Elm_Gen_Item *)it)->item->expanded;
4874 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
4876 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
4877 return ((Elm_Gen_Item *)it)->item->expanded_depth;
4881 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
4882 Elm_Genlist_Item_Scrollto_Type type,
4889 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4890 Evas_Coord gith = 0;
4891 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4892 if ((_it->item->queued) || (!_it->item->mincalcd))
4894 _it->wd->show_item = _it;
4895 _it->wd->bring_in = bring_in;
4896 _it->wd->scrollto_type = type;
4897 _it->item->showme = EINA_TRUE;
4900 if (_it->wd->show_item)
4902 _it->wd->show_item->item->showme = EINA_FALSE;
4903 _it->wd->show_item = NULL;
4906 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
4909 case ELM_GENLIST_ITEM_SCROLLTO_IN:
4910 if ((_it->item->group_item) &&
4911 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4912 gith = _it->item->group_item->item->h;
4914 *y = _it->y + _it->item->block->y - gith;
4916 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
4917 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4918 *y = _it->y + _it->item->block->y - gith;
4920 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
4921 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
4927 *x = _it->x + _it->item->block->x;
4928 *w = _it->item->block->w;
4933 elm_genlist_item_promote(Elm_Object_Item *it)
4935 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4936 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4937 if (_it->generation < _it->wd->generation) return;
4938 _item_move_before(_it,
4939 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
4943 elm_genlist_item_demote(Elm_Object_Item *it)
4945 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4946 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4947 if (_it->generation < _it->wd->generation) return;
4948 _item_move_after(_it,
4949 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
4953 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4955 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4956 Evas_Coord x, y, w, h;
4957 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4959 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
4960 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
4964 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4967 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4968 Evas_Coord x, y, w, h;
4969 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4971 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
4972 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
4976 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
4978 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4980 Evas_Object *content;
4981 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
4983 elm_widget_sub_object_del(WIDGET(it), content);
4984 evas_object_smart_member_del(content);
4985 evas_object_hide(content);
4986 if (l) *l = eina_list_append(*l, content);
4991 elm_genlist_item_update(Elm_Object_Item *it)
4993 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4994 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4996 if (!_it->item->block) return;
4997 if (_it->generation < _it->wd->generation) return;
4998 _it->item->mincalcd = EINA_FALSE;
4999 _it->item->updateme = EINA_TRUE;
5000 _it->item->block->updateme = EINA_TRUE;
5001 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5002 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5006 elm_genlist_item_fields_update(Elm_Object_Item *it,
5008 Elm_Genlist_Item_Field_Type itf)
5010 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5011 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5013 if (!_it->item->block) return;
5014 if (_it->generation < _it->wd->generation) return;
5016 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5017 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5018 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5020 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5021 &_it->contents, parts);
5022 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5023 &_it->contents, parts);
5027 _it->item->flip_content_objs =
5028 _item_mode_content_unrealize(_it, VIEW(_it),
5029 &_it->item->flip_contents, parts,
5030 &_it->item->flip_content_objs);
5031 _it->item->flip_content_objs =
5032 _item_mode_content_realize(_it, VIEW(_it),
5033 &_it->item->flip_contents, parts,
5034 &_it->item->flip_content_objs);
5036 if (_it->item->deco_it_view)
5038 _it->item->deco_it_content_objs =
5039 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5040 &_it->item->deco_it_contents, parts,
5041 &_it->item->deco_it_content_objs);
5042 _it->item->deco_it_content_objs =
5043 _item_mode_content_realize(_it, _it->item->deco_it_view,
5044 &_it->item->deco_it_contents, parts,
5045 &_it->item->deco_it_content_objs);
5047 if (_it->wd->decorate_all_mode)
5049 _it->item->deco_all_content_objs =
5050 _item_mode_content_unrealize(_it, _it->deco_all_view,
5051 &_it->item->deco_all_contents, parts,
5052 &_it->item->deco_all_content_objs);
5053 _it->item->deco_all_content_objs =
5054 _item_mode_content_realize(_it, _it->deco_all_view,
5055 &_it->item->deco_all_contents, parts,
5056 &_it->item->deco_all_content_objs);
5059 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5060 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5064 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5065 const Elm_Genlist_Item_Class *itc)
5067 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5068 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5070 if (!_it->item->block) return;
5071 EINA_SAFETY_ON_NULL_RETURN(itc);
5072 if (_it->generation < _it->wd->generation) return;
5074 _it->item->nocache_once = EINA_TRUE;
5076 elm_widget_stringlist_free(_it->texts);
5078 elm_widget_stringlist_free(_it->contents);
5079 _it->contents = NULL;
5080 elm_widget_stringlist_free(_it->states);
5085 elm_widget_stringlist_free(_it->item->flip_contents);
5086 _it->item->flip_contents = NULL;
5088 if (_it->item->deco_it_view)
5090 elm_widget_stringlist_free(_it->item->deco_it_texts);
5091 _it->item->deco_it_texts = NULL;
5092 elm_widget_stringlist_free(_it->item->deco_it_contents);
5093 _it->item->deco_it_contents = NULL;
5095 if (_it->wd->decorate_all_mode)
5097 elm_widget_stringlist_free(_it->item->deco_all_texts);
5098 _it->item->deco_all_texts = NULL;
5099 elm_widget_stringlist_free(_it->item->deco_all_contents);
5100 _it->item->deco_all_contents = NULL;
5103 elm_genlist_item_update(it);
5106 EAPI const Elm_Genlist_Item_Class *
5107 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5109 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5110 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5111 if (_it->generation < _it->wd->generation) return NULL;
5115 static Evas_Object *
5116 _elm_genlist_item_label_create(void *data,
5117 Evas_Object *obj __UNUSED__,
5118 Evas_Object *tooltip,
5119 void *it __UNUSED__)
5121 Evas_Object *label = elm_label_add(tooltip);
5124 elm_object_style_set(label, "tooltip");
5125 elm_object_text_set(label, data);
5130 _elm_genlist_item_label_del_cb(void *data,
5131 Evas_Object *obj __UNUSED__,
5132 void *event_info __UNUSED__)
5134 eina_stringshare_del(data);
5138 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5141 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5142 text = eina_stringshare_add(text);
5143 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5145 _elm_genlist_item_label_del_cb);
5149 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5150 Elm_Tooltip_Item_Content_Cb func,
5152 Evas_Smart_Cb del_cb)
5154 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5155 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5157 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5160 if (_it->tooltip.del_cb)
5161 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5163 _it->tooltip.content_cb = func;
5164 _it->tooltip.data = data;
5165 _it->tooltip.del_cb = del_cb;
5169 elm_widget_item_tooltip_content_cb_set(_it,
5170 _it->tooltip.content_cb,
5171 _it->tooltip.data, NULL);
5172 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5173 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5179 if (del_cb) del_cb((void *)data, NULL, NULL);
5183 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5185 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5186 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5188 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5189 elm_widget_item_tooltip_unset(_it);
5191 if (_it->tooltip.del_cb)
5192 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5193 _it->tooltip.del_cb = NULL;
5194 _it->tooltip.content_cb = NULL;
5195 _it->tooltip.data = NULL;
5196 _it->tooltip.free_size = EINA_FALSE;
5197 if (_it->tooltip.style)
5198 elm_genlist_item_tooltip_style_set(it, NULL);
5202 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5205 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5206 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5208 eina_stringshare_replace(&_it->tooltip.style, style);
5209 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5213 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5215 return elm_object_item_tooltip_style_get(it);
5219 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5222 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5223 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5225 _it->tooltip.free_size = disable;
5226 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5231 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5233 return elm_object_tooltip_window_mode_get(VIEW(it));
5237 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5240 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5241 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5242 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5243 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5247 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5249 return elm_widget_item_cursor_get(it);
5253 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5255 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5256 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5258 if (!_it->mouse_cursor) return;
5260 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5262 eina_stringshare_del(_it->mouse_cursor);
5263 _it->mouse_cursor = NULL;
5267 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5270 elm_widget_item_cursor_style_set(it, style);
5274 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5276 return elm_widget_item_cursor_style_get(it);
5280 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5281 Eina_Bool engine_only)
5283 elm_widget_item_cursor_engine_only_set(it, engine_only);
5287 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5289 return elm_widget_item_cursor_engine_only_get(it);
5293 elm_genlist_item_index_get(const Elm_Object_Item *it)
5295 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5296 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5298 if (_it->item->block)
5299 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5304 elm_genlist_mode_set(Evas_Object *obj,
5307 ELM_CHECK_WIDTYPE(obj, widtype);
5308 Widget_Data *wd = elm_widget_data_get(obj);
5310 if (wd->mode == mode) return;
5312 if (wd->mode == ELM_LIST_COMPRESS)
5313 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5319 elm_genlist_mode_get(const Evas_Object *obj)
5321 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5322 Widget_Data *wd = elm_widget_data_get(obj);
5323 if (!wd) return ELM_LIST_LAST;
5328 elm_genlist_bounce_set(Evas_Object *obj,
5332 ELM_CHECK_WIDTYPE(obj, widtype);
5333 Widget_Data *wd = elm_widget_data_get(obj);
5335 wd->h_bounce = !!h_bounce;
5336 wd->v_bounce = !!v_bounce;
5337 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5341 elm_genlist_bounce_get(const Evas_Object *obj,
5342 Eina_Bool *h_bounce,
5343 Eina_Bool *v_bounce)
5345 ELM_CHECK_WIDTYPE(obj, widtype);
5346 Widget_Data *wd = elm_widget_data_get(obj);
5348 if (h_bounce) *h_bounce = wd->h_bounce;
5349 if (v_bounce) *v_bounce = wd->v_bounce;
5353 elm_genlist_homogeneous_set(Evas_Object *obj,
5354 Eina_Bool homogeneous)
5356 ELM_CHECK_WIDTYPE(obj, widtype);
5357 Widget_Data *wd = elm_widget_data_get(obj);
5359 wd->homogeneous = !!homogeneous;
5363 elm_genlist_homogeneous_get(const Evas_Object *obj)
5365 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5366 Widget_Data *wd = elm_widget_data_get(obj);
5367 if (!wd) return EINA_FALSE;
5368 return wd->homogeneous;
5372 elm_genlist_block_count_set(Evas_Object *obj,
5375 ELM_CHECK_WIDTYPE(obj, widtype);
5376 Widget_Data *wd = elm_widget_data_get(obj);
5378 wd->max_items_per_block = count;
5379 wd->item_cache_max = wd->max_items_per_block * 2;
5380 _item_cache_clean(wd);
5384 elm_genlist_block_count_get(const Evas_Object *obj)
5386 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5387 Widget_Data *wd = elm_widget_data_get(obj);
5389 return wd->max_items_per_block;
5393 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5396 ELM_CHECK_WIDTYPE(obj, widtype);
5397 Widget_Data *wd = elm_widget_data_get(obj);
5399 wd->longpress_timeout = timeout;
5403 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5405 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5406 Widget_Data *wd = elm_widget_data_get(obj);
5408 return wd->longpress_timeout;
5412 elm_genlist_scroller_policy_set(Evas_Object *obj,
5413 Elm_Scroller_Policy policy_h,
5414 Elm_Scroller_Policy policy_v)
5416 ELM_CHECK_WIDTYPE(obj, widtype);
5417 Widget_Data *wd = elm_widget_data_get(obj);
5418 if ((!wd) || (!wd->scr)) return;
5419 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5420 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5422 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5426 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5427 Elm_Scroller_Policy *policy_h,
5428 Elm_Scroller_Policy *policy_v)
5430 ELM_CHECK_WIDTYPE(obj, widtype);
5431 Widget_Data *wd = elm_widget_data_get(obj);
5432 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5433 if ((!wd) || (!wd->scr)) return;
5434 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5435 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5436 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5440 elm_genlist_realized_items_update(Evas_Object *obj)
5442 ELM_CHECK_WIDTYPE(obj, widtype);
5444 Eina_List *list, *l;
5445 Elm_Object_Item *it;
5447 list = elm_genlist_realized_items_get(obj);
5448 EINA_LIST_FOREACH(list, l, it)
5449 elm_genlist_item_update(it);
5453 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5454 const char *decorate_it_type,
5455 Eina_Bool decorate_it_set)
5457 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5458 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5460 Widget_Data *wd = _it->wd;
5462 Elm_Object_Item *it2;
5465 if (!decorate_it_type) return;
5466 if ((_it->generation < _it->wd->generation) ||
5467 elm_widget_item_disabled_get(_it)) return;
5468 if (wd->decorate_all_mode) return;
5470 if ((wd->mode_item == _it) &&
5471 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5474 if (!_it->itc->decorate_item_style) return;
5475 _it->decorate_it_set = decorate_it_set;
5479 EINA_LIST_FOREACH(wd->selected, l, it2)
5480 if (((Elm_Gen_Item *)it2)->realized)
5481 elm_genlist_item_selected_set(it2, EINA_FALSE);
5485 it2 = elm_genlist_selected_item_get(wd->obj);
5486 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5487 elm_genlist_item_selected_set(it2, EINA_FALSE);
5490 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5491 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5492 _decorate_item_unset(wd);
5494 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5495 if (decorate_it_set) _decorate_item_set(_it);
5499 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5501 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5502 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5503 return _it->wd->decorate_it_type;
5506 EAPI const Elm_Object_Item *
5507 elm_genlist_decorated_item_get(const Evas_Object *obj)
5509 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5510 Widget_Data *wd = elm_widget_data_get(obj);
5511 if (!wd) return NULL;
5512 return (Elm_Object_Item *) wd->mode_item;
5516 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5518 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5519 Widget_Data *wd = elm_widget_data_get(obj);
5520 if (!wd) return EINA_FALSE;
5522 return wd->decorate_all_mode;
5526 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5528 ELM_CHECK_WIDTYPE(obj, widtype);
5529 Eina_List *list, *l;
5532 Widget_Data *wd = elm_widget_data_get(obj);
5534 decorated = !!decorated;
5535 if (wd->decorate_all_mode == decorated) return;
5536 wd->decorate_all_mode = decorated;
5538 list = elm_genlist_realized_items_get(obj);
5539 if (!wd->decorate_all_mode)
5541 EINA_LIST_FOREACH(list, l, it)
5543 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5544 _decorate_all_item_unrealize(it);
5546 _item_cache_zero(wd);
5550 EINA_LIST_FOREACH(list, l, it)
5552 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5554 if (it->selected) _item_unselect(it);
5555 if (it->itc->decorate_all_item_style)
5556 _decorate_all_item_realize(it, EINA_TRUE);
5560 if (wd->calc_job) ecore_job_del(wd->calc_job);
5561 wd->calc_job = ecore_job_add(_calc_job, wd);
5565 elm_genlist_reorder_mode_set(Evas_Object *obj,
5566 Eina_Bool reorder_mode)
5568 ELM_CHECK_WIDTYPE(obj, widtype);
5569 Widget_Data *wd = elm_widget_data_get(obj);
5571 wd->reorder_mode = !!reorder_mode;
5575 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5577 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5578 Widget_Data *wd = elm_widget_data_get(obj);
5579 if (!wd) return EINA_FALSE;
5580 return wd->reorder_mode;
5583 EAPI Elm_Genlist_Item_Type
5584 elm_genlist_item_type_get(const Elm_Object_Item *it)
5586 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5587 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5588 return _it->item->type;
5591 EAPI Elm_Genlist_Item_Class *
5592 elm_genlist_item_class_new(void)
5594 Elm_Genlist_Item_Class *itc;
5596 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5599 itc->version = CLASS_ALLOCATED;
5601 itc->delete_me = EINA_FALSE;
5607 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5609 if (itc && (itc->version == CLASS_ALLOCATED))
5611 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5612 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5622 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5624 if (itc && (itc->version == CLASS_ALLOCATED))
5627 if (itc->refcount == 0) itc->refcount--;
5632 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5634 if (itc && (itc->version == CLASS_ALLOCATED))
5636 if (itc->refcount > 0) itc->refcount--;
5637 if (itc->delete_me && (!itc->refcount))
5638 elm_genlist_item_class_free(itc);
5642 void _flip_job(void *data)
5644 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
5645 _elm_genlist_item_unrealize(it, EINA_FALSE);
5646 if (it->selected) _item_unselect(it);
5647 it->flipped = EINA_TRUE;
5648 it->item->nocache = EINA_TRUE;
5652 elm_genlist_item_flip_set(Elm_Object_Item *it,
5655 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5656 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5659 if (_it->flipped == flip) return;
5663 ecore_job_add(_flip_job, _it);
5664 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
5665 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
5669 _it->flipped = flip;
5670 _item_cache_zero(_it->wd);
5671 elm_genlist_item_update(it);
5672 _it->item->nocache = EINA_FALSE;
5677 elm_genlist_item_flip_get(const Elm_Object_Item *it)
5679 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5680 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5681 return _it->flipped;
5685 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
5687 ELM_CHECK_WIDTYPE(obj, widtype);
5688 Widget_Data *wd = elm_widget_data_get(obj);
5690 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5692 if (wd->select_mode != mode)
5693 wd->select_mode = mode;
5696 EAPI Elm_Object_Select_Mode
5697 elm_genlist_select_mode_get(const Evas_Object *obj)
5699 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
5700 Widget_Data *wd = elm_widget_data_get(obj);
5701 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
5702 return wd->select_mode;
5706 elm_genlist_highlight_mode_set(Evas_Object *obj,
5707 Eina_Bool highlight)
5709 ELM_CHECK_WIDTYPE(obj, widtype);
5710 Widget_Data *wd = elm_widget_data_get(obj);
5712 wd->highlight = !!highlight;
5716 elm_genlist_highlight_mode_get(const Evas_Object *obj)
5718 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5719 Widget_Data *wd = elm_widget_data_get(obj);
5720 if (!wd) return EINA_FALSE;
5721 return wd->highlight;
5725 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
5726 Elm_Object_Select_Mode mode)
5728 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5729 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5731 if (_it->generation < _it->wd->generation) return;
5732 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5734 if (_it->select_mode != mode)
5735 _it->select_mode = mode;
5737 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5739 _it->item->mincalcd = EINA_FALSE;
5740 _it->item->updateme = EINA_TRUE;
5741 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
5742 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5743 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5747 EAPI Elm_Object_Select_Mode
5748 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
5750 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
5751 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5752 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
5753 return _it->select_mode;
5756 /* for gengrid as of now */
5758 _elm_genlist_page_relative_set(Evas_Object *obj,
5762 Evas_Coord pagesize_h;
5763 Evas_Coord pagesize_v;
5765 ELM_CHECK_WIDTYPE(obj, widtype);
5766 Widget_Data *wd = elm_widget_data_get(obj);
5769 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5770 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5774 /* for gengrid as of now */
5776 _elm_genlist_page_relative_get(const Evas_Object *obj,
5780 ELM_CHECK_WIDTYPE(obj, widtype);
5781 Widget_Data *wd = elm_widget_data_get(obj);
5784 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5787 /* for gengrid as of now */
5789 _elm_genlist_page_size_set(Evas_Object *obj,
5790 Evas_Coord h_pagesize,
5791 Evas_Coord v_pagesize)
5796 ELM_CHECK_WIDTYPE(obj, widtype);
5797 Widget_Data *wd = elm_widget_data_get(obj);
5799 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5800 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5804 /* for gengrid as of now */
5806 _elm_genlist_current_page_get(const Evas_Object *obj,
5810 ELM_CHECK_WIDTYPE(obj, widtype);
5811 Widget_Data *wd = elm_widget_data_get(obj);
5813 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5816 /* for gengrid as of now */
5818 _elm_genlist_last_page_get(const Evas_Object *obj,
5822 ELM_CHECK_WIDTYPE(obj, widtype);
5823 Widget_Data *wd = elm_widget_data_get(obj);
5825 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5828 /* for gengrid as of now */
5830 _elm_genlist_page_show(const Evas_Object *obj,
5834 ELM_CHECK_WIDTYPE(obj, widtype);
5835 Widget_Data *wd = elm_widget_data_get(obj);
5837 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5840 /* for gengrid as of now */
5842 _elm_genlist_page_bring_in(const Evas_Object *obj,
5846 ELM_CHECK_WIDTYPE(obj, widtype);
5847 Widget_Data *wd = elm_widget_data_get(obj);
5849 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5853 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5856 Evas_Object *content;
5858 if (!it->realized) return;
5859 if (it->wd->reorder_it == it) return;
5861 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5863 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5866 ecore_timer_del(it->long_timer);
5867 it->long_timer = NULL;
5870 elm_widget_stringlist_free(it->texts);
5872 elm_widget_stringlist_free(it->contents);
5873 it->contents = NULL;
5874 elm_widget_stringlist_free(it->states);
5876 EINA_LIST_FREE(it->content_objs, content)
5877 evas_object_del(content);
5881 elm_widget_stringlist_free(it->item->flip_contents);
5882 it->item->flip_contents = NULL;
5883 EINA_LIST_FREE(it->item->flip_content_objs, content)
5884 evas_object_del(content);
5887 it->unrealize_cb(it);
5889 it->realized = EINA_FALSE;
5890 it->want_unrealize = EINA_FALSE;
5891 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5892 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5896 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5898 elm_widget_item_pre_notify_del(it);
5899 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5900 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5902 if (it->itc->func.del)
5903 it->itc->func.del((void *)it->base.data, WIDGET(it));
5907 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5909 _elm_genlist_item_del_notserious(it);
5910 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5911 if (it->tooltip.del_cb)
5912 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5913 it->wd->walking -= it->walking;
5916 ecore_timer_del(it->long_timer);
5917 it->long_timer = NULL;
5920 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5924 eina_inlist_sorted_state_free(it->wd->state);
5925 it->wd->state = NULL;
5927 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5928 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5932 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
5933 it->wd->last_selected_item = NULL;
5934 it->wd->item_count--;
5938 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
5940 ELM_CHECK_WIDTYPE(obj, widtype);
5941 Widget_Data *wd = elm_widget_data_get(obj);
5943 wd->tree_effect_enabled = !!enabled;
5947 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
5949 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5950 Widget_Data *wd = elm_widget_data_get(obj);
5951 if (!wd) return EINA_FALSE;
5952 return wd->tree_effect_enabled;
5956 _create_tray_alpha_bg(const Evas_Object *obj)
5958 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5959 Widget_Data *wd = elm_widget_data_get(obj);
5960 if (!wd) return NULL;
5962 Evas_Object *bg = NULL;
5963 Evas_Coord ox, oy, ow, oh;
5965 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5966 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
5967 evas_object_color_set(bg,0,0,0,0);
5968 evas_object_resize(bg , ow, oh);
5969 evas_object_move(bg , ox, oy);
5974 _item_contract_emit(Elm_Gen_Item *it)
5979 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
5980 it->item->tree_effect_finished = EINA_FALSE;
5982 EINA_LIST_FOREACH(it->item->items, l, it2)
5983 if (it2) _item_contract_emit(it2);
5987 _item_tree_effect_before(Elm_Gen_Item *it)
5992 EINA_LIST_FOREACH(it->item->items, l, it2)
5994 if (it2->parent && (it == it2->parent))
5997 it2->item->tree_effect_hideme = EINA_TRUE;
5998 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
5999 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6000 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6001 _item_contract_emit(it2);
6004 return ECORE_CALLBACK_CANCEL;
6008 _item_tree_effect(Widget_Data *wd, int y)
6010 Elm_Gen_Item *it = NULL, *expanded_next_it;
6012 expanded_next_it = wd->expanded_next_item;
6014 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6016 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6019 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6020 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6021 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6023 if (!it->item->tree_effect_finished)
6025 edje_object_signal_emit(VIEW(it), "flip_item", "");
6026 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6027 it->item->tree_effect_finished = EINA_TRUE;
6030 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6033 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6035 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6038 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6039 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6041 if (!it->item->tree_effect_finished)
6043 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6044 it->item->tree_effect_finished = EINA_TRUE;
6049 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6055 _item_tree_effect_finish(Widget_Data *wd)
6057 Elm_Gen_Item *it = NULL;
6060 if (wd->tree_effect_animator)
6062 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6063 _item_subitems_clear(wd->expanded_item);
6064 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6066 it->item->tree_effect_finished = EINA_TRUE;
6067 it->item->old_scrl_y = it->item->scrl_y;
6068 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6069 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6072 _item_auto_scroll(wd);
6073 evas_object_lower(wd->alpha_bg);
6074 evas_object_hide(wd->alpha_bg);
6075 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6076 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6078 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6079 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6080 evas_object_smart_changed(wd->pan_smart);
6082 wd->tree_effect_animator = NULL;
6086 _tree_effect_animator_cb(void *data)
6088 Widget_Data *wd = data;
6089 if (!wd) return EINA_FALSE;
6090 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6091 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6093 double effect_duration = 0.3, t;
6094 int y = 0, dy = 0, dh = 0;
6095 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6098 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6099 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6100 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6101 if (t > effect_duration) end = EINA_TRUE;
6103 // Below while statement is needed, when the genlist is resized.
6104 it2 = wd->expanded_item;
6107 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6108 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6109 cvx, cvy, cvw, cvh));
6110 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6113 if (wd->expanded_next_item)
6115 expanded_next_it = wd->expanded_next_item;
6118 EINA_LIST_FOREACH(wd->move_items, l, it)
6120 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6122 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6123 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6124 expanded_next_it->item->scrl_y = cvy + cvh;
6126 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6127 cvy + cvh : expanded_next_it->item->scrl_y) -
6128 expanded_next_it->item->old_scrl_y;
6130 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6132 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6133 expanded_next_it->item->old_scrl_y = cvy + cvh;
6135 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6137 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6139 expanded_next_it->item->old_scrl_y = cvy + cvh;
6143 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6144 expanded_next_it->item->old_scrl_y;
6148 if (t <= effect_duration)
6150 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6160 _item_realize(it, in, 0);
6164 if (it != expanded_next_it)
6166 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6170 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6171 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6174 _item_tree_effect(wd, y);
6178 int expanded_item_num = 0;
6181 if (wd->expanded_item)
6182 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6187 expanded_item_num++;
6188 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6194 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6195 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6197 if (!it->item->tree_effect_finished)
6199 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6201 edje_object_signal_emit(VIEW(it), "flip_item", "");
6202 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6203 it->item->tree_effect_finished = EINA_TRUE;
6207 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6213 _item_tree_effect_finish(wd);
6214 return ECORE_CALLBACK_CANCEL;
6216 return ECORE_CALLBACK_RENEW;