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 *mode_texts, *mode_contents, *mode_states, *mode_content_objs;
56 Eina_List *edit_texts, *edit_contents, *edit_states, *edit_content_objs;
57 Ecore_Timer *swipe_timer;
58 Evas_Coord scrl_x, scrl_y, old_scrl_y;
61 Evas_Object *mode_view;
67 Eina_Bool want_realize : 1;
68 Eina_Bool expanded : 1;
69 Eina_Bool mincalcd : 1;
72 Eina_Bool updateme : 1;
73 Eina_Bool nocache : 1; /* do not use cache for this item */
74 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
75 Eina_Bool stacking_even : 1;
76 Eina_Bool nostacking : 1;
77 Eina_Bool move_effect_enabled : 1;
78 Eina_Bool edit_mode_item_realized : 1;
79 Eina_Bool tree_effect_finished : 1; /* tree effect */
90 Evas_Coord x, y, w, h, minw, minh;
92 int item_position_stamp;
94 Eina_Bool position_update : 1;
95 Eina_Bool want_unrealize : 1;
96 Eina_Bool realized : 1;
97 Eina_Bool changed : 1;
98 Eina_Bool updateme : 1;
100 Eina_Bool must_recalc : 1;
107 Evas_Object *base_view, *spacer;
109 const char *item_style; // it->itc->item_style
110 Eina_Bool tree : 1; // it->group
111 Eina_Bool compress : 1; // it->wd->compress
113 Eina_Bool selected : 1; // it->selected
114 Eina_Bool disabled : 1; // it->disabled
115 Eina_Bool expanded : 1; // it->item->expanded
118 static const char *widtype = NULL;
119 static void _item_cache_zero(Widget_Data *wd);
120 static void _del_hook(Evas_Object *obj);
121 static void _mirrored_set(Evas_Object *obj,
123 static void _theme_hook(Evas_Object *obj);
124 static void _show_region_hook(void *data,
126 static void _sizing_eval(Evas_Object *obj);
127 static void _item_realize(Elm_Gen_Item *it,
130 static void _item_unrealize_cb(Elm_Gen_Item *it);
131 static void _item_block_unrealize(Item_Block *itb);
132 static void _calc_job(void *data);
133 static void _on_focus_hook(void *data,
135 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
136 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
137 static Eina_Bool _item_single_select_up(Widget_Data *wd);
138 static Eina_Bool _item_single_select_down(Widget_Data *wd);
139 static Eina_Bool _event_hook(Evas_Object *obj,
141 Evas_Callback_Type type,
143 static void _signal_emit_hook(Evas_Object *obj,
144 const char *emission,
146 static Eina_Bool _deselect_all_items(Widget_Data *wd);
147 static void _pan_calculate(Evas_Object *obj);
148 static void _pan_max_get(Evas_Object *obj,
151 static void _item_position(Elm_Gen_Item *it,
155 static void _mode_item_realize(Elm_Gen_Item *it);
156 static void _mode_item_unrealize(Elm_Gen_Item *it);
157 static void _item_mode_set(Elm_Gen_Item *it);
158 static void _item_mode_unset(Widget_Data *wd);
159 static void _edit_mode_item_position(Elm_Gen_Item *it, int itx, int ity);
160 static void _edit_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
161 static void _edit_mode_item_unrealize(Elm_Gen_Item *it);
162 static void _group_items_recalc(void *data);
163 static void _item_move_after(Elm_Gen_Item *it,
164 Elm_Gen_Item *after);
165 static void _item_move_before(Elm_Gen_Item *it,
166 Elm_Gen_Item *before);
167 static void _item_auto_scroll(Widget_Data *wd);
168 static void _elm_genlist_clear(Evas_Object *obj,
170 static void _pan_child_size_get(Evas_Object *obj,
173 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
174 static void _item_contract_emit(Elm_Gen_Item *it);
175 static int _item_tree_effect_before(Elm_Gen_Item *it);
176 static void _item_tree_effect(Widget_Data *wd, int y);
177 static void _item_tree_effect_finish(Widget_Data *wd);
178 static Eina_Bool _item_moving_effect_timer_cb(void *data);
180 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
182 static const char SIG_ACTIVATED[] = "activated";
183 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
184 static const char SIG_SELECTED[] = "selected";
185 static const char SIG_UNSELECTED[] = "unselected";
186 static const char SIG_EXPANDED[] = "expanded";
187 static const char SIG_CONTRACTED[] = "contracted";
188 static const char SIG_EXPAND_REQUEST[] = "expand,request";
189 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
190 static const char SIG_REALIZED[] = "realized";
191 static const char SIG_UNREALIZED[] = "unrealized";
192 static const char SIG_DRAG_START_UP[] = "drag,start,up";
193 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
194 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
195 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
196 static const char SIG_DRAG_STOP[] = "drag,stop";
197 static const char SIG_DRAG[] = "drag";
198 static const char SIG_LONGPRESSED[] = "longpressed";
199 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
200 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
201 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
202 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
203 static const char SIG_EDGE_TOP[] = "edge,top";
204 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
205 static const char SIG_EDGE_LEFT[] = "edge,left";
206 static const char SIG_EDGE_RIGHT[] = "edge,right";
207 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
208 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
209 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
210 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
211 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
212 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
213 static const char SIG_SWIPE[] = "swipe";
214 static const char SIG_MOVED[] = "moved";
215 static const char SIG_INDEX_UPDATE[] = "index,update";
216 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
218 static const Evas_Smart_Cb_Description _signals[] = {
219 {SIG_CLICKED_DOUBLE, ""},
222 {SIG_UNSELECTED, ""},
224 {SIG_CONTRACTED, ""},
225 {SIG_EXPAND_REQUEST, ""},
226 {SIG_CONTRACT_REQUEST, ""},
228 {SIG_UNREALIZED, ""},
229 {SIG_DRAG_START_UP, ""},
230 {SIG_DRAG_START_DOWN, ""},
231 {SIG_DRAG_START_LEFT, ""},
232 {SIG_DRAG_START_RIGHT, ""},
235 {SIG_LONGPRESSED, ""},
236 {SIG_SCROLL_ANIM_START, ""},
237 {SIG_SCROLL_ANIM_STOP, ""},
238 {SIG_SCROLL_DRAG_START, ""},
239 {SIG_SCROLL_DRAG_STOP, ""},
241 {SIG_EDGE_BOTTOM, ""},
243 {SIG_EDGE_RIGHT, ""},
244 {SIG_MULTI_SWIPE_LEFT, ""},
245 {SIG_MULTI_SWIPE_RIGHT, ""},
246 {SIG_MULTI_SWIPE_UP, ""},
247 {SIG_MULTI_SWIPE_DOWN, ""},
248 {SIG_MULTI_PINCH_OUT, ""},
249 {SIG_MULTI_PINCH_IN, ""},
252 {SIG_TREE_EFFECT_FINISHED, ""},
257 #undef ELM_CHECK_WIDTYPE
258 #define ELM_CHECK_WIDTYPE(obj, widtype) \
259 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
260 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
261 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
262 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
263 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
265 static const char *_gengrid = NULL;
266 static const char *_genlist = NULL;
268 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
270 elm_genlist_type_check(const Evas_Object *obj,
273 const char *provided, *expected = "(unknown)";
274 static int abort_on_warn = -1;
275 provided = elm_widget_type_get(obj);
276 if (!_genlist) _genlist = eina_stringshare_add("genlist");
277 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
278 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
280 if ((!provided) || (!provided[0]))
282 provided = evas_object_type_get(obj);
283 if ((!provided) || (!provided[0]))
284 provided = "(unknown)";
286 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
287 if (abort_on_warn == -1)
289 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
290 else abort_on_warn = 0;
292 if (abort_on_warn == 1) abort();
297 _event_hook(Evas_Object *obj,
298 Evas_Object *src __UNUSED__,
299 Evas_Callback_Type type,
302 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
303 Evas_Event_Key_Down *ev = event_info;
304 Widget_Data *wd = elm_widget_data_get(obj);
305 Evas_Coord pan_max_x = 0, pan_max_y = 0;
306 if (!wd) return EINA_FALSE;
307 if (!wd->items) return EINA_FALSE;
308 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
309 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
311 Elm_Object_Item *it = NULL;
314 Evas_Coord step_x = 0;
315 Evas_Coord step_y = 0;
318 Evas_Coord page_x = 0;
319 Evas_Coord page_y = 0;
321 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
322 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
323 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
324 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
326 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
330 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
334 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
336 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
337 (_item_multi_select_up(wd)))
338 || (_item_single_select_up(wd)))
340 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
346 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
348 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
349 (_item_multi_select_down(wd)))
350 || (_item_single_select_down(wd)))
352 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
358 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
360 it = elm_genlist_first_item_get(obj);
361 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
362 elm_genlist_item_selected_set(it, EINA_TRUE);
363 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
366 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
368 it = elm_genlist_last_item_get(obj);
369 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
370 elm_genlist_item_selected_set(it, EINA_TRUE);
371 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
374 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
377 y -= -(page_y * v_h) / 100;
381 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
384 y += -(page_y * v_h) / 100;
388 else if (!strcmp(ev->keyname, "Escape"))
390 if (!_deselect_all_items(wd)) return EINA_FALSE;
391 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
394 else if (((!strcmp(ev->keyname, "Return")) ||
395 (!strcmp(ev->keyname, "KP_Enter")) ||
396 (!strcmp(ev->keyname, "space")))
397 && (!wd->multi) && (wd->selected))
399 it = elm_genlist_selected_item_get(obj);
400 elm_genlist_item_expanded_set(it,
401 !elm_genlist_item_expanded_get(it));
402 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
404 else return EINA_FALSE;
406 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
407 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
409 if (x > pan_max_x) x = pan_max_x;
411 if (y > pan_max_y) y = pan_max_y;
412 elm_smart_scroller_child_pos_set(wd->scr, x, y);
417 _deselect_all_items(Widget_Data *wd)
419 if (!wd->selected) return EINA_FALSE;
421 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
427 _item_multi_select_up(Widget_Data *wd)
429 if (!wd->selected) return EINA_FALSE;
430 if (!wd->multi) return EINA_FALSE;
432 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
433 if (!prev) return EINA_TRUE;
435 if (elm_genlist_item_selected_get(prev))
437 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
438 wd->last_selected_item = prev;
439 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
443 elm_genlist_item_selected_set(prev, EINA_TRUE);
444 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
450 _item_multi_select_down(Widget_Data *wd)
452 if (!wd->selected) return EINA_FALSE;
453 if (!wd->multi) return EINA_FALSE;
455 Elm_Object_Item *next;
456 next = elm_genlist_item_next_get(wd->last_selected_item);
457 if (!next) return EINA_TRUE;
459 if (elm_genlist_item_selected_get(next))
461 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
462 wd->last_selected_item = next;
463 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
467 elm_genlist_item_selected_set(next, EINA_TRUE);
468 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
474 _item_single_select_up(Widget_Data *wd)
479 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
480 while ((prev) && (prev->generation < wd->generation))
481 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
483 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
485 if (!prev) return EINA_FALSE;
487 _deselect_all_items(wd);
489 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
490 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
495 _item_single_select_down(Widget_Data *wd)
500 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
501 while ((next) && (next->generation < wd->generation))
502 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
504 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
506 if (!next) return EINA_FALSE;
508 _deselect_all_items(wd);
510 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
511 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
516 _on_focus_hook(void *data __UNUSED__,
519 Widget_Data *wd = elm_widget_data_get(obj);
521 if (elm_widget_focus_get(obj))
523 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
524 evas_object_focus_set(wd->obj, EINA_TRUE);
525 if ((wd->selected) && (!wd->last_selected_item))
526 wd->last_selected_item = eina_list_data_get(wd->selected);
530 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
531 evas_object_focus_set(wd->obj, EINA_FALSE);
536 _del_hook(Evas_Object *obj)
538 Widget_Data *wd = elm_widget_data_get(obj);
540 _item_cache_zero(wd);
541 if (wd->calc_job) ecore_job_del(wd->calc_job);
542 if (wd->update_job) ecore_job_del(wd->update_job);
543 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
544 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
545 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
546 if (wd->mode_type) eina_stringshare_del(wd->mode_type);
547 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
552 _del_pre_hook(Evas_Object *obj)
554 Widget_Data *wd = elm_widget_data_get(obj);
556 if (wd->edit_mode) elm_genlist_edit_mode_set(wd->obj, EINA_FALSE);
557 elm_genlist_clear(obj);
558 evas_object_del(wd->pan_smart);
559 wd->pan_smart = NULL;
563 _mirrored_set(Evas_Object *obj,
566 Widget_Data *wd = elm_widget_data_get(obj);
568 _item_cache_zero(wd);
569 elm_smart_scroller_mirrored_set(wd->scr, rtl);
573 _theme_hook(Evas_Object *obj)
575 Widget_Data *wd = elm_widget_data_get(obj);
578 evas_event_freeze(evas_object_evas_get(wd->obj));
579 _item_cache_zero(wd);
580 _elm_widget_mirrored_reload(obj);
581 _mirrored_set(obj, elm_widget_mirrored_get(obj));
582 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
583 elm_widget_style_get(obj));
584 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
585 wd->item_width = wd->item_height = 0;
586 wd->group_item_width = wd->group_item_height = 0;
587 wd->minw = wd->minh = wd->realminw = 0;
588 EINA_INLIST_FOREACH(wd->blocks, itb)
593 if (itb->realized) _item_block_unrealize(itb);
594 EINA_LIST_FOREACH(itb->items, l, it)
595 it->item->mincalcd = EINA_FALSE;
597 itb->changed = EINA_TRUE;
599 if (wd->calc_job) ecore_job_del(wd->calc_job);
600 wd->calc_job = ecore_job_add(_calc_job, wd);
602 evas_event_thaw(evas_object_evas_get(wd->obj));
603 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
607 _show_region_hook(void *data,
610 Widget_Data *wd = elm_widget_data_get(data);
611 Evas_Coord x, y, w, h;
613 elm_widget_show_region_get(obj, &x, &y, &w, &h);
614 //x & y are screen coordinates, Add with pan coordinates
617 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
621 _translate_hook(Evas_Object *obj)
623 evas_object_smart_callback_call(obj, "language,changed", NULL);
627 _sizing_eval(Evas_Object *obj)
629 Widget_Data *wd = elm_widget_data_get(obj);
630 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
632 evas_object_size_hint_min_get(wd->scr, &minw, &minh);
633 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
635 if (wd->height_for_width)
639 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
640 if ((vw != 0) && (vw != wd->prev_viewport_w))
644 wd->prev_viewport_w = vw;
645 EINA_INLIST_FOREACH(wd->blocks, itb)
647 itb->must_recalc = EINA_TRUE;
649 if (wd->calc_job) ecore_job_del(wd->calc_job);
650 wd->calc_job = ecore_job_add(_calc_job, wd);
653 if (wd->mode == ELM_LIST_LIMIT)
659 elm_smart_scroller_child_viewport_size_get(wd->scr, &vmw, &vmh);
660 edje_object_size_min_calc
661 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
668 edje_object_size_min_calc
669 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
673 evas_object_size_hint_min_set(obj, minw, minh);
674 evas_object_size_hint_max_set(obj, maxw, maxh);
678 _signal_emit_hook(Evas_Object *obj,
679 const char *emission,
682 Widget_Data *wd = elm_widget_data_get(obj);
683 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
688 _item_highlight(Elm_Gen_Item *it)
690 const char *selectraise;
691 if ((it->wd->no_select) || (it->generation < it->wd->generation) ||
692 (it->highlighted) || elm_widget_item_disabled_get(it) ||
693 (it->display_only) || (it->item->mode_view))
695 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
696 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,selected", "elm");
697 selectraise = edje_object_data_get(VIEW(it), "selectraise");
698 if ((selectraise) && (!strcmp(selectraise, "on")))
700 if (it->edit_obj) evas_object_raise(it->edit_obj);
701 else evas_object_raise(VIEW(it));
702 if ((it->item->group_item) && (it->item->group_item->realized))
703 evas_object_raise(it->item->VIEW(group_item));
705 it->highlighted = EINA_TRUE;
709 _item_unhighlight(Elm_Gen_Item *it)
711 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
712 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
713 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,unselected", "elm");
714 if (!it->item->nostacking)
716 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
718 if (it->edit_obj) evas_object_lower(it->edit_obj);
719 else evas_object_lower(VIEW(it));
723 if (it->edit_obj) evas_object_raise(it->edit_obj);
724 else evas_object_raise(VIEW(it));
727 it->highlighted = EINA_FALSE;
731 _item_block_position_update(Eina_Inlist *list, int idx)
735 EINA_INLIST_FOREACH(list, tmp)
737 tmp->position = idx++;
738 tmp->position_update = EINA_TRUE;
743 _item_position_update(Eina_List *list, int idx)
748 EINA_LIST_FOREACH(list, l, it)
750 it->position = idx++;
751 it->position_update = EINA_TRUE;
756 _item_block_del(Elm_Gen_Item *it)
759 Item_Block *itb = it->item->block;
761 itb->items = eina_list_remove(itb->items, it);
763 itb->changed = EINA_TRUE;
764 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
765 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
768 il = EINA_INLIST_GET(itb);
769 Item_Block *itbn = (Item_Block *)(il->next);
771 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
774 _item_block_position_update(il->next, itb->position);
775 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
778 if (itbn) itbn->changed = EINA_TRUE;
782 if (itb->count < itb->wd->max_items_per_block/2)
784 il = EINA_INLIST_GET(itb);
785 Item_Block *itbp = (Item_Block *)(il->prev);
786 Item_Block *itbn = (Item_Block *)(il->next);
787 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
791 EINA_LIST_FREE(itb->items, it2)
793 it2->item->block = itbp;
794 itbp->items = eina_list_append(itbp->items, it2);
796 itbp->changed = EINA_TRUE;
798 _item_block_position_update(EINA_INLIST_GET(itb)->next,
800 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
801 EINA_INLIST_GET(itb));
804 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
808 Eina_List *last = eina_list_last(itb->items);
809 Elm_Gen_Item *it2 = last->data;
811 it2->item->block = itbn;
812 itb->items = eina_list_remove_list(itb->items, last);
813 itbn->items = eina_list_prepend(itbn->items, it2);
815 itbn->changed = EINA_TRUE;
817 _item_block_position_update(EINA_INLIST_GET(itb)->next,
820 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
828 _item_subitems_clear(Elm_Gen_Item *it)
830 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
831 Eina_List *tl = NULL, *l;
832 Elm_Object_Item *it2;
834 EINA_LIST_FOREACH(it->item->items, l, it2)
835 tl = eina_list_append(tl, it2);
836 EINA_LIST_FREE(tl, it2)
837 elm_object_item_del(it2);
841 _item_del(Elm_Gen_Item *it)
843 Evas_Object *obj = WIDGET(it);
845 evas_event_freeze(evas_object_evas_get(obj));
846 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
847 if (it->wd->show_item == it) it->wd->show_item = NULL;
848 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
849 if (it->item->edit_mode_item_realized) _edit_mode_item_unrealize(it);
850 if (it->item->block) _item_block_del(it);
851 if (it->item->queued)
852 it->wd->queue = eina_list_remove(it->wd->queue, it);
853 if (it->wd->anchor_item == it)
855 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
856 if (!it->wd->anchor_item)
857 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
859 if (it->wd->expanded_item == it) it->wd->expanded_item = NULL;
861 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
862 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
863 _elm_genlist_item_del_serious(it);
864 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
865 evas_event_thaw(evas_object_evas_get(obj));
866 evas_event_thaw_eval(evas_object_evas_get(obj));
870 _clear_cb(Widget_Data *wd)
872 wd->anchor_item = NULL;
875 Item_Block *itb = (Item_Block *)(wd->blocks);
877 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
878 if (itb->items) eina_list_free(itb->items);
881 if (wd->queue_idle_enterer)
883 ecore_idle_enterer_del(wd->queue_idle_enterer);
884 wd->queue_idle_enterer = NULL;
886 if (wd->must_recalc_idler)
888 ecore_idler_del(wd->must_recalc_idler);
889 wd->must_recalc_idler = NULL;
891 if (wd->queue) wd->queue = eina_list_free(wd->queue);
892 if (wd->reorder_move_animator)
894 ecore_animator_del(wd->reorder_move_animator);
895 wd->reorder_move_animator = NULL;
897 wd->show_item = NULL;
898 wd->reorder_old_pan_y = 0;
902 _item_unselect(Elm_Gen_Item *it)
904 if ((it->generation < it->wd->generation) || (!it->selected)) return;
905 it->selected = EINA_FALSE;
906 it->wd->selected = eina_list_remove(it->wd->selected, it);
907 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
911 _mouse_move(void *data,
912 Evas *evas __UNUSED__,
916 Elm_Gen_Item *it = data;
917 Evas_Event_Mouse_Move *ev = event_info;
918 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
919 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
921 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
923 if (!it->wd->on_hold)
925 it->wd->on_hold = EINA_TRUE;
926 if ((!it->wd->wasselected) && (!it->flipped))
928 _item_unhighlight(it);
933 if (it->wd->multitouched)
935 it->wd->cur_x = ev->cur.canvas.x;
936 it->wd->cur_y = ev->cur.canvas.y;
939 if ((it->dragging) && (it->down))
941 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
944 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
945 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
946 if (abs((it->wd->history[it->wd->movements].x -
947 it->wd->history[0].x)) > 40)
948 it->wd->swipe = EINA_TRUE;
954 ecore_timer_del(it->long_timer);
955 it->long_timer = NULL;
957 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
960 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
964 ecore_timer_del(it->long_timer);
965 it->long_timer = NULL;
967 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
969 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
970 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
972 if (!it->wd->reorder_start_y)
973 it->wd->reorder_start_y = it->item->block->y + it->y;
977 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
978 y_pos = oy + oh - it->wd->reorder_it->item->h;
983 _item_position(it, it->edit_obj, it->item->scrl_x, y_pos);
985 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
987 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
988 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
992 if (!it->display_only)
993 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
994 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
995 x = ev->cur.canvas.x - x;
996 y = ev->cur.canvas.y - y;
999 if (adx < 0) adx = -dx;
1002 if (ady < 0) ady = -dy;
1005 if ((adx > minw) || (ady > minh))
1007 it->dragging = EINA_TRUE;
1010 ecore_timer_del(it->long_timer);
1011 it->long_timer = NULL;
1013 if (!it->wd->wasselected)
1015 _item_unhighlight(it);
1021 evas_object_smart_callback_call(WIDGET(it),
1022 SIG_DRAG_START_UP, it);
1026 evas_object_smart_callback_call(WIDGET(it),
1027 SIG_DRAG_START_LEFT, it);
1029 evas_object_smart_callback_call(WIDGET(it),
1030 SIG_DRAG_START_RIGHT, it);
1036 evas_object_smart_callback_call(WIDGET(it),
1037 SIG_DRAG_START_DOWN, it);
1041 evas_object_smart_callback_call(WIDGET(it),
1042 SIG_DRAG_START_LEFT, it);
1044 evas_object_smart_callback_call(WIDGET(it),
1045 SIG_DRAG_START_RIGHT, it);
1052 _long_press(void *data)
1054 Elm_Gen_Item *it = data, *it_tmp;
1055 Eina_List *list, *l;
1057 it->long_timer = NULL;
1058 if (elm_widget_item_disabled_get(it) || (it->dragging) || (it->display_only))
1059 return ECORE_CALLBACK_CANCEL;
1060 it->wd->longpressed = EINA_TRUE;
1061 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1062 if ((it->wd->reorder_mode) && (!it->group))
1064 it->wd->reorder_it = it;
1065 it->wd->reorder_start_y = 0;
1067 evas_object_raise(it->edit_obj);
1069 evas_object_raise(VIEW(it));
1071 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1072 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1074 list = elm_genlist_realized_items_get(it->wd->obj);
1075 EINA_LIST_FOREACH(list, l, it_tmp)
1077 if (it != it_tmp) _item_unselect(it_tmp);
1079 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1081 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1082 return ECORE_CALLBACK_RENEW;
1085 if (!it->wd->edit_mode)
1086 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1088 return ECORE_CALLBACK_CANCEL;
1092 _swipe(Elm_Gen_Item *it)
1097 if ((it->display_only) || elm_widget_item_disabled_get(it)) return;
1098 it->wd->swipe = EINA_FALSE;
1099 for (i = 0; i < it->wd->movements; i++)
1101 sum += it->wd->history[i].x;
1102 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1105 sum /= it->wd->movements;
1106 if (abs(sum - it->wd->history[0].x) <= 10) return;
1107 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1111 _swipe_cancel(void *data)
1113 Elm_Gen_Item *it = data;
1115 if (!it) return ECORE_CALLBACK_CANCEL;
1116 it->wd->swipe = EINA_FALSE;
1117 it->wd->movements = 0;
1118 return ECORE_CALLBACK_RENEW;
1122 _multi_cancel(void *data)
1124 Widget_Data *wd = data;
1126 if (!wd) return ECORE_CALLBACK_CANCEL;
1127 wd->multi_timeout = EINA_TRUE;
1128 return ECORE_CALLBACK_RENEW;
1132 _multi_touch_gesture_eval(void *data)
1134 Elm_Gen_Item *it = data;
1136 it->wd->multitouched = EINA_FALSE;
1137 if (it->wd->multi_timer)
1139 ecore_timer_del(it->wd->multi_timer);
1140 it->wd->multi_timer = NULL;
1142 if (it->wd->multi_timeout)
1144 it->wd->multi_timeout = EINA_FALSE;
1148 Evas_Coord minw = 0, minh = 0;
1149 Evas_Coord off_x, off_y, off_mx, off_my;
1151 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1152 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1153 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1154 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1155 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1157 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1159 if ((off_x + off_mx) > (off_y + off_my))
1161 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1162 evas_object_smart_callback_call(WIDGET(it),
1163 SIG_MULTI_SWIPE_RIGHT, it);
1164 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1165 evas_object_smart_callback_call(WIDGET(it),
1166 SIG_MULTI_SWIPE_LEFT, it);
1167 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1168 evas_object_smart_callback_call(WIDGET(it),
1169 SIG_MULTI_PINCH_OUT, it);
1171 evas_object_smart_callback_call(WIDGET(it),
1172 SIG_MULTI_PINCH_IN, it);
1176 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1177 evas_object_smart_callback_call(WIDGET(it),
1178 SIG_MULTI_SWIPE_DOWN, it);
1179 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1180 evas_object_smart_callback_call(WIDGET(it),
1181 SIG_MULTI_SWIPE_UP, it);
1182 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1183 evas_object_smart_callback_call(WIDGET(it),
1184 SIG_MULTI_PINCH_OUT, it);
1186 evas_object_smart_callback_call(WIDGET(it),
1187 SIG_MULTI_PINCH_IN, it);
1190 it->wd->multi_timeout = EINA_FALSE;
1194 _multi_down(void *data,
1195 Evas *evas __UNUSED__,
1196 Evas_Object *obj __UNUSED__,
1199 Elm_Gen_Item *it = data;
1200 Evas_Event_Multi_Down *ev = event_info;
1202 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1203 it->wd->multi_device = ev->device;
1204 it->wd->multi_down = EINA_TRUE;
1205 it->wd->multitouched = EINA_TRUE;
1206 it->wd->prev_mx = ev->canvas.x;
1207 it->wd->prev_my = ev->canvas.y;
1208 if (!it->wd->wasselected)
1210 _item_unhighlight(it);
1213 it->wd->wasselected = EINA_FALSE;
1214 it->wd->longpressed = EINA_FALSE;
1217 ecore_timer_del(it->long_timer);
1218 it->long_timer = NULL;
1222 it->dragging = EINA_FALSE;
1223 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1225 if (it->item->swipe_timer)
1227 ecore_timer_del(it->item->swipe_timer);
1228 it->item->swipe_timer = NULL;
1230 if (it->wd->on_hold)
1232 it->wd->swipe = EINA_FALSE;
1233 it->wd->movements = 0;
1234 it->wd->on_hold = EINA_FALSE;
1239 _multi_up(void *data,
1240 Evas *evas __UNUSED__,
1241 Evas_Object *obj __UNUSED__,
1244 Elm_Gen_Item *it = data;
1245 Evas_Event_Multi_Up *ev = event_info;
1247 if (it->wd->multi_device != ev->device) return;
1248 it->wd->multi_device = 0;
1249 it->wd->multi_down = EINA_FALSE;
1250 if (it->wd->mouse_down) return;
1251 _multi_touch_gesture_eval(data);
1255 _multi_move(void *data,
1256 Evas *evas __UNUSED__,
1257 Evas_Object *obj __UNUSED__,
1260 Elm_Gen_Item *it = data;
1261 Evas_Event_Multi_Move *ev = event_info;
1263 if (it->wd->multi_device != ev->device) return;
1264 it->wd->cur_mx = ev->cur.canvas.x;
1265 it->wd->cur_my = ev->cur.canvas.y;
1269 _mouse_down(void *data,
1270 Evas *evas __UNUSED__,
1274 Elm_Gen_Item *it = data;
1275 Evas_Event_Mouse_Down *ev = event_info;
1278 if (ev->button != 1) return;
1279 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1281 it->wd->on_hold = EINA_TRUE;
1284 it->down = EINA_TRUE;
1285 it->dragging = EINA_FALSE;
1286 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1287 it->dx = ev->canvas.x - x;
1288 it->dy = ev->canvas.y - y;
1289 it->wd->mouse_down = EINA_TRUE;
1290 if (!it->wd->multitouched)
1292 it->wd->prev_x = ev->canvas.x;
1293 it->wd->prev_y = ev->canvas.y;
1294 it->wd->multi_timeout = EINA_FALSE;
1295 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1296 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1298 it->wd->longpressed = EINA_FALSE;
1299 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1300 else it->wd->on_hold = EINA_FALSE;
1301 if (it->wd->on_hold) return;
1302 it->wd->wasselected = it->selected;
1303 _item_highlight(it);
1304 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1305 if ((!elm_widget_item_disabled_get(it)) && (!it->display_only))
1307 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1308 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1310 if (it->long_timer) ecore_timer_del(it->long_timer);
1311 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1312 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1314 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1317 it->long_timer = NULL;
1318 it->wd->swipe = EINA_FALSE;
1319 it->wd->movements = 0;
1323 _mouse_up(void *data,
1324 Evas *evas __UNUSED__,
1325 Evas_Object *obj __UNUSED__,
1328 Elm_Gen_Item *it = data;
1329 Evas_Event_Mouse_Up *ev = event_info;
1330 Eina_Bool dragged = EINA_FALSE;
1332 if (ev->button != 1) return;
1333 it->down = EINA_FALSE;
1334 it->wd->mouse_down = EINA_FALSE;
1335 if (it->wd->multitouched)
1337 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1338 if (it->wd->multi_down) return;
1339 _multi_touch_gesture_eval(data);
1342 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1343 else it->wd->on_hold = EINA_FALSE;
1346 ecore_timer_del(it->long_timer);
1347 it->long_timer = NULL;
1351 it->dragging = EINA_FALSE;
1352 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1355 if (it->item->swipe_timer)
1357 ecore_timer_del(it->item->swipe_timer);
1358 it->item->swipe_timer = NULL;
1360 if (it->wd->multi_timer)
1362 ecore_timer_del(it->wd->multi_timer);
1363 it->wd->multi_timer = NULL;
1364 it->wd->multi_timeout = EINA_FALSE;
1366 if (it->wd->on_hold)
1368 if (it->wd->swipe) _swipe(data);
1369 it->wd->longpressed = EINA_FALSE;
1370 it->wd->on_hold = EINA_FALSE;
1373 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1375 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1377 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1379 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1380 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1382 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1386 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1387 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1389 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1390 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1391 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1392 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1394 if (it->wd->longpressed)
1396 it->wd->longpressed = EINA_FALSE;
1397 if ((!it->wd->wasselected) && (!it->flipped))
1399 _item_unhighlight(it);
1402 it->wd->wasselected = EINA_FALSE;
1407 if (it->want_unrealize)
1409 _elm_genlist_item_unrealize(it, EINA_FALSE);
1410 if (it->item->block->want_unrealize)
1411 _item_block_unrealize(it->item->block);
1414 if (elm_widget_item_disabled_get(it) || (dragged) || (it->display_only))
1416 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1421 _item_highlight(it);
1426 _item_unhighlight(it);
1434 Widget_Data *wd = it->wd;
1437 while (wd->selected)
1439 _item_unhighlight(wd->selected->data);
1440 _item_unselect(wd->selected->data);
1446 const Eina_List *l, *l_next;
1449 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1452 _item_unhighlight(it2);
1453 _item_unselect(it2);
1455 //_item_highlight(it);
1458 _item_highlight(it);
1464 _signal_expand_toggle(void *data,
1465 Evas_Object *obj __UNUSED__,
1466 const char *emission __UNUSED__,
1467 const char *source __UNUSED__)
1469 Elm_Gen_Item *it = data;
1471 if (it->item->expanded)
1472 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1474 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1478 _signal_expand(void *data,
1479 Evas_Object *obj __UNUSED__,
1480 const char *emission __UNUSED__,
1481 const char *source __UNUSED__)
1483 Elm_Gen_Item *it = data;
1485 if (!it->item->expanded)
1486 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1490 _signal_contract(void *data,
1491 Evas_Object *obj __UNUSED__,
1492 const char *emission __UNUSED__,
1493 const char *source __UNUSED__)
1495 Elm_Gen_Item *it = data;
1497 if (it->item->expanded)
1498 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1502 _scr_hold_timer_cb(void *data)
1504 if (!data) return ECORE_CALLBACK_CANCEL;
1505 Widget_Data *wd = data;
1506 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1507 wd->scr_hold_timer = NULL;
1508 return ECORE_CALLBACK_CANCEL;
1512 _mode_finished_signal_cb(void *data,
1514 const char *emission __UNUSED__,
1515 const char *source __UNUSED__)
1519 Elm_Gen_Item *it = data;
1520 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1522 Evas *te = evas_object_evas_get(obj);
1524 evas_event_freeze(te);
1525 it->item->nocache_once = EINA_FALSE;
1526 _mode_item_unrealize(it);
1527 if (it->item->group_item)
1528 evas_object_raise(it->item->VIEW(group_item));
1529 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->mode_type);
1530 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1531 evas_event_thaw(te);
1532 evas_event_thaw_eval(te);
1536 _item_cache_clean(Widget_Data *wd)
1538 evas_event_freeze(evas_object_evas_get(wd->obj));
1539 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1543 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1544 wd->item_cache = eina_inlist_remove(wd->item_cache,
1545 wd->item_cache->last);
1546 wd->item_cache_count--;
1547 if (itc->spacer) evas_object_del(itc->spacer);
1548 if (itc->base_view) evas_object_del(itc->base_view);
1549 eina_stringshare_del(itc->item_style);
1552 evas_event_thaw(evas_object_evas_get(wd->obj));
1553 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1557 _item_cache_zero(Widget_Data *wd)
1559 int pmax = wd->item_cache_max;
1560 wd->item_cache_max = 0;
1561 _item_cache_clean(wd);
1562 wd->item_cache_max = pmax;
1566 _item_cache_add(Elm_Gen_Item *it)
1570 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1571 if (it->wd->item_cache_max <= 0)
1573 evas_object_del(VIEW(it));
1575 evas_object_del(it->spacer);
1577 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1578 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1582 it->wd->item_cache_count++;
1583 itc = calloc(1, sizeof(Item_Cache));
1586 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1587 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1590 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1591 EINA_INLIST_GET(itc));
1592 itc->spacer = it->spacer;
1594 itc->base_view = VIEW(it);
1596 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1597 evas_object_hide(itc->base_view);
1598 evas_object_move(itc->base_view, -9999, -9999);
1599 itc->item_style = eina_stringshare_add(it->itc->item_style);
1600 if (it->item->type & ELM_GENLIST_ITEM_SUBITEMS) itc->tree = 1;
1601 itc->compress = (it->wd->compress);
1602 itc->selected = it->selected;
1603 itc->disabled = elm_widget_item_disabled_get(it);
1604 itc->expanded = it->item->expanded;
1607 ecore_timer_del(it->long_timer);
1608 it->long_timer = NULL;
1610 if (it->item->swipe_timer)
1612 ecore_timer_del(it->item->swipe_timer);
1613 it->item->swipe_timer = NULL;
1615 // FIXME: other callbacks?
1616 edje_object_signal_callback_del_full(itc->base_view,
1617 "elm,action,expand,toggle",
1618 "elm", _signal_expand_toggle, it);
1619 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1621 _signal_expand, it);
1622 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1623 "elm", _signal_contract, it);
1624 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1626 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1628 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1630 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1632 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1634 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1636 _item_cache_clean(it->wd);
1637 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1638 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1642 _item_cache_find(Elm_Gen_Item *it)
1647 if (it->item->type & ELM_GENLIST_ITEM_SUBITEMS) tree = 1;
1648 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1650 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1652 if ((itc->tree == tree) &&
1653 (itc->compress == it->wd->compress) &&
1654 (((!it->itc->item_style) && (!itc->item_style)) ||
1655 (it->itc->item_style && itc->item_style &&
1656 (!strcmp(it->itc->item_style, itc->item_style)))))
1658 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1659 EINA_INLIST_GET(itc));
1660 it->wd->item_cache_count--;
1668 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1670 if (it->position_update || it->item->block->position_update)
1672 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1673 it->position_update = EINA_FALSE;
1678 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1680 if (!it->item->nostacking)
1682 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1684 if (it->edit_obj) evas_object_lower(it->edit_obj);
1685 else evas_object_lower(VIEW(it));
1689 if (it->edit_obj) evas_object_raise(it->edit_obj);
1690 else evas_object_raise(VIEW(it));
1694 if (it->item->order_num_in & 0x1)
1696 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1697 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,odd", "elm");
1701 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1702 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,even", "elm");
1707 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1711 if (it->selected != itc->selected)
1714 edje_object_signal_emit(VIEW(it),
1715 "elm,state,selected", "elm");
1718 edje_object_signal_emit(it->edit_obj,
1719 "elm,state,selected", "elm");
1721 if (elm_widget_item_disabled_get(it) != itc->disabled)
1723 if (elm_widget_item_disabled_get(it))
1724 edje_object_signal_emit(VIEW(it),
1725 "elm,state,disabled", "elm");
1727 edje_object_signal_emit(it->edit_obj,
1728 "elm,state,disabled", "elm");
1730 if (it->item->expanded != itc->expanded)
1732 if (it->item->expanded)
1733 edje_object_signal_emit(VIEW(it),
1734 "elm,state,expanded", "elm");
1736 edje_object_signal_emit(it->edit_obj,
1737 "elm,state,expanded", "elm");
1744 edje_object_signal_emit(VIEW(it),
1745 "elm,state,selected", "elm");
1747 edje_object_signal_emit(it->edit_obj,
1748 "elm,state,selected", "elm");
1751 if (elm_widget_item_disabled_get(it))
1753 edje_object_signal_emit(VIEW(it),
1754 "elm,state,disabled", "elm");
1756 edje_object_signal_emit(it->edit_obj,
1757 "elm,state,disabled", "elm");
1759 if (it->item->expanded)
1761 edje_object_signal_emit(VIEW(it),
1762 "elm,state,expanded", "elm");
1764 edje_object_signal_emit(it->edit_obj,
1765 "elm,state,expanded", "elm");
1771 _item_cache_free(Item_Cache *itc)
1773 if (itc->spacer) evas_object_del(itc->spacer);
1774 if (itc->base_view) evas_object_del(itc->base_view);
1775 eina_stringshare_del(itc->item_style);
1780 _item_text_realize(Elm_Gen_Item *it,
1781 Evas_Object *target,
1785 if (it->itc->func.text_get)
1790 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1791 EINA_LIST_FOREACH(*source, l, key)
1793 if (parts && fnmatch(parts, key, FNM_PERIOD))
1796 char *s = it->itc->func.text_get
1797 ((void *)it->base.data, WIDGET(it), key);
1801 edje_object_part_text_set(target, key, s);
1806 edje_object_part_text_set(target, key, "");
1813 _item_content_unrealize(Elm_Gen_Item *it,
1814 Evas_Object *target,
1818 Eina_List *res = it->content_objs;
1820 if (it->itc->func.content_get)
1824 Evas_Object *ic = NULL;
1826 EINA_LIST_FOREACH(*source, l, key)
1828 if (parts && fnmatch(parts, key, FNM_PERIOD))
1831 ic = edje_object_part_swallow_get(target, key);
1834 res = eina_list_remove(res, ic);
1835 edje_object_part_unswallow(target, ic);
1836 evas_object_del(ic);
1845 _item_content_realize(Elm_Gen_Item *it,
1846 Evas_Object *target,
1850 Eina_List *res = NULL;
1852 if (it->itc->func.content_get)
1856 Evas_Object *ic = NULL;
1858 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1860 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
1861 res = it->content_objs;
1863 EINA_LIST_FOREACH(*source, l, key)
1865 if (parts && fnmatch(parts, key, FNM_PERIOD))
1868 if (it->itc->func.content_get)
1869 ic = it->itc->func.content_get
1870 ((void *)it->base.data, WIDGET(it), key);
1873 res = eina_list_append(res, ic);
1874 edje_object_part_swallow(target, key, ic);
1875 evas_object_show(ic);
1876 elm_widget_sub_object_add(WIDGET(it), ic);
1877 if (elm_widget_item_disabled_get(it))
1878 elm_widget_disabled_set(ic, EINA_TRUE);
1887 _item_state_realize(Elm_Gen_Item *it,
1888 Evas_Object *target,
1892 if (it->itc->func.state_get)
1898 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
1899 EINA_LIST_FOREACH(*source, l, key)
1901 if (parts && fnmatch(parts, key, FNM_PERIOD))
1904 Eina_Bool on = it->itc->func.state_get
1905 ((void *)it->base.data, WIDGET(it), key);
1909 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1910 edje_object_signal_emit(target, buf, "elm");
1914 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1915 edje_object_signal_emit(target, buf, "elm");
1922 _item_flips_realize(Elm_Gen_Item *it,
1923 Evas_Object *target,
1926 Eina_List *res = NULL;
1928 if (it->itc->func.content_get)
1932 Evas_Object *ic = NULL;
1934 *source = elm_widget_stringlist_get(edje_object_data_get(target, "flips"));
1936 EINA_LIST_FOREACH(*source, l, key)
1938 if (it->itc->func.content_get)
1939 ic = it->itc->func.content_get
1940 ((void *)it->base.data, WIDGET(it), key);
1943 res = eina_list_append(res, ic);
1944 edje_object_part_swallow(target, key, ic);
1945 evas_object_show(ic);
1946 elm_widget_sub_object_add(WIDGET(it), ic);
1947 if (elm_widget_item_disabled_get(it))
1948 elm_widget_disabled_set(ic, EINA_TRUE);
1957 _item_realize(Elm_Gen_Item *it,
1961 const char *treesize;
1964 Item_Cache *itc = NULL;
1966 if (it->generation < it->wd->generation) return;
1967 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1970 if (it->item->order_num_in != in)
1972 it->item->order_num_in = in;
1973 _elm_genlist_item_odd_even_update(it);
1974 _elm_genlist_item_state_update(it, NULL);
1975 _elm_genlist_item_index_update(it);
1977 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1978 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1981 it->item->order_num_in = in;
1983 if (it->item->nocache_once)
1984 it->item->nocache_once = EINA_FALSE;
1985 else if (!it->item->nocache)
1986 itc = _item_cache_find(it);
1987 if (itc && (!it->wd->tree_effect_enabled))
1989 VIEW(it) = itc->base_view;
1990 itc->base_view = NULL;
1991 it->spacer = itc->spacer;
1996 const char *stacking_even;
1997 const char *stacking;
1999 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2000 edje_object_scale_set(VIEW(it),
2001 elm_widget_scale_get(WIDGET(it)) *
2002 _elm_config->scale);
2003 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2004 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2006 if (it->item->type & ELM_GENLIST_ITEM_SUBITEMS)
2007 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->compress ? "_compress" : "", it->itc->item_style ?: "default");
2009 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->compress ? "_compress" : "", it->itc->item_style ?: "default");
2011 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2012 elm_widget_style_get(WIDGET(it)));
2014 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2015 if (!stacking_even) stacking_even = "above";
2016 it->item->stacking_even = !!strcmp("above", stacking_even);
2018 stacking = edje_object_data_get(VIEW(it), "stacking");
2019 if (!stacking) stacking = "yes";
2020 it->item->nostacking = !!strcmp("yes", stacking);
2022 edje_object_mirrored_set(VIEW(it),
2023 elm_widget_mirrored_get(WIDGET(it)));
2025 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2026 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2027 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2030 _elm_genlist_item_odd_even_update(it);
2032 treesize = edje_object_data_get(VIEW(it), "treesize");
2033 if (treesize) tsize = atoi(treesize);
2034 evas_object_size_hint_min_set(it->spacer,
2035 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2036 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2039 edje_object_signal_callback_add(VIEW(it),
2040 "elm,action,expand,toggle",
2041 "elm", _signal_expand_toggle, it);
2042 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2043 "elm", _signal_expand, it);
2044 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2045 "elm", _signal_contract, it);
2046 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
2048 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
2050 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
2052 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
2054 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
2056 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
2059 if ((it->wd->edit_mode) && (!it->edit_obj) &&
2060 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->edit_item_style))
2061 _edit_mode_item_realize(it, EINA_FALSE);
2063 _elm_genlist_item_state_update(it, itc);
2064 _elm_genlist_item_index_update(it);
2067 if ((calc) && (it->wd->homogeneous) &&
2068 ((it->wd->item_width) ||
2069 ((it->wd->item_width) && (it->wd->group_item_width))))
2071 /* homogenous genlist shortcut */
2072 if (!it->item->mincalcd)
2076 it->item->w = it->item->minw = it->wd->group_item_width;
2077 it->item->h = it->item->minh = it->wd->group_item_height;
2081 it->item->w = it->item->minw = it->wd->item_width;
2082 it->item->h = it->item->minh = it->wd->item_height;
2084 it->item->mincalcd = EINA_TRUE;
2089 /* FIXME: If you see that assert, please notify us and we
2090 will clean our mess */
2091 assert(eina_list_count(it->content_objs) == 0);
2093 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2094 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2095 _item_state_realize(it, VIEW(it), &it->states, NULL);
2098 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2099 it->content_objs = _item_flips_realize(it, VIEW(it), &it->contents);
2102 if (!it->item->mincalcd)
2104 Evas_Coord mw = -1, mh = -1;
2106 if (!it->display_only)
2107 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2108 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
2109 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2111 if (!it->display_only)
2112 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2113 it->item->w = it->item->minw = mw;
2114 it->item->h = it->item->minh = mh;
2115 it->item->mincalcd = EINA_TRUE;
2117 if ((!it->wd->group_item_width) && (it->group))
2119 it->wd->group_item_width = mw;
2120 it->wd->group_item_height = mh;
2122 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2124 it->wd->item_width = mw;
2125 it->wd->item_height = mh;
2128 if (!calc) evas_object_show(VIEW(it));
2131 if (it->tooltip.content_cb)
2133 elm_widget_item_tooltip_content_cb_set(it,
2134 it->tooltip.content_cb,
2135 it->tooltip.data, NULL);
2136 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2137 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2140 if (it->mouse_cursor)
2141 elm_widget_item_cursor_set(it, it->mouse_cursor);
2143 it->realized = EINA_TRUE;
2144 it->want_unrealize = EINA_FALSE;
2146 if (itc) _item_cache_free(itc);
2147 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2148 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2150 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2152 if ((!calc) && (it->wd->edit_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2154 if (it->itc->edit_item_style)
2156 if (!it->edit_obj) _edit_mode_item_realize(it, EINA_FALSE);
2157 edje_object_message_signal_process(it->edit_obj);
2160 edje_object_message_signal_process(VIEW(it));
2164 _item_unrealize_cb(Elm_Gen_Item *it)
2166 if (it->item->nocache_once || it->item->nocache)
2168 evas_object_del(VIEW(it));
2170 evas_object_del(it->spacer);
2175 edje_object_mirrored_set(VIEW(it),
2176 elm_widget_mirrored_get(WIDGET(it)));
2177 edje_object_scale_set(VIEW(it),
2178 elm_widget_scale_get(WIDGET(it))
2179 * _elm_config->scale);
2180 _item_cache_add(it);
2183 _mode_item_unrealize(it);
2185 it->realized = EINA_FALSE;
2186 it->want_unrealize = EINA_FALSE;
2187 if (it->wd->edit_mode) _edit_mode_item_unrealize(it);
2191 _item_block_recalc(Item_Block *itb,
2197 Evas_Coord minw = 0, minh = 0;
2198 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2201 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2203 EINA_LIST_FOREACH(itb->items, l, it)
2205 if (it->generation < it->wd->generation) continue;
2206 showme |= it->item->showme;
2211 if (!it->item->mincalcd) changed = EINA_TRUE;
2214 _item_realize(it, in, EINA_TRUE);
2215 _elm_genlist_item_unrealize(it, EINA_TRUE);
2220 _item_realize(it, in, EINA_TRUE);
2221 _elm_genlist_item_unrealize(it, EINA_TRUE);
2225 _item_realize(it, in, EINA_FALSE);
2226 minh += it->item->minh;
2227 if (minw < it->item->minw) minw = it->item->minw;
2235 itb->changed = EINA_FALSE;
2236 itb->position_update = EINA_FALSE;
2237 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2238 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2243 _item_block_realize(Item_Block *itb)
2245 if (itb->realized) return;
2246 itb->realized = EINA_TRUE;
2247 itb->want_unrealize = EINA_FALSE;
2251 _item_block_unrealize(Item_Block *itb)
2255 Eina_Bool dragging = EINA_FALSE;
2257 if (!itb->realized) return;
2258 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2259 EINA_LIST_FOREACH(itb->items, l, it)
2261 if (itb->must_recalc || !it->group)
2265 dragging = EINA_TRUE;
2266 it->want_unrealize = EINA_TRUE;
2269 _elm_genlist_item_unrealize(it, EINA_FALSE);
2274 itb->realized = EINA_FALSE;
2275 itb->want_unrealize = EINA_TRUE;
2278 itb->want_unrealize = EINA_FALSE;
2279 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2280 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2284 _get_space_for_reorder_item(Elm_Gen_Item *it)
2286 Evas_Coord rox, roy, row, roh, oy, oh;
2287 Eina_Bool top = EINA_FALSE;
2288 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2289 if (!reorder_it) return 0;
2291 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2292 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2294 if ((it->wd->reorder_start_y < it->item->block->y) &&
2295 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2297 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2298 if (it->item->block->count == 1)
2299 it->wd->reorder_rel = it;
2301 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2302 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2304 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2307 it->item->block->reorder_offset = 0;
2309 it->item->scrl_y += it->item->block->reorder_offset;
2311 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2312 rox, roy + (roh / 2), row, 1));
2315 it->wd->reorder_rel = it;
2316 it->item->scrl_y += it->wd->reorder_it->item->h;
2317 return it->wd->reorder_it->item->h;
2324 _reorder_move_animator_cb(void *data)
2326 Elm_Gen_Item *it = data;
2327 Eina_Bool down = EINA_FALSE;
2329 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2331 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2333 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2336 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2337 if (diff > it->item->h) y = diff / 2;
2339 if (it->item->old_scrl_y < it->item->scrl_y)
2341 it->item->old_scrl_y += y;
2344 else if (it->item->old_scrl_y > it->item->scrl_y)
2346 it->item->old_scrl_y -= y;
2351 _item_position(it, it->edit_obj, it->item->scrl_x, it->item->old_scrl_y);
2353 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2354 _group_items_recalc(it->wd);
2356 if ((it->wd->reorder_pan_move) ||
2357 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2358 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2360 it->item->old_scrl_y = it->item->scrl_y;
2361 it->item->move_effect_enabled = EINA_FALSE;
2362 it->wd->reorder_move_animator = NULL;
2363 return ECORE_CALLBACK_CANCEL;
2365 return ECORE_CALLBACK_RENEW;
2369 _item_position(Elm_Gen_Item *it,
2377 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2378 evas_object_resize(view, it->item->w, it->item->h);
2379 evas_object_move(view, it_x, it_y);
2380 evas_object_show(view);
2381 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2382 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2386 _item_block_position(Item_Block *itb,
2392 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2393 Eina_Bool vis = EINA_FALSE;
2395 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2396 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2397 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2399 EINA_LIST_FOREACH(itb->items, l, it)
2401 if (it->generation < it->wd->generation) continue;
2402 else if (it->wd->reorder_it == it) continue;
2405 it->item->w = itb->w;
2406 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2407 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2409 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2410 cvx, cvy, cvw, cvh));
2413 if ((itb->realized) && (!it->realized))
2415 if (vis) _item_realize(it, in, EINA_FALSE);
2419 if (vis || it->dragging)
2421 if (it->wd->reorder_mode)
2422 y += _get_space_for_reorder_item(it);
2423 git = it->item->group_item;
2426 if (git->item->scrl_y < oy)
2427 git->item->scrl_y = oy;
2428 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2429 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2430 git->item->want_realize = EINA_TRUE;
2432 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2434 if (!it->item->move_effect_enabled)
2436 it->item->move_effect_enabled = EINA_TRUE;
2437 it->wd->reorder_move_animator =
2439 _reorder_move_animator_cb, it);
2442 if (!it->item->move_effect_enabled)
2444 if ((it->wd->edit_mode) && (it->itc->edit_item_style))
2445 _edit_mode_item_position(it, it->item->scrl_x,
2449 if (it->item->mode_view)
2450 _item_position(it, it->item->mode_view,
2454 _item_position(it, VIEW(it), it->item->scrl_x,
2457 it->item->old_scrl_y = it->item->scrl_y;
2462 if (!it->wd->item_moving_effect_timer)
2463 _elm_genlist_item_unrealize(it, EINA_FALSE);
2470 if (vis) it->item->want_realize = EINA_TRUE;
2474 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2475 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2479 _group_items_recalc(void *data)
2481 Widget_Data *wd = data;
2485 evas_event_freeze(evas_object_evas_get(wd->obj));
2486 EINA_LIST_FOREACH(wd->group_items, l, git)
2488 if (git->item->want_realize)
2491 _item_realize(git, 0, EINA_FALSE);
2492 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2493 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2494 evas_object_show(VIEW(git));
2495 evas_object_raise(VIEW(git));
2497 else if (!git->item->want_realize && git->realized)
2500 _elm_genlist_item_unrealize(git, EINA_FALSE);
2503 evas_event_thaw(evas_object_evas_get(wd->obj));
2504 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2508 _must_recalc_idler(void *data)
2510 Widget_Data *wd = data;
2511 if (wd->calc_job) ecore_job_del(wd->calc_job);
2512 wd->calc_job = ecore_job_add(_calc_job, wd);
2513 wd->must_recalc_idler = NULL;
2514 return ECORE_CALLBACK_CANCEL;
2518 _scroll_item(Widget_Data *wd)
2520 Elm_Gen_Item *it = NULL;
2521 Evas_Coord gith = 0;
2522 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2524 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2526 dx = it->x + it->item->block->x;
2527 dy = it->y + it->item->block->y;
2528 dw = it->item->block->w;
2530 switch (wd->scrollto_type)
2532 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2533 if (it->item->group_item) gith = it->item->group_item->item->h;
2536 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2537 dy += (it->item->h / 2 - oh / 2);
2539 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2541 if ((wd->expanded_item) &&
2542 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2543 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2545 it = wd->expanded_item;
2546 if (it->item->group_item) gith = it->item->group_item->item->h;
2547 dx = it->x + it->item->block->x;
2548 dy = it->y + it->item->block->y - gith;
2549 dw = it->item->block->w;
2553 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2554 gith = it->item->group_item->item->h;
2561 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2563 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2565 it->item->showme = EINA_FALSE;
2566 wd->show_item = NULL;
2567 wd->auto_scroll_enabled = EINA_FALSE;
2568 wd->check_scroll = EINA_FALSE;
2572 _calc_job(void *data)
2574 Widget_Data *wd = data;
2575 Item_Block *itb, *chb = NULL;
2576 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2577 Evas_Coord pan_w = 0, pan_h = 0;
2579 Eina_Bool minw_change = EINA_FALSE;
2580 Eina_Bool did_must_recalc = EINA_FALSE;
2583 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2584 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2589 evas_event_freeze(evas_object_evas_get(wd->obj));
2590 EINA_INLIST_FOREACH(wd->blocks, itb)
2592 Eina_Bool showme = EINA_FALSE;
2595 showme = itb->showme;
2596 itb->showme = EINA_FALSE;
2599 if (itb->realized) _item_block_unrealize(itb);
2601 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2603 if (itb->must_recalc)
2607 EINA_LIST_FOREACH(itb->items, l, it)
2608 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2609 itb->changed = EINA_TRUE;
2610 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2611 if (itb->realized) _item_block_unrealize(itb);
2612 itb->must_recalc = EINA_FALSE;
2614 showme = _item_block_recalc(itb, in, EINA_FALSE);
2620 if (minw == -1) minw = itb->minw;
2621 else if ((!itb->must_recalc) && (minw < itb->minw))
2624 minw_change = EINA_TRUE;
2629 minw_change = EINA_TRUE;
2635 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2636 wd->check_scroll = EINA_TRUE;
2640 EINA_INLIST_FOREACH(wd->blocks, itb)
2646 if ((chb) && (EINA_INLIST_GET(chb)->next))
2648 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2650 if (itb->realized) _item_block_unrealize(itb);
2653 wd->realminw = minw;
2654 if (minw < wd->w) minw = wd->w;
2655 if ((minw != wd->minw) || (minh != wd->minh))
2659 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2660 _sizing_eval(wd->obj);
2661 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2666 it = wd->anchor_item;
2667 it_y = wd->anchor_y;
2668 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2669 it->item->block->y + it->y + it_y);
2670 wd->anchor_item = it;
2671 wd->anchor_y = it_y;
2674 if (did_must_recalc)
2676 if (!wd->must_recalc_idler)
2677 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2679 if (wd->check_scroll)
2681 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2682 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2683 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2684 switch (wd->scrollto_type)
2686 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2689 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2692 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2697 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2698 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2703 wd->calc_job = NULL;
2704 evas_object_smart_changed(wd->pan_smart);
2705 evas_event_thaw(evas_object_evas_get(wd->obj));
2706 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2710 _update_job(void *data)
2712 Widget_Data *wd = data;
2716 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2718 wd->update_job = NULL;
2721 evas_event_freeze(evas_object_evas_get(wd->obj));
2722 EINA_INLIST_FOREACH(wd->blocks, itb)
2724 Evas_Coord itminw, itminh;
2731 _item_block_position(itb, num);
2735 recalc = EINA_FALSE;
2736 EINA_LIST_FOREACH(itb->items, l2, it)
2738 if (it->item->updateme)
2740 itminw = it->item->minw;
2741 itminh = it->item->minh;
2743 it->item->updateme = EINA_FALSE;
2746 _elm_genlist_item_unrealize(it, EINA_FALSE);
2747 _item_realize(it, num, EINA_FALSE);
2748 position = EINA_TRUE;
2752 _item_realize(it, num, EINA_TRUE);
2753 _elm_genlist_item_unrealize(it, EINA_TRUE);
2755 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2760 itb->updateme = EINA_FALSE;
2763 position = EINA_TRUE;
2764 itb->changed = EINA_TRUE;
2765 _item_block_recalc(itb, num0, EINA_FALSE);
2766 _item_block_position(itb, num0);
2771 if (wd->calc_job) ecore_job_del(wd->calc_job);
2772 wd->calc_job = ecore_job_add(_calc_job, wd);
2774 evas_event_thaw(evas_object_evas_get(wd->obj));
2775 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2779 _pan_set(Evas_Object *obj,
2783 Pan *sd = evas_object_smart_data_get(obj);
2787 // Evas_Coord ow, oh;
2788 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2789 // ow = sd->wd->minw - ow;
2790 // if (ow < 0) ow = 0;
2791 // oh = sd->wd->minh - oh;
2792 // if (oh < 0) oh = 0;
2793 // if (x < 0) x = 0;
2794 // if (y < 0) y = 0;
2795 // if (x > ow) x = ow;
2796 // if (y > oh) y = oh;
2797 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2801 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2803 if ((itb->y + itb->h) > y)
2808 EINA_LIST_FOREACH(itb->items, l2, it)
2810 if ((itb->y + it->y) >= y)
2812 sd->wd->anchor_item = it;
2813 sd->wd->anchor_y = -(itb->y + it->y - y);
2820 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2824 _pan_get(Evas_Object *obj,
2828 Pan *sd = evas_object_smart_data_get(obj);
2831 if (x) *x = sd->wd->pan_x;
2832 if (y) *y = sd->wd->pan_y;
2836 _pan_max_get(Evas_Object *obj,
2840 Pan *sd = evas_object_smart_data_get(obj);
2844 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2845 ow = sd->wd->minw - ow;
2847 oh = sd->wd->minh - oh;
2854 _pan_min_get(Evas_Object *obj __UNUSED__,
2863 _pan_child_size_get(Evas_Object *obj,
2867 Pan *sd = evas_object_smart_data_get(obj);
2870 if (w) *w = sd->wd->minw;
2871 if (h) *h = sd->wd->minh;
2875 _pan_add(Evas_Object *obj)
2878 Evas_Object_Smart_Clipped_Data *cd;
2881 cd = evas_object_smart_data_get(obj);
2884 sd->__clipped_data = *cd;
2886 evas_object_smart_data_set(obj, sd);
2890 _pan_del(Evas_Object *obj)
2892 Pan *sd = evas_object_smart_data_get(obj);
2897 ecore_job_del(sd->resize_job);
2898 sd->resize_job = NULL;
2904 _pan_resize_job(void *data)
2908 _sizing_eval(sd->wd->obj);
2909 sd->resize_job = NULL;
2913 _pan_resize(Evas_Object *obj,
2917 Pan *sd = evas_object_smart_data_get(obj);
2921 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2922 if ((ow == w) && (oh == h)) return;
2923 if ((sd->wd->height_for_width) && (ow != w))
2926 if (sd->resize_job) ecore_job_del(sd->resize_job);
2927 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2929 sd->wd->pan_changed = EINA_TRUE;
2930 evas_object_smart_changed(obj);
2931 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2932 sd->wd->calc_job = NULL;
2934 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2935 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2940 _pan_calculate(Evas_Object *obj)
2942 Pan *sd = evas_object_smart_data_get(obj);
2944 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2950 evas_event_freeze(evas_object_evas_get(obj));
2952 if (sd->wd->pan_changed)
2955 sd->wd->pan_changed = EINA_FALSE;
2958 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2959 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2960 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2962 git->item->want_realize = EINA_FALSE;
2964 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2966 itb->w = sd->wd->minw;
2967 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2968 itb->y - sd->wd->pan_y + oy,
2970 cvx, cvy, cvw, cvh))
2972 if ((!itb->realized) || (itb->changed))
2973 _item_block_realize(itb);
2974 _item_block_position(itb, in);
2978 if (itb->realized) _item_block_unrealize(itb);
2982 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2983 _group_items_recalc(sd->wd);
2984 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2986 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2987 sd->wd->reorder_pan_move = EINA_TRUE;
2988 else sd->wd->reorder_pan_move = EINA_FALSE;
2989 evas_object_raise(sd->wd->VIEW(reorder_it));
2990 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2991 sd->wd->start_time = ecore_loop_time_get();
2994 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_NONE))
2996 if (!sd->wd->item_moving_effect_timer)
2998 _item_tree_effect_before(sd->wd->expanded_item);
2999 evas_object_raise(sd->wd->alpha_bg);
3000 evas_object_show(sd->wd->alpha_bg);
3001 sd->wd->start_time = ecore_time_get();
3002 sd->wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, sd->wd);
3006 _item_auto_scroll(sd->wd);
3008 evas_event_thaw(evas_object_evas_get(obj));
3009 evas_event_thaw_eval(evas_object_evas_get(obj));
3013 _pan_move(Evas_Object *obj,
3014 Evas_Coord x __UNUSED__,
3015 Evas_Coord y __UNUSED__)
3017 Pan *sd = evas_object_smart_data_get(obj);
3021 sd->wd->pan_changed = EINA_TRUE;
3022 evas_object_smart_changed(obj);
3023 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3024 sd->wd->calc_job = NULL;
3028 _hold_on(void *data __UNUSED__,
3030 void *event_info __UNUSED__)
3032 Widget_Data *wd = elm_widget_data_get(obj);
3034 elm_smart_scroller_hold_set(wd->scr, 1);
3038 _hold_off(void *data __UNUSED__,
3040 void *event_info __UNUSED__)
3042 Widget_Data *wd = elm_widget_data_get(obj);
3044 elm_smart_scroller_hold_set(wd->scr, 0);
3048 _freeze_on(void *data __UNUSED__,
3050 void *event_info __UNUSED__)
3052 Widget_Data *wd = elm_widget_data_get(obj);
3054 elm_smart_scroller_freeze_set(wd->scr, 1);
3058 _freeze_off(void *data __UNUSED__,
3060 void *event_info __UNUSED__)
3062 Widget_Data *wd = elm_widget_data_get(obj);
3064 elm_smart_scroller_freeze_set(wd->scr, 0);
3068 _scr_anim_start(void *data,
3069 Evas_Object *obj __UNUSED__,
3070 void *event_info __UNUSED__)
3072 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3076 _scr_anim_stop(void *data,
3077 Evas_Object *obj __UNUSED__,
3078 void *event_info __UNUSED__)
3080 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3084 _scr_drag_start(void *data,
3085 Evas_Object *obj __UNUSED__,
3086 void *event_info __UNUSED__)
3088 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3092 _scr_drag_stop(void *data,
3093 Evas_Object *obj __UNUSED__,
3094 void *event_info __UNUSED__)
3096 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3100 _edge_left(void *data,
3101 Evas_Object *scr __UNUSED__,
3102 void *event_info __UNUSED__)
3104 Evas_Object *obj = data;
3105 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3109 _edge_right(void *data,
3110 Evas_Object *scr __UNUSED__,
3111 void *event_info __UNUSED__)
3113 Evas_Object *obj = data;
3114 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3118 _edge_top(void *data,
3119 Evas_Object *scr __UNUSED__,
3120 void *event_info __UNUSED__)
3122 Evas_Object *obj = data;
3123 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3127 _edge_bottom(void *data,
3128 Evas_Object *scr __UNUSED__,
3129 void *event_info __UNUSED__)
3131 Evas_Object *obj = data;
3132 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3136 _mode_item_realize(Elm_Gen_Item *it)
3140 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
3142 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3143 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3144 edje_object_scale_set(it->item->mode_view,
3145 elm_widget_scale_get(WIDGET(it)) *
3146 _elm_config->scale);
3147 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
3148 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
3150 strncpy(buf, "item", sizeof(buf));
3151 if (it->wd->compress)
3152 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3154 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3155 strncat(buf, "/", sizeof(buf) - strlen(buf));
3156 strncat(buf, it->itc->mode_item_style, sizeof(buf) - strlen(buf));
3158 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
3159 elm_widget_style_get(WIDGET(it)));
3160 edje_object_mirrored_set(it->item->mode_view,
3161 elm_widget_mirrored_get(WIDGET(it)));
3163 /* signal callback add */
3164 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
3166 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
3168 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
3171 /* text_get, content_get, state_get */
3172 /* FIXME: If you see that assert, please notify us and we
3173 will clean our mess */
3174 assert(eina_list_count(it->item->mode_content_objs) == 0);
3176 _item_text_realize(it, it->item->mode_view, &it->item->mode_texts, NULL);
3177 it->item->mode_content_objs =
3178 _item_content_realize(it, it->item->mode_view,
3179 &it->item->mode_contents, NULL);
3180 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
3182 edje_object_part_swallow(it->item->mode_view,
3183 edje_object_data_get(it->item->mode_view, "mode_part"),
3186 it->want_unrealize = EINA_FALSE;
3187 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3188 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3192 _mode_item_unrealize(Elm_Gen_Item *it)
3194 Widget_Data *wd = it->wd;
3195 Evas_Object *content;
3196 if (!it->item->mode_view) return;
3198 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3199 elm_widget_stringlist_free(it->item->mode_texts);
3200 it->item->mode_texts = NULL;
3201 elm_widget_stringlist_free(it->item->mode_contents);
3202 it->item->mode_contents = NULL;
3203 elm_widget_stringlist_free(it->item->mode_states);
3205 EINA_LIST_FREE(it->item->mode_content_objs, content)
3206 evas_object_del(content);
3208 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
3209 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3210 evas_object_del(it->item->mode_view);
3211 it->item->mode_view = NULL;
3213 if (wd->mode_item == it)
3214 wd->mode_item = NULL;
3215 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3216 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3220 _item_mode_set(Elm_Gen_Item *it)
3223 Widget_Data *wd = it->wd;
3228 it->item->nocache_once = EINA_TRUE;
3230 if (wd->scr_hold_timer)
3232 ecore_timer_del(wd->scr_hold_timer);
3233 wd->scr_hold_timer = NULL;
3235 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3236 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3238 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3239 _mode_item_realize(it);
3240 if (it->item->group_item)
3241 evas_object_raise(it->item->VIEW(group_item));
3242 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
3243 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3244 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3246 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
3247 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3251 _item_mode_unset(Widget_Data *wd)
3254 if (!wd->mode_item) return;
3255 char buf[1024], buf2[1024];
3259 it->item->nocache_once = EINA_TRUE;
3261 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
3262 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
3264 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3265 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
3267 wd->mode_item = NULL;
3271 _edit_mode_item_position(Elm_Gen_Item *it, int itx, int ity)
3273 if ((!it) || (!it->wd->edit_mode)) return;
3274 evas_object_resize(it->edit_obj, it->item->w, it->item->h);
3275 evas_object_move(it->edit_obj, itx, ity);
3279 _edit_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3282 const char *stacking_even;
3283 const char *stacking;
3285 if ((!it) || (it->item->edit_mode_item_realized) ||
3286 (it->generation < it->wd->generation))
3289 it->edit_obj = edje_object_add(evas_object_evas_get(WIDGET(it)));
3290 edje_object_scale_set(it->edit_obj, elm_widget_scale_get(WIDGET(it)) *
3291 _elm_config->scale);
3292 evas_object_smart_member_add(it->edit_obj, it->wd->pan_smart);
3293 elm_widget_sub_object_add(WIDGET(it), it->edit_obj);
3295 if (it->item->type & ELM_GENLIST_ITEM_SUBITEMS)
3296 strncpy(buf, "tree", sizeof(buf));
3297 else strncpy(buf, "item", sizeof(buf));
3298 if (it->wd->compress)
3299 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3301 strncat(buf, "/", sizeof(buf) - strlen(buf));
3302 strncat(buf, it->itc->edit_item_style, sizeof(buf) - strlen(buf));
3304 _elm_theme_object_set(WIDGET(it), it->edit_obj, "genlist", buf,
3305 elm_widget_style_get(WIDGET(it)));
3307 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3308 if (!stacking_even) stacking_even = "above";
3309 it->item->stacking_even = !!strcmp("above", stacking_even);
3311 stacking = edje_object_data_get(VIEW(it), "stacking");
3312 if (!stacking) stacking = "yes";
3313 it->item->nostacking = !!strcmp("yes", stacking);
3315 edje_object_mirrored_set(it->edit_obj,
3316 elm_widget_mirrored_get(WIDGET(it)));
3318 _elm_genlist_item_odd_even_update(it);
3319 _elm_genlist_item_state_update(it, NULL);
3321 if (effect_on) edje_object_signal_emit(it->edit_obj, "elm,state,edit,enabled,effect", "elm");
3322 else edje_object_signal_emit(it->edit_obj, "elm,state,edit,enabled", "elm");
3324 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
3326 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
3328 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
3330 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MULTI_DOWN,
3332 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MULTI_UP,
3334 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MULTI_MOVE,
3337 _item_text_realize(it, it->edit_obj, &it->item->edit_texts, NULL);
3338 if (it->flipped) edje_object_signal_emit(it->edit_obj, "elm,state,flip,enabled", "elm");
3339 it->item->edit_content_objs =
3340 _item_content_realize(it, it->edit_obj, &it->item->edit_contents, NULL);
3341 _item_state_realize(it, it->edit_obj, &it->item->edit_states, NULL);
3342 edje_object_part_swallow(it->edit_obj, "elm.swallow.edit.content", VIEW(it));
3344 _edit_mode_item_position(it, it->item->scrl_x, it->item->scrl_y);
3345 evas_object_show(it->edit_obj);
3347 it->item->edit_mode_item_realized = EINA_TRUE;
3348 it->want_unrealize = EINA_FALSE;
3352 _edit_mode_item_unrealize(Elm_Gen_Item *it)
3355 if ((!it) || (!it->item->edit_mode_item_realized)) return;
3357 edje_object_part_unswallow(it->edit_obj, VIEW(it));
3358 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3359 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3360 _elm_genlist_item_odd_even_update(it);
3361 _elm_genlist_item_state_update(it, NULL);
3363 evas_object_del(it->edit_obj);
3364 it->edit_obj = NULL;
3365 elm_widget_stringlist_free(it->item->edit_texts);
3366 it->item->edit_texts = NULL;
3367 elm_widget_stringlist_free(it->item->edit_contents);
3368 it->item->edit_contents = NULL;
3369 elm_widget_stringlist_free(it->item->edit_states);
3370 it->item->edit_states = NULL;
3371 EINA_LIST_FREE(it->item->edit_content_objs, icon)
3372 evas_object_del(icon);
3373 edje_object_message_signal_process(it->edit_obj);
3375 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
3377 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
3379 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
3381 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MULTI_DOWN,
3383 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MULTI_UP,
3385 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MULTI_MOVE,
3387 it->item->edit_mode_item_realized = EINA_FALSE;
3391 _item_auto_scroll(Widget_Data *wd)
3394 Elm_Gen_Item *tmp_item = NULL;
3396 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3398 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3399 if (!tmp_item) return;
3400 wd->show_item = tmp_item;
3401 wd->bring_in = EINA_TRUE;
3402 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3403 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3405 wd->show_item->item->showme = EINA_TRUE;
3406 wd->auto_scroll_enabled = EINA_FALSE;
3414 elm_genlist_add(Evas_Object *parent)
3419 Evas_Coord minw, minh;
3420 static Evas_Smart *smart = NULL;
3424 static Evas_Smart_Class sc;
3426 evas_object_smart_clipped_smart_set(&_pan_sc);
3428 sc.name = "elm_genlist_pan";
3429 sc.version = EVAS_SMART_CLASS_VERSION;
3432 sc.resize = _pan_resize;
3433 sc.move = _pan_move;
3434 sc.calculate = _pan_calculate;
3435 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3438 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3440 ELM_SET_WIDTYPE(widtype, "genlist");
3442 elm_widget_type_set(obj, "genlist");
3443 elm_widget_sub_object_add(parent, obj);
3444 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3445 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3446 elm_widget_data_set(obj, wd);
3447 elm_widget_del_hook_set(obj, _del_hook);
3448 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3449 elm_widget_theme_hook_set(obj, _theme_hook);
3450 elm_widget_can_focus_set(obj, EINA_TRUE);
3451 elm_widget_event_hook_set(obj, _event_hook);
3452 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3453 elm_widget_translate_hook_set(obj, _translate_hook);
3456 wd->scr = elm_smart_scroller_add(e);
3457 elm_smart_scroller_widget_set(wd->scr, obj);
3458 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3459 elm_widget_style_get(obj));
3460 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3461 _elm_config->thumbscroll_bounce_enable);
3462 elm_widget_resize_object_set(obj, wd->scr);
3464 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3465 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3466 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3467 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3468 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3469 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3470 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3471 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3474 wd->mode = ELM_LIST_SCROLL;
3475 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3476 wd->item_cache_max = wd->max_items_per_block * 2;
3477 wd->longpress_timeout = _elm_config->longpress_timeout;
3479 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3480 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3481 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3482 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3484 wd->pan_smart = evas_object_smart_add(e, smart);
3485 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3488 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3489 _pan_set, _pan_get, _pan_max_get,
3490 _pan_min_get, _pan_child_size_get);
3492 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3494 evas_object_size_hint_min_set(obj, minw, minh);
3496 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3498 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3504 _item_select(Elm_Gen_Item *it)
3506 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3509 it->selected = EINA_TRUE;
3510 it->wd->selected = eina_list_append(it->wd->selected, it);
3512 else if (!it->wd->always_select) return;
3514 evas_object_ref(WIDGET(it));
3517 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3518 if (it->generation == it->wd->generation)
3519 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3522 evas_object_unref(WIDGET(it));
3523 if ((it->wd->clear_me) && (!it->wd->walking))
3524 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3527 if ((!it->walking) && (it->generation < it->wd->generation))
3532 elm_widget_item_free(it);
3536 it->wd->last_selected_item = (Elm_Object_Item *)it;
3540 static Evas_Object *
3541 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3543 return edje_object_part_swallow_get(VIEW(it), part);
3547 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3549 if (content && part)
3551 it->content_objs = eina_list_append(it->content_objs, content);
3552 edje_object_part_swallow(VIEW(it), part, content);
3556 static Evas_Object *
3557 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3560 obj = edje_object_part_swallow_get(VIEW(it), part);
3561 if (!obj) return NULL;
3562 it->content_objs = eina_list_remove(it->content_objs, obj);
3563 edje_object_part_unswallow(VIEW(it), obj);
3568 _item_text_hook(Elm_Gen_Item *it, const char *part)
3570 if (!it->itc->func.text_get) return NULL;
3571 return edje_object_part_text_get(VIEW(it), part);
3575 _item_disable_hook(Elm_Object_Item *it)
3579 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3581 if (_it->generation < _it->wd->generation) return;
3584 elm_genlist_item_selected_set(it, EINA_FALSE);
3588 if (elm_widget_item_disabled_get(it))
3590 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
3592 edje_object_signal_emit(_it->edit_obj, "elm,state,disabled", "elm");
3596 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
3598 edje_object_signal_emit(_it->edit_obj, "elm,state,enabled", "elm");
3600 EINA_LIST_FOREACH(_it->content_objs, l, obj)
3601 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
3606 _item_del_pre_hook(Elm_Object_Item *it)
3608 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3610 if ((_it->relcount > 0) || (_it->walking > 0))
3612 elm_genlist_item_subitems_clear(it);
3613 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
3614 _elm_genlist_item_del_notserious(_it);
3615 if (_it->item->block)
3617 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
3618 _it->item->block->changed = EINA_TRUE;
3619 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
3620 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
3624 _it->parent->item->items =
3625 eina_list_remove(_it->parent->item->items, it);
3635 _elm_genlist_item_new(Widget_Data *wd,
3636 const Elm_Gen_Item_Class *itc,
3638 Elm_Gen_Item *parent,
3640 const void *func_data)
3644 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3645 if (!it) return NULL;
3647 it->generation = wd->generation;
3649 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
3650 it->base.data = data;
3651 it->parent = parent;
3652 it->func.func = func;
3653 it->func.data = func_data;
3654 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3655 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3656 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3657 elm_widget_item_text_get_hook_set(it, _item_text_hook);
3658 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3659 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3661 it->sel_cb = (Ecore_Cb)_item_select;
3666 static Elm_Gen_Item *
3667 _item_new(Widget_Data *wd,
3668 const Elm_Genlist_Item_Class *itc,
3670 Elm_Gen_Item *parent,
3671 Elm_Genlist_Item_Type type,
3673 const void *func_data)
3675 Elm_Gen_Item *it, *it2;
3678 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3679 if (!it) return NULL;
3680 it->item = ELM_NEW(Elm_Gen_Item_Type);
3681 it->item->type = type;
3682 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
3683 it->item->expanded_depth = 0;
3684 ELM_GEN_ITEM_SETUP(it);
3687 if (it->parent->group)
3688 it->item->group_item = parent;
3689 else if (it->parent->item->group_item)
3690 it->item->group_item = it->parent->item->group_item;
3692 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3694 if (!it2->parent->group) depth += 1;
3696 it->item->expanded_depth = depth;
3702 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3706 itb = calloc(1, sizeof(Item_Block));
3707 if (!itb) return NULL;
3711 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3712 _item_block_position_update(wd->blocks, 0);
3716 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3717 itb->position_update = EINA_TRUE;
3718 if (wd->blocks != EINA_INLIST_GET(itb))
3720 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3731 _item_block_add(Widget_Data *wd,
3734 Item_Block *itb = NULL;
3741 itb = calloc(1, sizeof(Item_Block));
3742 if (!itb) return EINA_FALSE;
3744 if (!it->item->rel->item->block)
3747 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3748 itb->items = eina_list_append(itb->items, it);
3749 itb->position_update = EINA_TRUE;
3750 it->position = eina_list_count(itb->items);
3751 it->position_update = EINA_TRUE;
3753 if (wd->blocks != EINA_INLIST_GET(itb))
3755 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3766 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3767 if (it->item->before)
3769 wd->blocks = eina_inlist_prepend_relative
3770 (wd->blocks, EINA_INLIST_GET(itb),
3771 EINA_INLIST_GET(it->item->rel->item->block));
3773 eina_list_prepend_relative_list(itb->items, it, tmp);
3775 /* Update index from where we prepended */
3776 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3777 _item_block_position_update(EINA_INLIST_GET(itb),
3778 it->item->rel->item->block->position);
3782 wd->blocks = eina_inlist_append_relative
3783 (wd->blocks, EINA_INLIST_GET(itb),
3784 EINA_INLIST_GET(it->item->rel->item->block));
3786 eina_list_append_relative_list(itb->items, it, tmp);
3788 /* Update block index from where we appended */
3789 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3790 _item_block_position_update(EINA_INLIST_GET(itb),
3791 it->item->rel->item->block->position + 1);
3797 if (it->item->before)
3801 itb = (Item_Block *)(wd->blocks);
3802 if (itb->count >= wd->max_items_per_block)
3804 itb = _item_block_new(wd, EINA_TRUE);
3805 if (!itb) return EINA_FALSE;
3810 itb = _item_block_new(wd, EINA_TRUE);
3811 if (!itb) return EINA_FALSE;
3813 itb->items = eina_list_prepend(itb->items, it);
3815 _item_position_update(itb->items, 0);
3821 itb = (Item_Block *)(wd->blocks->last);
3822 if (itb->count >= wd->max_items_per_block)
3824 itb = _item_block_new(wd, EINA_FALSE);
3825 if (!itb) return EINA_FALSE;
3830 itb = _item_block_new(wd, EINA_FALSE);
3831 if (!itb) return EINA_FALSE;
3833 itb->items = eina_list_append(itb->items, it);
3834 it->position = eina_list_count(itb->items);
3842 if (it->item->rel->item->queued)
3844 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3845 on sorted insertion order, so the queue is not always ordered like the item list.
3846 This lead to issue where we depend on an item that is not yet created. As a quick
3847 work around, we reschedule the calc of the item and stop reordering the list to
3848 prevent any nasty issue to show up here.
3850 wd->queue = eina_list_append(wd->queue, it);
3851 wd->requeued = EINA_TRUE;
3852 it->item->queued = EINA_TRUE;
3855 itb = it->item->rel->item->block;
3856 if (!itb) goto newblock;
3857 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3858 if (it->item->before)
3860 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3861 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3865 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3866 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3870 itb->changed = EINA_TRUE;
3871 it->item->block = itb;
3872 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3873 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3876 it->item->rel->relcount--;
3877 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3879 _item_del(it->item->rel);
3880 elm_widget_item_free(it->item->rel);
3882 it->item->rel = NULL;
3884 if (itb->count > itb->wd->max_items_per_block)
3889 Eina_Bool done = EINA_FALSE;
3891 newc = itb->count / 2;
3893 if (EINA_INLIST_GET(itb)->prev)
3895 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3897 if (itbp->count + newc < wd->max_items_per_block / 2)
3899 /* moving items to previous block */
3900 while ((itb->count > newc) && (itb->items))
3902 it2 = eina_list_data_get(itb->items);
3903 itb->items = eina_list_remove_list(itb->items, itb->items);
3906 itbp->items = eina_list_append(itbp->items, it2);
3907 it2->item->block = itbp;
3915 if (!done && EINA_INLIST_GET(itb)->next)
3917 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3919 if (itbn->count + newc < wd->max_items_per_block / 2)
3921 /* moving items to next block */
3922 while ((itb->count > newc) && (itb->items))
3926 l = eina_list_last(itb->items);
3927 it2 = eina_list_data_get(l);
3928 itb->items = eina_list_remove_list(itb->items, l);
3931 itbn->items = eina_list_prepend(itbn->items, it2);
3932 it2->item->block = itbn;
3942 /* moving items to new block */
3943 itb2 = calloc(1, sizeof(Item_Block));
3944 if (!itb2) return EINA_FALSE;
3947 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3948 EINA_INLIST_GET(itb));
3949 itb2->changed = EINA_TRUE;
3950 while ((itb->count > newc) && (itb->items))
3954 l = eina_list_last(itb->items);
3956 itb->items = eina_list_remove_list(itb->items, l);
3959 itb2->items = eina_list_prepend(itb2->items, it2);
3960 it2->item->block = itb2;
3970 _queue_process(Widget_Data *wd)
3973 Eina_Bool showme = EINA_FALSE;
3976 t0 = ecore_loop_time_get();
3977 //evas_event_freeze(evas_object_evas_get(wd->obj));
3978 for (n = 0; (wd->queue) && (n < 128); n++)
3982 it = eina_list_data_get(wd->queue);
3983 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3984 it->item->queued = EINA_FALSE;
3985 if (!_item_block_add(wd, it)) continue;
3987 _item_block_realize(it->item->block);
3988 t = ecore_time_get();
3989 if (it->item->block->changed)
3991 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3992 it->item->block->changed = 0;
3993 if (wd->pan_changed)
3995 if (wd->calc_job) ecore_job_del(wd->calc_job);
3996 wd->calc_job = NULL;
3998 wd->pan_changed = EINA_FALSE;
4001 if (showme) it->item->block->showme = EINA_TRUE;
4002 /* same as eina_inlist_count > 1 */
4003 if (wd->blocks && wd->blocks->next)
4005 if ((t - t0) > (ecore_animator_frametime_get())) break;
4008 //evas_event_thaw(evas_object_evas_get(wd->obj));
4009 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4014 _idle_process(void *data, Eina_Bool *wakeup)
4016 Widget_Data *wd = data;
4019 //static double q_start = 0.0;
4020 //if (q_start == 0.0) q_start = ecore_time_get();
4022 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4026 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4028 return ECORE_CALLBACK_CANCEL;
4030 return ECORE_CALLBACK_RENEW;
4034 _item_idle_enterer(void *data)
4036 Widget_Data *wd = data;
4037 Eina_Bool wakeup = EINA_FALSE;
4038 Eina_Bool ok = _idle_process(data, &wakeup);
4043 if (wd->calc_job) ecore_job_del(wd->calc_job);
4044 wd->calc_job = ecore_job_add(_calc_job, wd);
4046 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4051 _item_queue(Widget_Data *wd,
4055 if (it->item->queued) return;
4056 it->item->queued = EINA_TRUE;
4057 if (cb && !wd->requeued)
4058 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4060 wd->queue = eina_list_append(wd->queue, it);
4061 // FIXME: why does a freeze then thaw here cause some genlist
4062 // elm_genlist_item_append() to be much much slower?
4063 // evas_event_freeze(evas_object_evas_get(wd->obj));
4064 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4066 if (wd->queue_idle_enterer)
4068 ecore_idle_enterer_del(wd->queue_idle_enterer);
4069 wd->queue_idle_enterer = NULL;
4073 // evas_event_thaw(evas_object_evas_get(wd->obj));
4074 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4075 if (!wd->queue_idle_enterer)
4076 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4080 _elm_genlist_item_compare(const void *data, const void *data1)
4082 const Elm_Gen_Item *it, *item1;
4083 it = ELM_GEN_ITEM_FROM_INLIST(data);
4084 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4085 return it->wd->item_compare_cb(it, item1);
4089 _elm_genlist_item_list_compare(const void *data, const void *data1)
4091 const Elm_Gen_Item *it = data;
4092 const Elm_Gen_Item *item1 = data1;
4093 return it->wd->item_compare_cb(it, item1);
4097 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4102 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4103 _item_block_del(it);
4105 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4106 it->item->rel = after;
4107 it->item->rel->relcount++;
4108 it->item->before = EINA_FALSE;
4109 if (after->item->group_item) it->item->group_item = after->item->group_item;
4110 _item_queue(it->wd, it, NULL);
4112 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4116 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4119 if (!before) return;
4121 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4122 _item_block_del(it);
4123 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4124 it->item->rel = before;
4125 it->item->rel->relcount++;
4126 it->item->before = EINA_TRUE;
4127 if (before->item->group_item) it->item->group_item = before->item->group_item;
4128 _item_queue(it->wd, it, NULL);
4130 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4134 elm_genlist_items_count(const Evas_Object *obj)
4136 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4137 Widget_Data *wd = elm_widget_data_get(obj);
4139 return wd->item_count;
4142 EAPI Elm_Object_Item *
4143 elm_genlist_item_append(Evas_Object *obj,
4144 const Elm_Genlist_Item_Class *itc,
4146 Elm_Object_Item *parent,
4147 Elm_Genlist_Item_Type type,
4149 const void *func_data)
4151 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4152 Widget_Data *wd = elm_widget_data_get(obj);
4153 if (!wd) return NULL;
4154 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4156 if (!it) return NULL;
4160 wd->group_items = eina_list_append(wd->group_items, it);
4161 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4162 it->item->rel = NULL;
4166 Elm_Gen_Item *it2 = NULL;
4167 Eina_List *ll = eina_list_last(it->parent->item->items);
4168 if (ll) it2 = ll->data;
4169 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4170 if (!it2) it2 = it->parent;
4172 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4173 EINA_INLIST_GET(it2));
4174 it->item->rel = it2;
4175 it->item->rel->relcount++;
4177 it->item->before = EINA_FALSE;
4178 _item_queue(wd, it, NULL);
4179 return (Elm_Object_Item *)it;
4182 EAPI Elm_Object_Item *
4183 elm_genlist_item_prepend(Evas_Object *obj,
4184 const Elm_Genlist_Item_Class *itc,
4186 Elm_Object_Item *parent,
4187 Elm_Genlist_Item_Type type,
4189 const void *func_data)
4191 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4192 Widget_Data *wd = elm_widget_data_get(obj);
4193 if (!wd) return NULL;
4194 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4196 if (!it) return NULL;
4200 wd->group_items = eina_list_prepend(wd->group_items, it);
4201 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4202 it->item->rel = NULL;
4206 Elm_Gen_Item *it2 = NULL;
4207 Eina_List *ll = it->parent->item->items;
4208 if (ll) it2 = ll->data;
4209 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4210 if (!it2) it2 = it->parent;
4212 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4213 EINA_INLIST_GET(it2));
4214 it->item->rel = it2;
4215 it->item->rel->relcount++;
4217 it->item->before = EINA_TRUE;
4218 _item_queue(wd, it, NULL);
4219 return (Elm_Object_Item *)it;
4222 EAPI Elm_Object_Item *
4223 elm_genlist_item_insert_after(Evas_Object *obj,
4224 const Elm_Genlist_Item_Class *itc,
4226 Elm_Object_Item *parent,
4227 Elm_Object_Item *after,
4228 Elm_Genlist_Item_Type type,
4230 const void *func_data)
4232 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4233 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4234 Widget_Data *wd = elm_widget_data_get(obj);
4235 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4236 if (!wd) return NULL;
4237 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4238 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4240 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4242 if (!it) return NULL;
4245 if ((it->group) && (_after->group))
4246 wd->group_items = eina_list_append_relative(wd->group_items, it,
4251 it->parent->item->items =
4252 eina_list_append_relative(it->parent->item->items, it, _after);
4254 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4255 EINA_INLIST_GET(_after));
4256 it->item->rel = _after;
4257 it->item->rel->relcount++;
4258 it->item->before = EINA_FALSE;
4259 _item_queue(wd, it, NULL);
4260 return (Elm_Object_Item *)it;
4263 EAPI Elm_Object_Item *
4264 elm_genlist_item_insert_before(Evas_Object *obj,
4265 const Elm_Genlist_Item_Class *itc,
4267 Elm_Object_Item *parent,
4268 Elm_Object_Item *before,
4269 Elm_Genlist_Item_Type type,
4271 const void *func_data)
4273 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4274 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4275 Widget_Data *wd = elm_widget_data_get(obj);
4276 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4277 if (!wd) return NULL;
4278 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4279 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4281 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4283 if (!it) return NULL;
4286 if (it->group && _before->group)
4287 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4292 it->parent->item->items =
4293 eina_list_prepend_relative(it->parent->item->items, it, _before);
4295 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4296 EINA_INLIST_GET(_before));
4297 it->item->rel = _before;
4298 it->item->rel->relcount++;
4299 it->item->before = EINA_TRUE;
4300 _item_queue(wd, it, NULL);
4301 return (Elm_Object_Item *)it;
4304 EAPI Elm_Object_Item *
4305 elm_genlist_item_sorted_insert(Evas_Object *obj,
4306 const Elm_Genlist_Item_Class *itc,
4308 Elm_Object_Item *parent,
4309 Elm_Genlist_Item_Type type,
4310 Eina_Compare_Cb comp,
4312 const void *func_data)
4314 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4315 Widget_Data *wd = elm_widget_data_get(obj);
4316 if (!wd) return NULL;
4317 Elm_Gen_Item *rel = NULL;
4318 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4320 if (!it) return NULL;
4322 wd->item_compare_cb = comp;
4329 l = eina_list_search_sorted_near_list(it->parent->item->items,
4330 _elm_genlist_item_list_compare,
4334 rel = eina_list_data_get(l);
4338 if (cmp_result >= 0)
4340 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4341 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4342 it->item->before = EINA_FALSE;
4344 else if (cmp_result < 0)
4346 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4347 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4348 it->item->before = EINA_TRUE;
4355 wd->state = eina_inlist_sorted_state_new();
4356 eina_inlist_sorted_state_init(wd->state, wd->items);
4357 wd->requeued = EINA_FALSE;
4361 wd->group_items = eina_list_append(wd->group_items, it);
4363 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4364 _elm_genlist_item_compare, wd->state);
4366 if (EINA_INLIST_GET(it)->next)
4368 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4369 it->item->before = EINA_TRUE;
4371 else if (EINA_INLIST_GET(it)->prev)
4373 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4374 it->item->before = EINA_FALSE;
4380 it->item->rel = rel;
4381 it->item->rel->relcount++;
4384 _item_queue(wd, it, _elm_genlist_item_list_compare);
4386 return (Elm_Object_Item *)it;
4390 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4392 Eina_Inlist *next, *l;
4394 ELM_CHECK_WIDTYPE(obj, widtype);
4395 Widget_Data *wd = elm_widget_data_get(obj);
4398 if (!standby) wd->generation++;
4402 eina_inlist_sorted_state_free(wd->state);
4406 if (wd->walking > 0)
4408 wd->clear_me = EINA_TRUE;
4411 evas_event_freeze(evas_object_evas_get(wd->obj));
4412 for (l = wd->items, next = l ? l->next : NULL;
4414 l = next, next = next ? next->next : NULL)
4416 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4418 if (it->generation < wd->generation)
4420 Elm_Gen_Item *itn = NULL;
4422 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4423 if (itn) itn->walking++; /* prevent early death of subitem */
4425 elm_widget_item_free(it);
4426 if (itn) itn->walking--;
4429 wd->clear_me = EINA_FALSE;
4430 wd->pan_changed = EINA_TRUE;
4433 ecore_job_del(wd->calc_job);
4434 wd->calc_job = NULL;
4436 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4437 if (wd->clear_cb) wd->clear_cb(wd);
4443 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4444 wd->alpha_bg = NULL;
4448 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4449 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4451 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4452 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4453 evas_event_thaw(evas_object_evas_get(wd->obj));
4454 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4458 elm_genlist_clear(Evas_Object *obj)
4460 _elm_genlist_clear(obj, EINA_FALSE);
4464 elm_genlist_multi_select_set(Evas_Object *obj,
4467 ELM_CHECK_WIDTYPE(obj, widtype);
4468 Widget_Data *wd = elm_widget_data_get(obj);
4470 wd->multi = !!multi;
4474 elm_genlist_multi_select_get(const Evas_Object *obj)
4476 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4477 Widget_Data *wd = elm_widget_data_get(obj);
4478 if (!wd) return EINA_FALSE;
4482 EAPI Elm_Object_Item *
4483 elm_genlist_selected_item_get(const Evas_Object *obj)
4485 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4486 Widget_Data *wd = elm_widget_data_get(obj);
4487 if (!wd) return NULL;
4488 if (wd->selected) return wd->selected->data;
4492 EAPI const Eina_List *
4493 elm_genlist_selected_items_get(const Evas_Object *obj)
4495 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4496 Widget_Data *wd = elm_widget_data_get(obj);
4497 if (!wd) return NULL;
4498 return wd->selected;
4502 elm_genlist_realized_items_get(const Evas_Object *obj)
4504 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4505 Widget_Data *wd = elm_widget_data_get(obj);
4506 Eina_List *list = NULL;
4508 Eina_Bool done = EINA_FALSE;
4509 if (!wd) return NULL;
4510 EINA_INLIST_FOREACH(wd->blocks, itb)
4518 EINA_LIST_FOREACH(itb->items, l, it)
4520 if (it->realized) list = eina_list_append(list, it);
4531 EAPI Elm_Object_Item *
4532 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4537 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4538 Widget_Data *wd = elm_widget_data_get(obj);
4539 Evas_Coord ox, oy, ow, oh;
4542 if (!wd) return NULL;
4543 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4545 EINA_INLIST_FOREACH(wd->blocks, itb)
4550 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4551 oy + itb->y - itb->wd->pan_y,
4552 itb->w, itb->h, x, y, 1, 1))
4554 EINA_LIST_FOREACH(itb->items, l, it)
4556 Evas_Coord itx, ity;
4558 itx = ox + itb->x + it->x - itb->wd->pan_x;
4559 ity = oy + itb->y + it->y - itb->wd->pan_y;
4560 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4564 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4565 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4569 return (Elm_Object_Item *)it;
4571 lasty = ity + it->item->h;
4576 if (y > lasty) *posret = 1;
4582 EAPI Elm_Object_Item *
4583 elm_genlist_first_item_get(const Evas_Object *obj)
4585 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4586 Widget_Data *wd = elm_widget_data_get(obj);
4587 if (!wd) return NULL;
4588 if (!wd->items) return NULL;
4589 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4590 while ((it) && (it->generation < wd->generation))
4591 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4592 return (Elm_Object_Item *)it;
4595 EAPI Elm_Object_Item *
4596 elm_genlist_last_item_get(const Evas_Object *obj)
4598 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4599 Widget_Data *wd = elm_widget_data_get(obj);
4600 if (!wd) return NULL;
4601 if (!wd->items) return NULL;
4602 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4603 while ((it) && (it->generation < wd->generation))
4604 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4605 return (Elm_Object_Item *)it;
4608 EAPI Elm_Object_Item *
4609 elm_genlist_item_next_get(const Elm_Object_Item *it)
4611 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4612 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4615 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
4616 if ((_it) && (_it->generation == _it->wd->generation)) break;
4618 return (Elm_Object_Item *) _it;
4621 EAPI Elm_Object_Item *
4622 elm_genlist_item_prev_get(const Elm_Object_Item *it)
4624 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4625 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4628 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
4629 if ((_it) && (_it->generation == _it->wd->generation)) break;
4631 return (Elm_Object_Item *) _it;
4634 EAPI Elm_Object_Item *
4635 elm_genlist_item_parent_get(const Elm_Object_Item *it)
4637 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4638 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
4642 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
4644 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4645 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
4647 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4649 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
4650 _item_subitems_clear(_it);
4653 if (!wd->item_moving_effect_timer)
4655 wd->expanded_item = _it;
4656 _item_tree_effect_before(_it);
4657 evas_object_raise(wd->alpha_bg);
4658 evas_object_show(wd->alpha_bg);
4659 wd->start_time = ecore_time_get();
4660 wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, wd);
4663 _item_subitems_clear(_it);
4668 elm_genlist_item_selected_set(Elm_Object_Item *it,
4671 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4672 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4673 Widget_Data *wd = _it->wd;
4675 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
4677 selected = !!selected;
4678 if (_it->selected == selected) return;
4684 while (wd->selected)
4686 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
4687 _it->unsel_cb(wd->selected->data);
4690 _it->highlight_cb(_it);
4694 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
4699 elm_genlist_item_selected_get(const Elm_Object_Item *it)
4701 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4702 return ((Elm_Gen_Item *)it)->selected;
4706 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
4709 if (it->item->expanded)
4711 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4715 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4718 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
4719 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4726 _elm_genlist_move_items_set(Elm_Gen_Item *it)
4729 Elm_Gen_Item *it2 = NULL;
4730 Evas_Coord ox, oy, ow, oh, dh = 0;
4732 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
4734 if (it->item->expanded)
4736 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
4737 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
4739 if (it2 == it->wd->expanded_next_item) break;
4740 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
4745 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
4746 it2 = it->wd->expanded_next_item;
4747 while (it2 && (dh < oy + oh))
4750 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
4751 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4757 elm_genlist_item_expanded_set(Elm_Object_Item *it,
4760 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4761 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4762 expanded = !!expanded;
4763 if (_it->item->expanded == expanded) return;
4764 _it->item->expanded = expanded;
4765 _it->wd->expanded_item = _it;
4766 _elm_genlist_move_items_set(_it);
4768 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
4769 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
4771 if (_it->item->expanded)
4773 _it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND;
4775 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
4776 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
4777 _it->wd->auto_scroll_enabled = EINA_TRUE;
4781 _it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT;
4783 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
4784 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
4785 _it->wd->auto_scroll_enabled = EINA_FALSE;
4790 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
4792 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4793 return ((Elm_Gen_Item *)it)->item->expanded;
4797 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
4799 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
4800 return ((Elm_Gen_Item *)it)->item->expanded_depth;
4804 elm_genlist_item_display_only_set(Elm_Object_Item *it,
4805 Eina_Bool display_only)
4807 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4808 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4809 display_only = !!display_only;
4810 if (_it->display_only == display_only) return;
4811 if (_it->generation < _it->wd->generation) return;
4812 _it->display_only = display_only;
4813 _it->item->mincalcd = EINA_FALSE;
4814 _it->item->updateme = EINA_TRUE;
4815 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
4816 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
4817 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
4821 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
4823 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4824 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4825 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4826 return _it->display_only;
4829 static Eina_Bool _elm_genlist_item_compute_coordinates(
4830 Elm_Object_Item *it,
4831 Elm_Genlist_Item_Scrollto_Type type,
4837 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4838 Evas_Coord gith = 0;
4839 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4840 if ((_it->item->queued) || (!_it->item->mincalcd))
4842 _it->wd->show_item = _it;
4843 _it->wd->bring_in = EINA_FALSE;
4844 _it->wd->scrollto_type = type;
4845 _it->item->showme = EINA_TRUE;
4848 if (_it->wd->show_item)
4850 _it->wd->show_item->item->showme = EINA_FALSE;
4851 _it->wd->show_item = NULL;
4854 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
4855 if (type==ELM_GENLIST_ITEM_SCROLLTO_IN)
4857 if ((_it->item->group_item) &&
4858 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4859 gith = _it->item->group_item->item->h;
4862 *y = _it->y + _it->item->block->y - gith;
4864 else if (type==ELM_GENLIST_ITEM_SCROLLTO_TOP)
4866 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4867 *y = _it->y + _it->item->block->y - gith;
4869 else if (type==ELM_GENLIST_ITEM_SCROLLTO_MIDDLE)
4871 *y = _it->y + _it->item->block->y - *h / 2 + _it->item->h / 2;
4876 *x = _it->x + _it->item->block->x;
4877 *w = _it->item->block->w;
4882 elm_genlist_item_promote(Elm_Object_Item *it)
4884 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4885 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4886 if (_it->generation < _it->wd->generation) return;
4887 _item_move_before(_it,
4888 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
4892 elm_genlist_item_demote(Elm_Object_Item *it)
4894 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4895 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4896 if (_it->generation < _it->wd->generation) return;
4897 _item_move_after(_it,
4898 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
4902 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4904 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4905 Evas_Coord x, y, w, h;
4906 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4908 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
4909 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
4913 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4916 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4917 Evas_Coord x, y, w, h;
4918 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4920 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
4921 elm_smart_scroller_region_bring_in(_it->wd->scr,x, y, w, h);
4924 EINA_DEPRECATED EAPI void
4925 elm_genlist_item_top_show(Elm_Object_Item *it)
4927 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
4930 EINA_DEPRECATED EAPI void
4931 elm_genlist_item_top_bring_in(Elm_Object_Item *it)
4933 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
4936 EINA_DEPRECATED EAPI void
4937 elm_genlist_item_middle_show(Elm_Object_Item *it)
4939 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
4942 EINA_DEPRECATED EAPI void
4943 elm_genlist_item_middle_bring_in(Elm_Object_Item *it)
4945 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
4948 EINA_DEPRECATED EAPI void
4949 elm_genlist_item_contents_orphan(Elm_Object_Item *it)
4951 elm_genlist_item_all_contents_unset(it, NULL);
4955 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
4957 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4959 Evas_Object *content;
4960 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
4962 elm_widget_sub_object_del(WIDGET(it), content);
4963 evas_object_smart_member_del(content);
4964 evas_object_hide(content);
4966 *l = eina_list_append(*l, content);
4970 EINA_DEPRECATED EAPI const Evas_Object *
4971 elm_genlist_item_object_get(const Elm_Object_Item *it)
4973 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4978 elm_genlist_item_update(Elm_Object_Item *it)
4980 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4981 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4983 if (!_it->item->block) return;
4984 if (_it->generation < _it->wd->generation) return;
4985 _it->item->mincalcd = EINA_FALSE;
4986 _it->item->updateme = EINA_TRUE;
4987 _it->item->block->updateme = EINA_TRUE;
4988 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
4989 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
4993 elm_genlist_item_fields_update(Elm_Object_Item *it,
4995 Elm_Genlist_Item_Field_Type itf)
4997 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4998 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5000 if (!_it->item->block) return;
5001 if (_it->generation < _it->wd->generation) return;
5003 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5004 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5005 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5007 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5008 &_it->contents, parts);
5009 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5010 &_it->contents, parts);
5012 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5013 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5017 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5018 const Elm_Genlist_Item_Class *itc)
5020 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5021 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5023 if (!_it->item->block) return;
5024 EINA_SAFETY_ON_NULL_RETURN(itc);
5025 if (_it->generation < _it->wd->generation) return;
5027 _it->item->nocache_once = EINA_TRUE;
5028 elm_genlist_item_update(it);
5031 EAPI const Elm_Genlist_Item_Class *
5032 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5034 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5035 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5036 if (_it->generation < _it->wd->generation) return NULL;
5040 static Evas_Object *
5041 _elm_genlist_item_label_create(void *data,
5042 Evas_Object *obj __UNUSED__,
5043 Evas_Object *tooltip,
5044 void *it __UNUSED__)
5046 Evas_Object *label = elm_label_add(tooltip);
5049 elm_object_style_set(label, "tooltip");
5050 elm_object_text_set(label, data);
5055 _elm_genlist_item_label_del_cb(void *data,
5056 Evas_Object *obj __UNUSED__,
5057 void *event_info __UNUSED__)
5059 eina_stringshare_del(data);
5063 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5066 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5067 text = eina_stringshare_add(text);
5068 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5070 _elm_genlist_item_label_del_cb);
5074 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5075 Elm_Tooltip_Item_Content_Cb func,
5077 Evas_Smart_Cb del_cb)
5079 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5080 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5082 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5085 if (_it->tooltip.del_cb)
5086 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5088 _it->tooltip.content_cb = func;
5089 _it->tooltip.data = data;
5090 _it->tooltip.del_cb = del_cb;
5094 elm_widget_item_tooltip_content_cb_set(_it,
5095 _it->tooltip.content_cb,
5096 _it->tooltip.data, NULL);
5097 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5098 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5104 if (del_cb) del_cb((void *)data, NULL, NULL);
5108 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5110 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5111 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5113 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5114 elm_widget_item_tooltip_unset(_it);
5116 if (_it->tooltip.del_cb)
5117 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5118 _it->tooltip.del_cb = NULL;
5119 _it->tooltip.content_cb = NULL;
5120 _it->tooltip.data = NULL;
5121 _it->tooltip.free_size = EINA_FALSE;
5122 if (_it->tooltip.style)
5123 elm_genlist_item_tooltip_style_set(it, NULL);
5127 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5130 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5131 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5133 eina_stringshare_replace(&_it->tooltip.style, style);
5134 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5138 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5140 return elm_object_item_tooltip_style_get(it);
5144 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5147 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5148 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5150 _it->tooltip.free_size = disable;
5151 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5156 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5158 return elm_object_tooltip_window_mode_get(VIEW(it));
5162 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5165 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5166 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5167 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5168 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5172 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5174 return elm_widget_item_cursor_get(it);
5178 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5180 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5181 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5183 if (!_it->mouse_cursor) return;
5185 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5187 eina_stringshare_del(_it->mouse_cursor);
5188 _it->mouse_cursor = NULL;
5192 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5195 elm_widget_item_cursor_style_set(it, style);
5199 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5201 return elm_widget_item_cursor_style_get(it);
5205 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5206 Eina_Bool engine_only)
5208 elm_widget_item_cursor_engine_only_set(it, engine_only);
5212 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5214 return elm_widget_item_cursor_engine_only_get(it);
5218 elm_genlist_item_index_get(const Elm_Object_Item *it)
5220 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5221 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5223 if (_it->item->block)
5224 return _it->position + _it->item->block->position;
5229 elm_genlist_mode_set(Evas_Object *obj,
5232 ELM_CHECK_WIDTYPE(obj, widtype);
5233 Widget_Data *wd = elm_widget_data_get(obj);
5235 if (wd->mode == mode) return;
5242 elm_genlist_mode_get(const Evas_Object *obj)
5244 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5245 Widget_Data *wd = elm_widget_data_get(obj);
5246 if (!wd) return ELM_LIST_LAST;
5251 elm_genlist_always_select_mode_set(Evas_Object *obj,
5252 Eina_Bool always_select)
5254 ELM_CHECK_WIDTYPE(obj, widtype);
5255 Widget_Data *wd = elm_widget_data_get(obj);
5257 wd->always_select = !!always_select;
5261 elm_genlist_always_select_mode_get(const Evas_Object *obj)
5263 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5264 Widget_Data *wd = elm_widget_data_get(obj);
5265 if (!wd) return EINA_FALSE;
5266 return wd->always_select;
5270 elm_genlist_no_select_mode_set(Evas_Object *obj,
5271 Eina_Bool no_select)
5273 ELM_CHECK_WIDTYPE(obj, widtype);
5274 Widget_Data *wd = elm_widget_data_get(obj);
5276 wd->no_select = !!no_select;
5280 elm_genlist_no_select_mode_get(const Evas_Object *obj)
5282 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5283 Widget_Data *wd = elm_widget_data_get(obj);
5284 if (!wd) return EINA_FALSE;
5285 return wd->no_select;
5289 elm_genlist_compress_mode_set(Evas_Object *obj,
5292 ELM_CHECK_WIDTYPE(obj, widtype);
5293 Widget_Data *wd = elm_widget_data_get(obj);
5295 wd->compress = !!compress;
5296 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
5300 elm_genlist_compress_mode_get(const Evas_Object *obj)
5302 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5303 Widget_Data *wd = elm_widget_data_get(obj);
5304 if (!wd) return EINA_FALSE;
5305 return wd->compress;
5309 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
5310 Eina_Bool height_for_width)
5312 ELM_CHECK_WIDTYPE(obj, widtype);
5313 Widget_Data *wd = elm_widget_data_get(obj);
5315 wd->height_for_width = !!height_for_width;
5316 if (wd->height_for_width)
5318 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5319 elm_genlist_compress_mode_set(obj, EINA_TRUE);
5324 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
5326 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5327 Widget_Data *wd = elm_widget_data_get(obj);
5328 if (!wd) return EINA_FALSE;
5329 return wd->height_for_width;
5333 elm_genlist_bounce_set(Evas_Object *obj,
5337 ELM_CHECK_WIDTYPE(obj, widtype);
5338 Widget_Data *wd = elm_widget_data_get(obj);
5340 wd->h_bounce = !!h_bounce;
5341 wd->v_bounce = !!v_bounce;
5342 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5346 elm_genlist_bounce_get(const Evas_Object *obj,
5347 Eina_Bool *h_bounce,
5348 Eina_Bool *v_bounce)
5350 ELM_CHECK_WIDTYPE(obj, widtype);
5351 Widget_Data *wd = elm_widget_data_get(obj);
5353 if (h_bounce) *h_bounce = wd->h_bounce;
5354 if (v_bounce) *v_bounce = wd->v_bounce;
5358 elm_genlist_homogeneous_set(Evas_Object *obj,
5359 Eina_Bool homogeneous)
5361 ELM_CHECK_WIDTYPE(obj, widtype);
5362 Widget_Data *wd = elm_widget_data_get(obj);
5364 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
5365 wd->homogeneous = !!homogeneous;
5369 elm_genlist_homogeneous_get(const Evas_Object *obj)
5371 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5372 Widget_Data *wd = elm_widget_data_get(obj);
5373 if (!wd) return EINA_FALSE;
5374 return wd->homogeneous;
5378 elm_genlist_block_count_set(Evas_Object *obj,
5381 ELM_CHECK_WIDTYPE(obj, widtype);
5382 Widget_Data *wd = elm_widget_data_get(obj);
5384 wd->max_items_per_block = count;
5385 wd->item_cache_max = wd->max_items_per_block * 2;
5386 _item_cache_clean(wd);
5390 elm_genlist_block_count_get(const Evas_Object *obj)
5392 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5393 Widget_Data *wd = elm_widget_data_get(obj);
5395 return wd->max_items_per_block;
5399 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5402 ELM_CHECK_WIDTYPE(obj, widtype);
5403 Widget_Data *wd = elm_widget_data_get(obj);
5405 wd->longpress_timeout = timeout;
5409 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5411 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5412 Widget_Data *wd = elm_widget_data_get(obj);
5414 return wd->longpress_timeout;
5418 elm_genlist_scroller_policy_set(Evas_Object *obj,
5419 Elm_Scroller_Policy policy_h,
5420 Elm_Scroller_Policy policy_v)
5422 ELM_CHECK_WIDTYPE(obj, widtype);
5423 Widget_Data *wd = elm_widget_data_get(obj);
5424 if ((!wd) || (!wd->scr)) return;
5425 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5426 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5428 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5432 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5433 Elm_Scroller_Policy *policy_h,
5434 Elm_Scroller_Policy *policy_v)
5436 ELM_CHECK_WIDTYPE(obj, widtype);
5437 Widget_Data *wd = elm_widget_data_get(obj);
5438 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5439 if ((!wd) || (!wd->scr)) return;
5440 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5441 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5442 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5446 elm_genlist_realized_items_update(Evas_Object *obj)
5448 ELM_CHECK_WIDTYPE(obj, widtype);
5450 Eina_List *list, *l;
5451 Elm_Object_Item *it;
5453 list = elm_genlist_realized_items_get(obj);
5454 EINA_LIST_FOREACH(list, l, it)
5455 elm_genlist_item_update(it);
5459 elm_genlist_item_mode_set(Elm_Object_Item *it,
5460 const char *mode_type,
5463 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5464 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5466 Widget_Data *wd = _it->wd;
5468 Elm_Object_Item *it2;
5471 if (!mode_type) return;
5472 if ((_it->generation < _it->wd->generation) ||
5473 elm_widget_item_disabled_get(_it)) return;
5474 if (wd->edit_mode) return;
5476 if ((wd->mode_item == _it) &&
5477 (!strcmp(mode_type, wd->mode_type)) &&
5480 if (!_it->itc->mode_item_style) return;
5481 _it->mode_set = mode_set;
5485 EINA_LIST_FOREACH(wd->selected, l, it2)
5486 if (((Elm_Gen_Item *)it2)->realized)
5487 elm_genlist_item_selected_set(it2, EINA_FALSE);
5491 it2 = elm_genlist_selected_item_get(wd->obj);
5492 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5493 elm_genlist_item_selected_set(it2, EINA_FALSE);
5496 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
5498 ((_it == wd->mode_item) && (!mode_set)))
5499 _item_mode_unset(wd);
5501 eina_stringshare_replace(&wd->mode_type, mode_type);
5502 if (mode_set) _item_mode_set(_it);
5506 elm_genlist_mode_type_get(const Evas_Object *obj)
5508 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5509 Widget_Data *wd = elm_widget_data_get(obj);
5510 if (!wd) return NULL;
5511 return wd->mode_type;
5514 EAPI const Elm_Object_Item *
5515 elm_genlist_mode_item_get(const Evas_Object *obj)
5517 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5518 Widget_Data *wd = elm_widget_data_get(obj);
5519 if (!wd) return NULL;
5520 return (Elm_Object_Item *) wd->mode_item;
5524 elm_genlist_edit_mode_get(const Evas_Object *obj)
5526 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5527 Widget_Data *wd = elm_widget_data_get(obj);
5528 if (!wd) return EINA_FALSE;
5530 return wd->edit_mode;
5534 elm_genlist_edit_mode_set(Evas_Object *obj, Eina_Bool edit_mode)
5536 ELM_CHECK_WIDTYPE(obj, widtype);
5537 Eina_List *list, *l;
5540 Widget_Data *wd = elm_widget_data_get(obj);
5542 edit_mode = !!edit_mode;
5543 if (wd->edit_mode == edit_mode) return;
5544 wd->edit_mode = edit_mode;
5546 list = elm_genlist_realized_items_get(obj);
5549 EINA_LIST_FOREACH(list, l, it)
5551 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5552 _edit_mode_item_unrealize(it);
5554 _item_cache_zero(wd);
5558 EINA_LIST_FOREACH(list, l, it)
5560 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5562 if (it->selected) _item_unselect(it);
5563 if (it->itc->edit_item_style)
5564 _edit_mode_item_realize(it, EINA_TRUE);
5568 if (wd->calc_job) ecore_job_del(wd->calc_job);
5569 wd->calc_job = ecore_job_add(_calc_job, wd);
5573 elm_genlist_reorder_mode_set(Evas_Object *obj,
5574 Eina_Bool reorder_mode)
5576 ELM_CHECK_WIDTYPE(obj, widtype);
5577 Widget_Data *wd = elm_widget_data_get(obj);
5579 wd->reorder_mode = !!reorder_mode;
5583 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5585 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5586 Widget_Data *wd = elm_widget_data_get(obj);
5587 if (!wd) return EINA_FALSE;
5588 return wd->reorder_mode;
5591 EAPI Elm_Genlist_Item_Type
5592 elm_genlist_item_type_get(const Elm_Object_Item *it)
5594 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5595 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5596 return _it->item->type;
5599 EINA_DEPRECATED EAPI Elm_Genlist_Item_Type
5600 elm_genlist_item_flags_get(const Elm_Object_Item *it)
5602 return elm_genlist_item_type_get(it);
5605 EAPI Elm_Genlist_Item_Class *
5606 elm_genlist_item_class_new(void)
5608 Elm_Genlist_Item_Class *itc;
5610 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5613 itc->version = CLASS_ALLOCATED;
5615 itc->delete_me = EINA_FALSE;
5621 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5623 if (itc && (itc->version == CLASS_ALLOCATED))
5625 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5626 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5636 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5638 if (itc && (itc->version == CLASS_ALLOCATED))
5641 if (itc->refcount == 0) itc->refcount--;
5646 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5648 if (itc && (itc->version == CLASS_ALLOCATED))
5650 if (itc->refcount > 0) itc->refcount--;
5651 if (itc->delete_me && (!itc->refcount))
5652 elm_genlist_item_class_free(itc);
5656 void _flip_job(void *data)
5658 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
5659 _elm_genlist_item_unrealize(it, EINA_FALSE);
5660 if (it->selected) _item_unselect(it);
5661 it->flipped = EINA_TRUE;
5662 it->item->nocache = EINA_TRUE;
5666 elm_genlist_item_flip_set(Elm_Object_Item *it,
5669 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5670 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5673 if (_it->flipped == flip) return;
5677 ecore_job_add(_flip_job, _it);
5678 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
5679 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
5683 _it->flipped = flip;
5684 _item_cache_zero(_it->wd);
5685 elm_genlist_item_update(it);
5686 _it->item->nocache = EINA_FALSE;
5691 elm_genlist_item_flip_get(const Elm_Object_Item *it)
5693 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5694 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5695 return _it->flipped;
5698 /* for gengrid as of now */
5700 _elm_genlist_page_relative_set(Evas_Object *obj,
5704 Evas_Coord pagesize_h;
5705 Evas_Coord pagesize_v;
5707 ELM_CHECK_WIDTYPE(obj, widtype);
5708 Widget_Data *wd = elm_widget_data_get(obj);
5711 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5712 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5716 /* for gengrid as of now */
5718 _elm_genlist_page_relative_get(const Evas_Object *obj,
5722 ELM_CHECK_WIDTYPE(obj, widtype);
5723 Widget_Data *wd = elm_widget_data_get(obj);
5726 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5729 /* for gengrid as of now */
5731 _elm_genlist_page_size_set(Evas_Object *obj,
5732 Evas_Coord h_pagesize,
5733 Evas_Coord v_pagesize)
5738 ELM_CHECK_WIDTYPE(obj, widtype);
5739 Widget_Data *wd = elm_widget_data_get(obj);
5741 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5742 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5746 /* for gengrid as of now */
5748 _elm_genlist_current_page_get(const Evas_Object *obj,
5752 ELM_CHECK_WIDTYPE(obj, widtype);
5753 Widget_Data *wd = elm_widget_data_get(obj);
5755 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5758 /* for gengrid as of now */
5760 _elm_genlist_last_page_get(const Evas_Object *obj,
5764 ELM_CHECK_WIDTYPE(obj, widtype);
5765 Widget_Data *wd = elm_widget_data_get(obj);
5767 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5770 /* for gengrid as of now */
5772 _elm_genlist_page_show(const Evas_Object *obj,
5776 ELM_CHECK_WIDTYPE(obj, widtype);
5777 Widget_Data *wd = elm_widget_data_get(obj);
5779 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5782 /* for gengrid as of now */
5784 _elm_genlist_page_bring_in(const Evas_Object *obj,
5788 ELM_CHECK_WIDTYPE(obj, widtype);
5789 Widget_Data *wd = elm_widget_data_get(obj);
5791 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5795 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5798 Evas_Object *content;
5800 if (!it->realized) return;
5801 if (it->wd->reorder_it == it) return;
5803 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5805 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5808 ecore_timer_del(it->long_timer);
5809 it->long_timer = NULL;
5812 elm_widget_stringlist_free(it->texts);
5814 elm_widget_stringlist_free(it->contents);
5815 it->contents = NULL;
5816 elm_widget_stringlist_free(it->states);
5819 EINA_LIST_FREE(it->content_objs, content)
5820 evas_object_del(content);
5822 it->unrealize_cb(it);
5824 it->realized = EINA_FALSE;
5825 it->want_unrealize = EINA_FALSE;
5826 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5827 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5831 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5833 elm_widget_item_pre_notify_del(it);
5834 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5835 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5837 if (it->itc->func.del)
5838 it->itc->func.del((void *)it->base.data, WIDGET(it));
5842 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5844 _elm_genlist_item_del_notserious(it);
5845 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5846 if (it->tooltip.del_cb)
5847 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5848 it->wd->walking -= it->walking;
5849 if (it->long_timer) ecore_timer_del(it->long_timer);
5851 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5855 eina_inlist_sorted_state_free(it->wd->state);
5856 it->wd->state = NULL;
5858 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5859 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5863 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
5864 it->wd->last_selected_item = NULL;
5865 it->wd->item_count--;
5869 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
5871 ELM_CHECK_WIDTYPE(obj, widtype);
5872 Widget_Data *wd = elm_widget_data_get(obj);
5874 wd->tree_effect_enabled = !!enabled;
5878 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
5880 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5881 Widget_Data *wd = elm_widget_data_get(obj);
5882 if (!wd) return EINA_FALSE;
5883 return wd->tree_effect_enabled;
5887 _create_tray_alpha_bg(const Evas_Object *obj)
5889 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5890 Widget_Data *wd = elm_widget_data_get(obj);
5891 if (!wd) return NULL;
5893 Evas_Object *bg = NULL;
5894 Evas_Coord ox, oy, ow, oh;
5896 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5897 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
5898 evas_object_color_set(bg,0,0,0,0);
5899 evas_object_resize(bg , ow, oh);
5900 evas_object_move(bg , ox, oy);
5905 _item_contract_emit(Elm_Gen_Item *it)
5910 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
5911 it->item->tree_effect_finished = EINA_FALSE;
5913 EINA_LIST_FOREACH(it->item->items, l, it2)
5914 if (it2) _item_contract_emit(it2);
5918 _item_tree_effect_before(Elm_Gen_Item *it)
5923 EINA_LIST_FOREACH(it->item->items, l, it2)
5925 if (it2->parent && (it == it2->parent))
5927 if (it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
5928 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
5929 else if (it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
5930 _item_contract_emit(it2);
5933 return ECORE_CALLBACK_CANCEL;
5937 _item_tree_effect(Widget_Data *wd, int y)
5939 Elm_Gen_Item *it = NULL, *expanded_next_it;
5941 expanded_next_it = wd->expanded_next_item;
5943 if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
5945 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
5948 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
5949 if (it->item->scrl_y && (it->item->scrl_y < expanded_next_it->item->old_scrl_y + y) &&
5950 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
5952 if (!it->item->tree_effect_finished)
5954 edje_object_signal_emit(VIEW(it), "flip_item", "");
5955 evas_object_show(VIEW(it));
5956 it->item->tree_effect_finished = EINA_TRUE;
5959 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
5962 else if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
5964 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
5967 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
5968 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
5970 if (!it->item->tree_effect_finished)
5972 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
5973 it->item->tree_effect_finished = EINA_TRUE;
5978 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
5984 _item_tree_effect_finish(Widget_Data *wd)
5987 Elm_Gen_Item *it = NULL;
5990 if (wd->item_moving_effect_timer)
5992 if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
5993 _item_subitems_clear(wd->expanded_item);
5994 EINA_INLIST_FOREACH(wd->blocks, itb)
5996 EINA_LIST_FOREACH(itb->items, l, it)
5998 it->item->tree_effect_finished = EINA_TRUE;
5999 it->item->old_scrl_y = it->item->scrl_y;
6003 _item_auto_scroll(wd);
6004 evas_object_lower(wd->alpha_bg);
6005 evas_object_hide(wd->alpha_bg);
6006 wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
6007 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6009 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6010 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6011 evas_object_smart_changed(wd->pan_smart);
6013 wd->item_moving_effect_timer = NULL;
6017 _item_moving_effect_timer_cb(void *data)
6019 Widget_Data *wd = data;
6020 if (!wd) return EINA_FALSE;
6021 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6022 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6024 double effect_duration = 0.5, t;
6025 int y = 0, dy = 0, dh = 0;
6026 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6029 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6030 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6031 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6032 if (t > effect_duration) end = EINA_TRUE;
6034 // Below while statement is needed, when the genlist is resized.
6035 it2 = wd->expanded_item;
6038 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6039 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6040 cvx, cvy, cvw, cvh));
6041 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6044 if (wd->expanded_next_item)
6046 expanded_next_it = wd->expanded_next_item;
6049 EINA_LIST_FOREACH(wd->move_items, l, it)
6051 if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
6053 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6054 if (expanded_next_it->item->scrl_y < expanded_next_it->item->old_scrl_y) //did not calculate next item position
6055 expanded_next_it->item->scrl_y = cvy + cvh;
6057 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6058 cvy + cvh : expanded_next_it->item->scrl_y) -
6059 expanded_next_it->item->old_scrl_y;
6061 else if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
6063 if (expanded_next_it->item->scrl_y > expanded_next_it->item->old_scrl_y) //did not calculate next item position
6064 expanded_next_it->item->old_scrl_y = cvy + cvh;
6066 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6068 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6070 expanded_next_it->item->old_scrl_y = cvy + cvh;
6074 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6075 expanded_next_it->item->old_scrl_y;
6079 if (t <= effect_duration)
6081 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6091 _item_realize(it, in, 0);
6095 if (it != expanded_next_it)
6097 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6101 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6102 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6105 _item_tree_effect(wd, y);
6109 int expanded_item_num = 0;
6112 if (wd->expanded_item)
6113 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6118 expanded_item_num++;
6119 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6125 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6126 if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
6128 if (!it->item->tree_effect_finished)
6130 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6132 edje_object_signal_emit(VIEW(it), "flip_item", "");
6133 evas_object_show(VIEW(it));
6134 it->item->tree_effect_finished = EINA_TRUE;
6138 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6144 _item_tree_effect_finish(wd);
6145 return ECORE_CALLBACK_CANCEL;
6147 return ECORE_CALLBACK_RENEW;