3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.h"
9 // internally allocated
10 #define CLASS_ALLOCATED 0x3a70f11f
12 #define MAX_ITEMS_PER_BLOCK 32
13 #define REORDER_EFFECT_TIME 0.5
15 #define ELM_GEN_SETUP(wd) \
16 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
17 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
18 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
32 ERR("Genlist_Item_Class(itc) is NULL"); \
35 if ((itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) && \
36 (itc->version != CLASS_ALLOCATED)) \
38 ERR("Genlist_Item_Class version mismatched! current = (%d), required = (%d) or (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION, CLASS_ALLOCATED); \
44 typedef struct _Item_Block Item_Block;
45 typedef struct _Item_Cache Item_Cache;
47 struct Elm_Gen_Item_Type
52 Evas_Coord w, h, minw, minh;
53 Elm_Gen_Item *group_item;
54 Elm_Genlist_Item_Type type;
55 Eina_List *deco_it_texts, *deco_it_contents, *deco_it_states, *deco_it_content_objs;
56 Eina_List *deco_all_texts, *deco_all_contents, *deco_all_states, *deco_all_content_objs;
57 Eina_List *flip_contents, *flip_content_objs;
58 Ecore_Timer *swipe_timer;
59 Evas_Coord scrl_x, scrl_y, old_scrl_y;
62 Evas_Object *deco_it_view;
68 Eina_Bool want_realize : 1;
69 Eina_Bool expanded : 1;
70 Eina_Bool mincalcd : 1;
73 Eina_Bool updateme : 1;
74 Eina_Bool nocache : 1; /* do not use cache for this item */
75 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
76 Eina_Bool stacking_even : 1;
77 Eina_Bool nostacking : 1;
78 Eina_Bool move_effect_enabled : 1;
79 Eina_Bool decorate_all_item_realized : 1;
80 Eina_Bool tree_effect_finished : 1; /* tree effect */
81 Eina_Bool tree_effect_hideme : 1; /* item hide for tree effect */
92 Evas_Coord x, y, w, h, minw, minh;
94 int item_position_stamp;
96 Eina_Bool position_update : 1;
97 Eina_Bool want_unrealize : 1;
98 Eina_Bool realized : 1;
99 Eina_Bool changed : 1;
100 Eina_Bool updateme : 1;
101 Eina_Bool showme : 1;
102 Eina_Bool must_recalc : 1;
109 Evas_Object *base_view, *spacer;
111 const char *item_style; // it->itc->item_style
112 Eina_Bool tree : 1; // it->group
114 Eina_Bool selected : 1; // it->selected
115 Eina_Bool disabled : 1; // it->disabled
116 Eina_Bool expanded : 1; // it->item->expanded
119 static const char *widtype = NULL;
120 static void _item_cache_zero(Widget_Data *wd);
121 static void _del_hook(Evas_Object *obj);
122 static void _mirrored_set(Evas_Object *obj,
124 static void _theme_hook(Evas_Object *obj);
125 static void _show_region_hook(void *data,
127 static void _sizing_eval(Evas_Object *obj);
128 static void _item_realize(Elm_Gen_Item *it,
131 static void _item_unrealize_cb(Elm_Gen_Item *it);
132 static void _item_block_unrealize(Item_Block *itb);
133 static void _calc_job(void *data);
134 static void _on_focus_hook(void *data,
136 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
137 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
138 static Eina_Bool _item_single_select_up(Widget_Data *wd);
139 static Eina_Bool _item_single_select_down(Widget_Data *wd);
140 static Evas_Object * _item_content_unset_hook(Elm_Gen_Item *it, const char *part);
141 static Eina_Bool _event_hook(Evas_Object *obj,
143 Evas_Callback_Type type,
145 static void _signal_emit_hook(Evas_Object *obj,
146 const char *emission,
148 static Eina_Bool _deselect_all_items(Widget_Data *wd);
149 static void _pan_calculate(Evas_Object *obj);
150 static void _pan_max_get(Evas_Object *obj,
153 static void _item_position(Elm_Gen_Item *it,
157 static void _decorate_item_realize(Elm_Gen_Item *it);
158 static void _decorate_item_unrealize(Elm_Gen_Item *it);
159 static void _decorate_item_set(Elm_Gen_Item *it);
160 static void _decorate_item_unset(Widget_Data *wd);
161 static void _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity);
162 static void _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
163 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
164 static void _group_items_recalc(void *data);
165 static void _item_move_after(Elm_Gen_Item *it,
166 Elm_Gen_Item *after);
167 static void _item_move_before(Elm_Gen_Item *it,
168 Elm_Gen_Item *before);
169 static void _item_auto_scroll(Widget_Data *wd);
170 static void _elm_genlist_clear(Evas_Object *obj,
172 static void _pan_child_size_get(Evas_Object *obj,
175 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
176 static void _item_contract_emit(Elm_Gen_Item *it);
177 static int _item_tree_effect_before(Elm_Gen_Item *it);
178 static void _item_tree_effect(Widget_Data *wd, int y);
179 static void _item_tree_effect_finish(Widget_Data *wd);
180 static Eina_Bool _tree_effect_animator_cb(void *data);
182 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
184 static const char SIG_ACTIVATED[] = "activated";
185 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
186 static const char SIG_SELECTED[] = "selected";
187 static const char SIG_UNSELECTED[] = "unselected";
188 static const char SIG_EXPANDED[] = "expanded";
189 static const char SIG_CONTRACTED[] = "contracted";
190 static const char SIG_EXPAND_REQUEST[] = "expand,request";
191 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
192 static const char SIG_REALIZED[] = "realized";
193 static const char SIG_UNREALIZED[] = "unrealized";
194 static const char SIG_DRAG_START_UP[] = "drag,start,up";
195 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
196 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
197 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
198 static const char SIG_DRAG_STOP[] = "drag,stop";
199 static const char SIG_DRAG[] = "drag";
200 static const char SIG_LONGPRESSED[] = "longpressed";
201 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
202 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
203 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
204 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
205 static const char SIG_EDGE_TOP[] = "edge,top";
206 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
207 static const char SIG_EDGE_LEFT[] = "edge,left";
208 static const char SIG_EDGE_RIGHT[] = "edge,right";
209 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
210 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
211 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
212 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
213 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
214 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
215 static const char SIG_SWIPE[] = "swipe";
216 static const char SIG_MOVED[] = "moved";
217 static const char SIG_MOVED_AFTER[] = "moved,after";
218 static const char SIG_MOVED_BEFORE[] = "moved,before";
219 static const char SIG_INDEX_UPDATE[] = "index,update";
220 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
222 static const Evas_Smart_Cb_Description _signals[] = {
223 {SIG_CLICKED_DOUBLE, ""},
226 {SIG_UNSELECTED, ""},
228 {SIG_CONTRACTED, ""},
229 {SIG_EXPAND_REQUEST, ""},
230 {SIG_CONTRACT_REQUEST, ""},
232 {SIG_UNREALIZED, ""},
233 {SIG_DRAG_START_UP, ""},
234 {SIG_DRAG_START_DOWN, ""},
235 {SIG_DRAG_START_LEFT, ""},
236 {SIG_DRAG_START_RIGHT, ""},
239 {SIG_LONGPRESSED, ""},
240 {SIG_SCROLL_ANIM_START, ""},
241 {SIG_SCROLL_ANIM_STOP, ""},
242 {SIG_SCROLL_DRAG_START, ""},
243 {SIG_SCROLL_DRAG_STOP, ""},
245 {SIG_EDGE_BOTTOM, ""},
247 {SIG_EDGE_RIGHT, ""},
248 {SIG_MULTI_SWIPE_LEFT, ""},
249 {SIG_MULTI_SWIPE_RIGHT, ""},
250 {SIG_MULTI_SWIPE_UP, ""},
251 {SIG_MULTI_SWIPE_DOWN, ""},
252 {SIG_MULTI_PINCH_OUT, ""},
253 {SIG_MULTI_PINCH_IN, ""},
256 {SIG_MOVED_AFTER, ""},
257 {SIG_MOVED_BEFORE, ""},
258 {SIG_TREE_EFFECT_FINISHED, ""},
263 #undef ELM_CHECK_WIDTYPE
264 #define ELM_CHECK_WIDTYPE(obj, widtype) \
265 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
266 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
267 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
268 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
269 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
271 static const char *_gengrid = NULL;
272 static const char *_genlist = NULL;
274 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
276 elm_genlist_type_check(const Evas_Object *obj,
279 const char *provided, *expected = "(unknown)";
280 static int abort_on_warn = -1;
281 provided = elm_widget_type_get(obj);
282 if (!_genlist) _genlist = eina_stringshare_add("genlist");
283 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
284 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
286 if ((!provided) || (!provided[0]))
288 provided = evas_object_type_get(obj);
289 if ((!provided) || (!provided[0]))
290 provided = "(unknown)";
292 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
293 if (abort_on_warn == -1)
295 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
296 else abort_on_warn = 0;
298 if (abort_on_warn == 1) abort();
303 _event_hook(Evas_Object *obj,
304 Evas_Object *src __UNUSED__,
305 Evas_Callback_Type type,
308 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
309 Evas_Event_Key_Down *ev = event_info;
310 Widget_Data *wd = elm_widget_data_get(obj);
311 Evas_Coord pan_max_x = 0, pan_max_y = 0;
312 if (!wd) return EINA_FALSE;
313 if (!wd->items) return EINA_FALSE;
314 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
315 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
317 Elm_Object_Item *it = NULL;
320 Evas_Coord step_x = 0;
321 Evas_Coord step_y = 0;
324 Evas_Coord page_x = 0;
325 Evas_Coord page_y = 0;
327 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
328 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
329 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
330 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
332 if ((!strcmp(ev->keyname, "Left")) ||
333 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
337 else if ((!strcmp(ev->keyname, "Right")) ||
338 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
342 else if ((!strcmp(ev->keyname, "Up")) ||
343 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
345 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
346 (_item_multi_select_up(wd)))
347 || (_item_single_select_up(wd)))
349 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
355 else if ((!strcmp(ev->keyname, "Down")) ||
356 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
358 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
359 (_item_multi_select_down(wd)))
360 || (_item_single_select_down(wd)))
362 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
368 else if ((!strcmp(ev->keyname, "Home")) ||
369 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
371 it = elm_genlist_first_item_get(obj);
372 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
373 elm_genlist_item_selected_set(it, EINA_TRUE);
374 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
377 else if ((!strcmp(ev->keyname, "End")) ||
378 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
380 it = elm_genlist_last_item_get(obj);
381 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
382 elm_genlist_item_selected_set(it, EINA_TRUE);
383 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
386 else if ((!strcmp(ev->keyname, "Prior")) ||
387 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
390 y -= -(page_y * v_h) / 100;
394 else if ((!strcmp(ev->keyname, "Next")) ||
395 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
398 y += -(page_y * v_h) / 100;
402 else if (!strcmp(ev->keyname, "Escape"))
404 if (!_deselect_all_items(wd)) return EINA_FALSE;
405 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
408 else if (((!strcmp(ev->keyname, "Return")) ||
409 (!strcmp(ev->keyname, "KP_Enter")) ||
410 (!strcmp(ev->keyname, "space")))
411 && (!wd->multi) && (wd->selected))
413 it = elm_genlist_selected_item_get(obj);
414 elm_genlist_item_expanded_set(it,
415 !elm_genlist_item_expanded_get(it));
416 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
418 else return EINA_FALSE;
420 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
421 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
423 if (x > pan_max_x) x = pan_max_x;
425 if (y > pan_max_y) y = pan_max_y;
426 elm_smart_scroller_child_pos_set(wd->scr, x, y);
431 _deselect_all_items(Widget_Data *wd)
433 if (!wd->selected) return EINA_FALSE;
435 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
441 _item_multi_select_up(Widget_Data *wd)
443 if (!wd->selected) return EINA_FALSE;
444 if (!wd->multi) return EINA_FALSE;
446 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
447 if (!prev) return EINA_TRUE;
449 if (elm_genlist_item_selected_get(prev))
451 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
452 wd->last_selected_item = prev;
453 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
457 elm_genlist_item_selected_set(prev, EINA_TRUE);
458 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
464 _item_multi_select_down(Widget_Data *wd)
466 if (!wd->selected) return EINA_FALSE;
467 if (!wd->multi) return EINA_FALSE;
469 Elm_Object_Item *next;
470 next = elm_genlist_item_next_get(wd->last_selected_item);
471 if (!next) return EINA_TRUE;
473 if (elm_genlist_item_selected_get(next))
475 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
476 wd->last_selected_item = next;
477 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
481 elm_genlist_item_selected_set(next, EINA_TRUE);
482 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
488 _item_single_select_up(Widget_Data *wd)
493 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
494 while ((prev) && (prev->generation < wd->generation))
495 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
497 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
499 if (!prev) return EINA_FALSE;
501 _deselect_all_items(wd);
503 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
504 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
509 _item_single_select_down(Widget_Data *wd)
514 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
515 while ((next) && (next->generation < wd->generation))
516 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
518 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
520 if (!next) return EINA_FALSE;
522 _deselect_all_items(wd);
524 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
525 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
530 _on_focus_hook(void *data __UNUSED__,
533 Widget_Data *wd = elm_widget_data_get(obj);
535 if (elm_widget_focus_get(obj))
537 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
538 evas_object_focus_set(wd->obj, EINA_TRUE);
539 if ((wd->selected) && (!wd->last_selected_item))
540 wd->last_selected_item = eina_list_data_get(wd->selected);
544 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
545 evas_object_focus_set(wd->obj, EINA_FALSE);
550 _del_hook(Evas_Object *obj)
552 Widget_Data *wd = elm_widget_data_get(obj);
554 _item_cache_zero(wd);
555 if (wd->calc_job) ecore_job_del(wd->calc_job);
556 if (wd->update_job) ecore_job_del(wd->update_job);
557 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
558 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
559 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
560 if (wd->decorate_it_type) eina_stringshare_del(wd->decorate_it_type);
561 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
562 if (wd->tree_effect_animator) ecore_animator_del(wd->tree_effect_animator);
567 _del_pre_hook(Evas_Object *obj)
569 Widget_Data *wd = elm_widget_data_get(obj);
571 if (wd->decorate_all_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
572 elm_genlist_clear(obj);
573 evas_object_del(wd->pan_smart);
574 wd->pan_smart = NULL;
578 _mirrored_set(Evas_Object *obj,
581 Widget_Data *wd = elm_widget_data_get(obj);
583 _item_cache_zero(wd);
584 elm_smart_scroller_mirrored_set(wd->scr, rtl);
588 _theme_hook(Evas_Object *obj)
590 Widget_Data *wd = elm_widget_data_get(obj);
593 evas_event_freeze(evas_object_evas_get(wd->obj));
594 _item_cache_zero(wd);
595 _elm_widget_mirrored_reload(obj);
596 _mirrored_set(obj, elm_widget_mirrored_get(obj));
597 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
598 elm_widget_style_get(obj));
599 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
600 wd->item_width = wd->item_height = 0;
601 wd->group_item_width = wd->group_item_height = 0;
602 wd->minw = wd->minh = wd->realminw = 0;
603 EINA_INLIST_FOREACH(wd->blocks, itb)
608 if (itb->realized) _item_block_unrealize(itb);
609 EINA_LIST_FOREACH(itb->items, l, it)
610 it->item->mincalcd = EINA_FALSE;
612 itb->changed = EINA_TRUE;
614 if (wd->calc_job) ecore_job_del(wd->calc_job);
615 wd->calc_job = ecore_job_add(_calc_job, wd);
617 evas_event_thaw(evas_object_evas_get(wd->obj));
618 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
622 _show_region_hook(void *data,
625 Widget_Data *wd = elm_widget_data_get(data);
626 Evas_Coord x, y, w, h;
628 elm_widget_show_region_get(obj, &x, &y, &w, &h);
629 //x & y are screen coordinates, Add with pan coordinates
632 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
636 _translate_hook(Evas_Object *obj)
638 evas_object_smart_callback_call(obj, "language,changed", NULL);
642 _sizing_eval(Evas_Object *obj)
644 Widget_Data *wd = elm_widget_data_get(obj);
645 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
646 Evas_Coord vmw = 0, vmh = 0;
649 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
650 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
652 edje_object_size_min_calc
653 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
655 if (wd->mode == ELM_LIST_COMPRESS)
659 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
660 if ((vw != 0) && (vw != wd->prev_viewport_w))
664 wd->prev_viewport_w = vw;
665 EINA_INLIST_FOREACH(wd->blocks, itb)
667 itb->must_recalc = EINA_TRUE;
669 if (wd->calc_job) ecore_job_del(wd->calc_job);
670 wd->calc_job = ecore_job_add(_calc_job, wd);
675 else if (wd->mode == ELM_LIST_LIMIT)
686 evas_object_size_hint_min_set(obj, minw, minh);
687 evas_object_size_hint_max_set(obj, maxw, maxh);
691 _signal_emit_hook(Evas_Object *obj,
692 const char *emission,
695 Widget_Data *wd = elm_widget_data_get(obj);
696 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
701 _item_highlight(Elm_Gen_Item *it)
703 const char *selectraise;
704 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
705 (!it->wd->highlight) ||
706 (it->generation < it->wd->generation) ||
707 (it->highlighted) || elm_widget_item_disabled_get(it) ||
708 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->deco_it_view) ||
709 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
711 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
712 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
713 selectraise = edje_object_data_get(VIEW(it), "selectraise");
714 if ((selectraise) && (!strcmp(selectraise, "on")))
716 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
717 else evas_object_raise(VIEW(it));
718 if ((it->item->group_item) && (it->item->group_item->realized))
719 evas_object_raise(it->item->VIEW(group_item));
721 it->highlighted = EINA_TRUE;
725 _item_unhighlight(Elm_Gen_Item *it)
727 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
728 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
729 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
730 if (!it->item->nostacking)
732 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
734 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
735 else evas_object_lower(VIEW(it));
739 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
740 else evas_object_raise(VIEW(it));
743 it->highlighted = EINA_FALSE;
747 _item_block_position_update(Eina_Inlist *list, int idx)
751 EINA_INLIST_FOREACH(list, tmp)
753 tmp->position = idx++;
754 tmp->position_update = EINA_TRUE;
759 _item_position_update(Eina_List *list, int idx)
764 EINA_LIST_FOREACH(list, l, it)
766 it->position = idx++;
767 it->position_update = EINA_TRUE;
772 _item_block_del(Elm_Gen_Item *it)
775 Item_Block *itb = it->item->block;
777 itb->items = eina_list_remove(itb->items, it);
779 itb->changed = EINA_TRUE;
780 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
781 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
784 il = EINA_INLIST_GET(itb);
785 Item_Block *itbn = (Item_Block *)(il->next);
787 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
790 _item_block_position_update(il->next, itb->position);
791 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
794 if (itbn) itbn->changed = EINA_TRUE;
798 if (itb->count < itb->wd->max_items_per_block/2)
800 il = EINA_INLIST_GET(itb);
801 Item_Block *itbp = (Item_Block *)(il->prev);
802 Item_Block *itbn = (Item_Block *)(il->next);
803 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
807 EINA_LIST_FREE(itb->items, it2)
809 it2->item->block = itbp;
810 itbp->items = eina_list_append(itbp->items, it2);
812 itbp->changed = EINA_TRUE;
814 _item_block_position_update(EINA_INLIST_GET(itb)->next,
816 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
817 EINA_INLIST_GET(itb));
820 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
824 Eina_List *last = eina_list_last(itb->items);
825 Elm_Gen_Item *it2 = last->data;
827 it2->item->block = itbn;
828 itb->items = eina_list_remove_list(itb->items, last);
829 itbn->items = eina_list_prepend(itbn->items, it2);
831 itbn->changed = EINA_TRUE;
833 _item_block_position_update(EINA_INLIST_GET(itb)->next,
836 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
844 _item_subitems_clear(Elm_Gen_Item *it)
846 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
847 Eina_List *tl = NULL, *l;
848 Elm_Object_Item *it2;
850 EINA_LIST_FOREACH(it->item->items, l, it2)
851 tl = eina_list_append(tl, it2);
852 EINA_LIST_FREE(tl, it2)
853 elm_object_item_del(it2);
857 _item_del(Elm_Gen_Item *it)
859 Evas_Object *obj = WIDGET(it);
861 evas_event_freeze(evas_object_evas_get(obj));
862 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
863 if (it->wd->show_item == it) it->wd->show_item = NULL;
864 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
865 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
866 if (it->item->block) _item_block_del(it);
867 if (it->item->queued)
868 it->wd->queue = eina_list_remove(it->wd->queue, it);
869 if (it->wd->anchor_item == it)
871 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
872 if (!it->wd->anchor_item)
873 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
875 if (it->wd->expanded_item == it) it->wd->expanded_item = NULL;
876 if (it->wd->expanded_next_item == it) it->wd->expanded_next_item = NULL;
878 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
879 if (it->item->swipe_timer)
881 ecore_timer_del(it->item->swipe_timer);
882 it->item->swipe_timer = NULL;
884 _elm_genlist_item_del_serious(it);
885 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
886 evas_event_thaw(evas_object_evas_get(obj));
887 evas_event_thaw_eval(evas_object_evas_get(obj));
891 _clear_cb(Widget_Data *wd)
893 wd->anchor_item = NULL;
894 if (wd->queue_idle_enterer)
896 ecore_idle_enterer_del(wd->queue_idle_enterer);
897 wd->queue_idle_enterer = NULL;
899 if (wd->must_recalc_idler)
901 ecore_idler_del(wd->must_recalc_idler);
902 wd->must_recalc_idler = NULL;
904 if (wd->queue) wd->queue = eina_list_free(wd->queue);
905 if (wd->reorder_move_animator)
907 ecore_animator_del(wd->reorder_move_animator);
908 wd->reorder_move_animator = NULL;
910 wd->show_item = NULL;
911 wd->reorder_old_pan_y = 0;
915 _item_unselect(Elm_Gen_Item *it)
917 if ((it->generation < it->wd->generation) || (!it->selected)) return;
918 it->selected = EINA_FALSE;
919 it->wd->selected = eina_list_remove(it->wd->selected, it);
920 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
924 _mouse_move(void *data,
925 Evas *evas __UNUSED__,
929 Elm_Gen_Item *it = data;
930 Evas_Event_Mouse_Move *ev = event_info;
931 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
932 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
934 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
936 if (!it->wd->on_hold)
938 it->wd->on_hold = EINA_TRUE;
939 if ((!it->wd->wasselected) && (!it->flipped))
941 _item_unhighlight(it);
946 if (it->wd->multitouched)
948 it->wd->cur_x = ev->cur.canvas.x;
949 it->wd->cur_y = ev->cur.canvas.y;
952 if ((it->dragging) && (it->down))
954 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
957 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
958 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
959 if (abs((it->wd->history[it->wd->movements].x -
960 it->wd->history[0].x)) > 40)
961 it->wd->swipe = EINA_TRUE;
967 ecore_timer_del(it->long_timer);
968 it->long_timer = NULL;
970 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
973 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
977 ecore_timer_del(it->long_timer);
978 it->long_timer = NULL;
980 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
982 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
983 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
985 if (!it->wd->reorder_start_y)
986 it->wd->reorder_start_y = it->item->block->y + it->y;
990 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
991 y_pos = oy + oh - it->wd->reorder_it->item->h;
995 if (it->deco_all_view)
996 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
998 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1000 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1001 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1005 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1006 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1007 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1008 x = ev->cur.canvas.x - x;
1009 y = ev->cur.canvas.y - y;
1012 if (adx < 0) adx = -dx;
1015 if (ady < 0) ady = -dy;
1018 if ((adx > minw) || (ady > minh))
1020 it->dragging = EINA_TRUE;
1023 ecore_timer_del(it->long_timer);
1024 it->long_timer = NULL;
1026 if (!it->wd->wasselected)
1028 _item_unhighlight(it);
1034 evas_object_smart_callback_call(WIDGET(it),
1035 SIG_DRAG_START_UP, it);
1039 evas_object_smart_callback_call(WIDGET(it),
1040 SIG_DRAG_START_LEFT, it);
1042 evas_object_smart_callback_call(WIDGET(it),
1043 SIG_DRAG_START_RIGHT, it);
1049 evas_object_smart_callback_call(WIDGET(it),
1050 SIG_DRAG_START_DOWN, it);
1054 evas_object_smart_callback_call(WIDGET(it),
1055 SIG_DRAG_START_LEFT, it);
1057 evas_object_smart_callback_call(WIDGET(it),
1058 SIG_DRAG_START_RIGHT, it);
1065 _long_press(void *data)
1067 Elm_Gen_Item *it = data, *it_tmp;
1068 Eina_List *list, *l;
1070 it->long_timer = NULL;
1071 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1072 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1073 return ECORE_CALLBACK_CANCEL;
1074 it->wd->longpressed = EINA_TRUE;
1075 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1076 if ((it->wd->reorder_mode) && (!it->group))
1078 it->wd->reorder_it = it;
1079 it->wd->reorder_start_y = 0;
1080 if (it->deco_all_view)
1081 evas_object_raise(it->deco_all_view);
1083 evas_object_raise(VIEW(it));
1085 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1086 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1088 list = elm_genlist_realized_items_get(it->wd->obj);
1089 EINA_LIST_FOREACH(list, l, it_tmp)
1091 if (it != it_tmp) _item_unselect(it_tmp);
1093 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1095 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1096 return ECORE_CALLBACK_RENEW;
1099 if (!it->wd->decorate_all_mode)
1100 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1102 return ECORE_CALLBACK_CANCEL;
1106 _swipe(Elm_Gen_Item *it)
1111 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1112 elm_widget_item_disabled_get(it)) return;
1113 it->wd->swipe = EINA_FALSE;
1114 for (i = 0; i < it->wd->movements; i++)
1116 sum += it->wd->history[i].x;
1117 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1120 sum /= it->wd->movements;
1121 if (abs(sum - it->wd->history[0].x) <= 10) return;
1122 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1126 _swipe_cancel(void *data)
1128 Elm_Gen_Item *it = data;
1130 if (!it) return ECORE_CALLBACK_CANCEL;
1131 it->wd->swipe = EINA_FALSE;
1132 it->wd->movements = 0;
1133 return ECORE_CALLBACK_RENEW;
1137 _multi_cancel(void *data)
1139 Widget_Data *wd = data;
1141 if (!wd) return ECORE_CALLBACK_CANCEL;
1142 wd->multi_timeout = EINA_TRUE;
1143 return ECORE_CALLBACK_RENEW;
1147 _multi_touch_gesture_eval(void *data)
1149 Elm_Gen_Item *it = data;
1151 it->wd->multitouched = EINA_FALSE;
1152 if (it->wd->multi_timer)
1154 ecore_timer_del(it->wd->multi_timer);
1155 it->wd->multi_timer = NULL;
1157 if (it->wd->multi_timeout)
1159 it->wd->multi_timeout = EINA_FALSE;
1163 Evas_Coord minw = 0, minh = 0;
1164 Evas_Coord off_x, off_y, off_mx, off_my;
1166 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1167 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1168 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1169 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1170 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1172 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1174 if ((off_x + off_mx) > (off_y + off_my))
1176 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1177 evas_object_smart_callback_call(WIDGET(it),
1178 SIG_MULTI_SWIPE_RIGHT, it);
1179 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1180 evas_object_smart_callback_call(WIDGET(it),
1181 SIG_MULTI_SWIPE_LEFT, it);
1182 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
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);
1191 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1192 evas_object_smart_callback_call(WIDGET(it),
1193 SIG_MULTI_SWIPE_DOWN, it);
1194 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1195 evas_object_smart_callback_call(WIDGET(it),
1196 SIG_MULTI_SWIPE_UP, it);
1197 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1198 evas_object_smart_callback_call(WIDGET(it),
1199 SIG_MULTI_PINCH_OUT, it);
1201 evas_object_smart_callback_call(WIDGET(it),
1202 SIG_MULTI_PINCH_IN, it);
1205 it->wd->multi_timeout = EINA_FALSE;
1209 _multi_down(void *data,
1210 Evas *evas __UNUSED__,
1211 Evas_Object *obj __UNUSED__,
1214 Elm_Gen_Item *it = data;
1215 Evas_Event_Multi_Down *ev = event_info;
1217 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1218 it->wd->multi_device = ev->device;
1219 it->wd->multi_down = EINA_TRUE;
1220 it->wd->multitouched = EINA_TRUE;
1221 it->wd->prev_mx = ev->canvas.x;
1222 it->wd->prev_my = ev->canvas.y;
1223 if (!it->wd->wasselected)
1225 _item_unhighlight(it);
1228 it->wd->wasselected = EINA_FALSE;
1229 it->wd->longpressed = EINA_FALSE;
1232 ecore_timer_del(it->long_timer);
1233 it->long_timer = NULL;
1237 it->dragging = EINA_FALSE;
1238 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1240 if (it->item->swipe_timer)
1242 ecore_timer_del(it->item->swipe_timer);
1243 it->item->swipe_timer = NULL;
1245 if (it->wd->on_hold)
1247 it->wd->swipe = EINA_FALSE;
1248 it->wd->movements = 0;
1249 it->wd->on_hold = EINA_FALSE;
1254 _multi_up(void *data,
1255 Evas *evas __UNUSED__,
1256 Evas_Object *obj __UNUSED__,
1259 Elm_Gen_Item *it = data;
1260 Evas_Event_Multi_Up *ev = event_info;
1262 if (it->wd->multi_device != ev->device) return;
1263 it->wd->multi_device = 0;
1264 it->wd->multi_down = EINA_FALSE;
1265 if (it->wd->mouse_down) return;
1266 _multi_touch_gesture_eval(data);
1270 _multi_move(void *data,
1271 Evas *evas __UNUSED__,
1272 Evas_Object *obj __UNUSED__,
1275 Elm_Gen_Item *it = data;
1276 Evas_Event_Multi_Move *ev = event_info;
1278 if (it->wd->multi_device != ev->device) return;
1279 it->wd->cur_mx = ev->cur.canvas.x;
1280 it->wd->cur_my = ev->cur.canvas.y;
1284 _mouse_down(void *data,
1285 Evas *evas __UNUSED__,
1289 Elm_Gen_Item *it = data;
1290 Evas_Event_Mouse_Down *ev = event_info;
1293 if (ev->button != 1) return;
1294 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1296 it->wd->on_hold = EINA_TRUE;
1299 it->down = EINA_TRUE;
1300 it->dragging = EINA_FALSE;
1301 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1302 it->dx = ev->canvas.x - x;
1303 it->dy = ev->canvas.y - y;
1304 it->wd->mouse_down = EINA_TRUE;
1305 if (!it->wd->multitouched)
1307 it->wd->prev_x = ev->canvas.x;
1308 it->wd->prev_y = ev->canvas.y;
1309 it->wd->multi_timeout = EINA_FALSE;
1310 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1311 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1313 it->wd->longpressed = EINA_FALSE;
1314 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1315 else it->wd->on_hold = EINA_FALSE;
1316 if (it->wd->on_hold) return;
1317 it->wd->wasselected = it->selected;
1318 _item_highlight(it);
1319 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1320 if ((!elm_widget_item_disabled_get(it)) &&
1321 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1323 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1324 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1326 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1327 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1328 if (it->long_timer) ecore_timer_del(it->long_timer);
1330 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1333 it->long_timer = NULL;
1334 it->wd->swipe = EINA_FALSE;
1335 it->wd->movements = 0;
1339 _mouse_up(void *data,
1340 Evas *evas __UNUSED__,
1341 Evas_Object *obj __UNUSED__,
1344 Elm_Gen_Item *it = data;
1345 Evas_Event_Mouse_Up *ev = event_info;
1346 Eina_Bool dragged = EINA_FALSE;
1348 if (ev->button != 1) return;
1349 it->down = EINA_FALSE;
1350 it->wd->mouse_down = EINA_FALSE;
1351 if (it->wd->multitouched)
1353 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1354 if (it->wd->multi_down) return;
1355 _multi_touch_gesture_eval(data);
1358 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1359 else it->wd->on_hold = EINA_FALSE;
1362 ecore_timer_del(it->long_timer);
1363 it->long_timer = NULL;
1367 it->dragging = EINA_FALSE;
1368 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1371 if (it->item->swipe_timer)
1373 ecore_timer_del(it->item->swipe_timer);
1374 it->item->swipe_timer = NULL;
1376 if (it->wd->multi_timer)
1378 ecore_timer_del(it->wd->multi_timer);
1379 it->wd->multi_timer = NULL;
1380 it->wd->multi_timeout = EINA_FALSE;
1382 if (it->wd->on_hold)
1384 if (it->wd->swipe) _swipe(data);
1385 it->wd->longpressed = EINA_FALSE;
1386 it->wd->on_hold = EINA_FALSE;
1389 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1391 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1393 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1395 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1396 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1398 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1399 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1403 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1404 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1406 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1407 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1408 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1409 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1411 if (it->wd->longpressed)
1413 it->wd->longpressed = EINA_FALSE;
1414 if ((!it->wd->wasselected) && (!it->flipped))
1416 _item_unhighlight(it);
1419 it->wd->wasselected = EINA_FALSE;
1424 if (it->want_unrealize)
1426 _elm_genlist_item_unrealize(it, EINA_FALSE);
1427 if (it->item->block->want_unrealize)
1428 _item_block_unrealize(it->item->block);
1431 if (elm_widget_item_disabled_get(it) || (dragged) ||
1432 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1434 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1439 _item_highlight(it);
1444 _item_unhighlight(it);
1452 Widget_Data *wd = it->wd;
1455 while (wd->selected)
1457 _item_unhighlight(wd->selected->data);
1458 _item_unselect(wd->selected->data);
1464 const Eina_List *l, *l_next;
1467 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1470 _item_unhighlight(it2);
1471 _item_unselect(it2);
1473 //_item_highlight(it);
1476 _item_highlight(it);
1482 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1484 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1486 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1488 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1490 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1492 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1494 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1499 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1501 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1503 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1505 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1507 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1509 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1511 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1516 _signal_expand_toggle(void *data,
1517 Evas_Object *obj __UNUSED__,
1518 const char *emission __UNUSED__,
1519 const char *source __UNUSED__)
1521 Elm_Gen_Item *it = data;
1523 if (it->item->expanded)
1524 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1526 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1530 _signal_expand(void *data,
1531 Evas_Object *obj __UNUSED__,
1532 const char *emission __UNUSED__,
1533 const char *source __UNUSED__)
1535 Elm_Gen_Item *it = data;
1537 if (!it->item->expanded)
1538 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1542 _signal_contract(void *data,
1543 Evas_Object *obj __UNUSED__,
1544 const char *emission __UNUSED__,
1545 const char *source __UNUSED__)
1547 Elm_Gen_Item *it = data;
1549 if (it->item->expanded)
1550 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1554 _scr_hold_timer_cb(void *data)
1556 if (!data) return ECORE_CALLBACK_CANCEL;
1557 Widget_Data *wd = data;
1558 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1559 wd->scr_hold_timer = NULL;
1560 return ECORE_CALLBACK_CANCEL;
1564 _decorate_item_finished_signal_cb(void *data,
1566 const char *emission __UNUSED__,
1567 const char *source __UNUSED__)
1571 Elm_Gen_Item *it = data;
1572 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1574 Evas *te = evas_object_evas_get(obj);
1576 evas_event_freeze(te);
1577 it->item->nocache_once = EINA_FALSE;
1578 _decorate_item_unrealize(it);
1579 if (it->item->group_item)
1580 evas_object_raise(it->item->VIEW(group_item));
1581 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1582 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1583 evas_event_thaw(te);
1584 evas_event_thaw_eval(te);
1588 _item_cache_clean(Widget_Data *wd)
1590 evas_event_freeze(evas_object_evas_get(wd->obj));
1591 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1595 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1596 wd->item_cache = eina_inlist_remove(wd->item_cache,
1597 wd->item_cache->last);
1598 wd->item_cache_count--;
1599 if (itc->spacer) evas_object_del(itc->spacer);
1600 if (itc->base_view) evas_object_del(itc->base_view);
1601 eina_stringshare_del(itc->item_style);
1604 evas_event_thaw(evas_object_evas_get(wd->obj));
1605 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1609 _item_cache_zero(Widget_Data *wd)
1611 int pmax = wd->item_cache_max;
1612 wd->item_cache_max = 0;
1613 _item_cache_clean(wd);
1614 wd->item_cache_max = pmax;
1618 _item_cache_add(Elm_Gen_Item *it)
1622 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1623 if (it->wd->item_cache_max <= 0)
1625 evas_object_del(VIEW(it));
1629 evas_object_del(it->spacer);
1632 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1633 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1637 it->wd->item_cache_count++;
1638 itc = calloc(1, sizeof(Item_Cache));
1641 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1642 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1645 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1646 EINA_INLIST_GET(itc));
1647 itc->spacer = it->spacer;
1649 itc->base_view = VIEW(it);
1651 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1652 evas_object_hide(itc->base_view);
1653 evas_object_move(itc->base_view, -9999, -9999);
1654 itc->item_style = eina_stringshare_add(it->itc->item_style);
1655 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1656 itc->selected = it->selected;
1657 itc->disabled = elm_widget_item_disabled_get(it);
1658 itc->expanded = it->item->expanded;
1661 ecore_timer_del(it->long_timer);
1662 it->long_timer = NULL;
1664 if (it->item->swipe_timer)
1666 ecore_timer_del(it->item->swipe_timer);
1667 it->item->swipe_timer = NULL;
1669 // FIXME: other callbacks?
1670 edje_object_signal_callback_del_full(itc->base_view,
1671 "elm,action,expand,toggle",
1672 "elm", _signal_expand_toggle, it);
1673 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1675 _signal_expand, it);
1676 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1677 "elm", _signal_contract, it);
1678 _item_mouse_callbacks_del(it, itc->base_view);
1679 _item_cache_clean(it->wd);
1680 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1681 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1685 _item_cache_find(Elm_Gen_Item *it)
1690 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1691 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1693 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1695 if ((itc->tree == tree) &&
1696 (((!it->itc->item_style) && (!itc->item_style)) ||
1697 (it->itc->item_style && itc->item_style &&
1698 (!strcmp(it->itc->item_style, itc->item_style)))))
1700 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1701 EINA_INLIST_GET(itc));
1702 it->wd->item_cache_count--;
1710 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1712 if (it->position_update || it->item->block->position_update)
1714 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1715 it->position_update = EINA_FALSE;
1720 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1722 if (!it->item->nostacking)
1724 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1726 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1727 else evas_object_lower(VIEW(it));
1731 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1732 else evas_object_raise(VIEW(it));
1736 if (it->item->order_num_in & 0x1)
1738 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1739 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1743 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1744 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1749 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1753 if (it->selected != itc->selected)
1757 edje_object_signal_emit(VIEW(it),
1758 "elm,state,selected", "elm");
1760 if (it->deco_all_view)
1761 edje_object_signal_emit(it->deco_all_view,
1762 "elm,state,selected", "elm");
1765 if (elm_widget_item_disabled_get(it) != itc->disabled)
1767 if (elm_widget_item_disabled_get(it))
1768 edje_object_signal_emit(VIEW(it),
1769 "elm,state,disabled", "elm");
1770 if (it->deco_all_view)
1771 edje_object_signal_emit(it->deco_all_view,
1772 "elm,state,disabled", "elm");
1774 if (it->item->expanded != itc->expanded)
1776 if (it->item->expanded)
1777 edje_object_signal_emit(VIEW(it),
1778 "elm,state,expanded", "elm");
1779 if (it->deco_all_view)
1780 edje_object_signal_emit(it->deco_all_view,
1781 "elm,state,expanded", "elm");
1788 edje_object_signal_emit(VIEW(it),
1789 "elm,state,selected", "elm");
1790 if (it->deco_all_view)
1791 edje_object_signal_emit(it->deco_all_view,
1792 "elm,state,selected", "elm");
1795 if (elm_widget_item_disabled_get(it))
1797 edje_object_signal_emit(VIEW(it),
1798 "elm,state,disabled", "elm");
1799 if (it->deco_all_view)
1800 edje_object_signal_emit(it->deco_all_view,
1801 "elm,state,disabled", "elm");
1803 if (it->item->expanded)
1805 edje_object_signal_emit(VIEW(it),
1806 "elm,state,expanded", "elm");
1807 if (it->deco_all_view)
1808 edje_object_signal_emit(it->deco_all_view,
1809 "elm,state,expanded", "elm");
1815 _item_mode_content_realize(Elm_Gen_Item *it,
1816 Evas_Object *target,
1819 Eina_List **contents_list)
1821 Eina_List *res = *contents_list;
1823 if (it->itc->func.content_get)
1828 EINA_LIST_FOREACH(*source, l, key)
1830 if (parts && fnmatch(parts, key, FNM_PERIOD))
1833 Evas_Object *ic = it->itc->func.content_get
1834 ((void *)it->base.data, WIDGET(it), l->data);
1838 res = eina_list_append(res, ic);
1839 edje_object_part_swallow(target, key, ic);
1840 evas_object_show(ic);
1841 elm_widget_sub_object_add(WIDGET(it), ic);
1842 if (it->item->deco_it_view || it->wd->decorate_all_mode)
1844 if (elm_widget_item_disabled_get(it))
1845 elm_widget_disabled_set(ic, EINA_TRUE);
1855 _item_mode_content_unrealize(Elm_Gen_Item *it,
1856 Evas_Object *target,
1859 Eina_List **contents_list)
1861 Eina_List *res = *contents_list;
1863 if (it->itc->func.content_get)
1867 Evas_Object *ic = NULL;
1869 EINA_LIST_FOREACH(*source, l, key)
1871 if (parts && fnmatch(parts, key, FNM_PERIOD))
1874 ic = edje_object_part_swallow_get(target, key);
1877 res = eina_list_remove(res, ic);
1878 edje_object_part_unswallow(target, ic);
1879 evas_object_del(ic);
1888 _item_cache_free(Item_Cache *itc)
1890 if (itc->spacer) evas_object_del(itc->spacer);
1891 if (itc->base_view) evas_object_del(itc->base_view);
1892 eina_stringshare_del(itc->item_style);
1897 _item_text_realize(Elm_Gen_Item *it,
1898 Evas_Object *target,
1902 if (it->itc->func.text_get)
1908 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1909 EINA_LIST_FOREACH(*source, l, key)
1911 if (parts && fnmatch(parts, key, FNM_PERIOD))
1914 char *s = it->itc->func.text_get
1915 ((void *)it->base.data, WIDGET(it), key);
1919 edje_object_part_text_set(target, key, s);
1924 edje_object_part_text_set(target, key, "");
1931 _item_content_unrealize(Elm_Gen_Item *it,
1932 Evas_Object *target,
1936 Eina_List *res = it->content_objs;
1938 if (it->itc->func.content_get)
1942 Evas_Object *ic = NULL;
1944 EINA_LIST_FOREACH(*source, l, key)
1946 if (parts && fnmatch(parts, key, FNM_PERIOD))
1949 ic = edje_object_part_swallow_get(target, key);
1952 res = eina_list_remove(res, ic);
1953 edje_object_part_unswallow(target, ic);
1954 evas_object_del(ic);
1963 _item_content_realize(Elm_Gen_Item *it,
1964 Evas_Object *target,
1968 Eina_List *res = it->content_objs;
1970 if (it->itc->func.content_get)
1974 Evas_Object *ic = NULL;
1977 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1979 EINA_LIST_FOREACH(*source, l, key)
1981 if (parts && fnmatch(parts, key, FNM_PERIOD))
1984 if (it->itc->func.content_get)
1985 ic = it->itc->func.content_get
1986 ((void *)it->base.data, WIDGET(it), key);
1989 res = eina_list_append(res, ic);
1990 edje_object_part_swallow(target, key, ic);
1991 evas_object_show(ic);
1992 elm_widget_sub_object_add(WIDGET(it), ic);
1993 if (elm_widget_item_disabled_get(it))
1994 elm_widget_disabled_set(ic, EINA_TRUE);
2003 _item_state_realize(Elm_Gen_Item *it,
2004 Evas_Object *target,
2008 if (it->itc->func.state_get)
2015 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2016 EINA_LIST_FOREACH(*source, l, key)
2018 if (parts && fnmatch(parts, key, FNM_PERIOD))
2021 Eina_Bool on = it->itc->func.state_get
2022 ((void *)it->base.data, WIDGET(it), key);
2026 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2027 edje_object_signal_emit(target, buf, "elm");
2031 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2032 edje_object_signal_emit(target, buf, "elm");
2039 _item_realize(Elm_Gen_Item *it,
2043 const char *treesize;
2046 Item_Cache *itc = NULL;
2048 if (it->generation < it->wd->generation) return;
2049 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2052 if (it->item->order_num_in != in)
2054 it->item->order_num_in = in;
2055 _elm_genlist_item_odd_even_update(it);
2056 _elm_genlist_item_state_update(it, NULL);
2057 _elm_genlist_item_index_update(it);
2059 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2060 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2063 it->item->order_num_in = in;
2065 if (it->item->nocache_once)
2066 it->item->nocache_once = EINA_FALSE;
2067 else if (!it->item->nocache)
2068 itc = _item_cache_find(it);
2069 if (itc && (!it->wd->tree_effect_enabled))
2071 VIEW(it) = itc->base_view;
2072 itc->base_view = NULL;
2073 it->spacer = itc->spacer;
2078 const char *stacking_even;
2079 const char *stacking;
2081 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2082 edje_object_scale_set(VIEW(it),
2083 elm_widget_scale_get(WIDGET(it)) *
2084 _elm_config->scale);
2085 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2086 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2088 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2089 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2091 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2093 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2094 elm_widget_style_get(WIDGET(it)));
2096 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2097 if (!stacking_even) stacking_even = "above";
2098 it->item->stacking_even = !!strcmp("above", stacking_even);
2100 stacking = edje_object_data_get(VIEW(it), "stacking");
2101 if (!stacking) stacking = "yes";
2102 it->item->nostacking = !!strcmp("yes", stacking);
2104 edje_object_mirrored_set(VIEW(it),
2105 elm_widget_mirrored_get(WIDGET(it)));
2108 _elm_genlist_item_odd_even_update(it);
2110 treesize = edje_object_data_get(VIEW(it), "treesize");
2111 if (treesize) tsize = atoi(treesize);
2112 if (!it->spacer && treesize)
2115 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2116 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2117 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2121 evas_object_size_hint_min_set(it->spacer,
2122 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2123 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2127 edje_object_signal_callback_add(VIEW(it),
2128 "elm,action,expand,toggle",
2129 "elm", _signal_expand_toggle, it);
2130 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2131 "elm", _signal_expand, it);
2132 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2133 "elm", _signal_contract, it);
2134 _item_mouse_callbacks_add(it, VIEW(it));
2136 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2137 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2138 _decorate_all_item_realize(it, EINA_FALSE);
2140 _elm_genlist_item_state_update(it, itc);
2141 _elm_genlist_item_index_update(it);
2144 if ((calc) && (it->wd->homogeneous) &&
2145 ((it->wd->item_width) ||
2146 ((it->wd->item_width) && (it->wd->group_item_width))))
2148 /* homogenous genlist shortcut */
2149 if (!it->item->mincalcd)
2153 it->item->w = it->item->minw = it->wd->group_item_width;
2154 it->item->h = it->item->minh = it->wd->group_item_height;
2158 it->item->w = it->item->minw = it->wd->item_width;
2159 it->item->h = it->item->minh = it->wd->item_height;
2161 it->item->mincalcd = EINA_TRUE;
2166 /* FIXME: If you see that assert, please notify us and we
2167 will clean our mess */
2168 assert(eina_list_count(it->content_objs) == 0);
2170 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2171 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2172 _item_state_realize(it, VIEW(it), &it->states, NULL);
2175 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2176 if (!(it->item->flip_contents))
2177 it->item->flip_contents =
2178 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2179 it->item->flip_content_objs =
2180 _item_mode_content_realize(it, VIEW(it),
2181 &it->item->flip_contents, NULL,
2182 &it->item->flip_content_objs);
2185 if (!it->item->mincalcd)
2187 Evas_Coord mw = -1, mh = -1;
2189 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2190 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2191 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2192 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2194 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2195 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2196 it->item->w = it->item->minw = mw;
2197 it->item->h = it->item->minh = mh;
2198 it->item->mincalcd = EINA_TRUE;
2200 if ((!it->wd->group_item_width) && (it->group))
2202 it->wd->group_item_width = mw;
2203 it->wd->group_item_height = mh;
2205 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2207 it->wd->item_width = mw;
2208 it->wd->item_height = mh;
2211 if (!calc) evas_object_show(VIEW(it));
2214 if (it->tooltip.content_cb)
2216 elm_widget_item_tooltip_content_cb_set(it,
2217 it->tooltip.content_cb,
2218 it->tooltip.data, NULL);
2219 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2220 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2223 if (it->mouse_cursor)
2224 elm_widget_item_cursor_set(it, it->mouse_cursor);
2226 it->realized = EINA_TRUE;
2227 it->want_unrealize = EINA_FALSE;
2229 if (itc) _item_cache_free(itc);
2230 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2231 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2234 if (it->item->tree_effect_hideme)
2236 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2237 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2238 it->item->tree_effect_hideme = EINA_FALSE;
2240 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2243 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2245 if (it->itc->decorate_all_item_style)
2247 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2248 edje_object_message_signal_process(it->deco_all_view);
2251 edje_object_message_signal_process(VIEW(it));
2255 _item_unrealize_cb(Elm_Gen_Item *it)
2257 if (it->item->nocache_once || it->item->nocache)
2259 evas_object_del(VIEW(it));
2263 evas_object_del(it->spacer);
2269 edje_object_mirrored_set(VIEW(it),
2270 elm_widget_mirrored_get(WIDGET(it)));
2271 edje_object_scale_set(VIEW(it),
2272 elm_widget_scale_get(WIDGET(it))
2273 * _elm_config->scale);
2274 _item_cache_add(it);
2277 _decorate_item_unrealize(it);
2279 it->realized = EINA_FALSE;
2280 it->want_unrealize = EINA_FALSE;
2281 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2285 _item_block_recalc(Item_Block *itb,
2291 Evas_Coord minw = 0, minh = 0;
2292 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2295 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2297 EINA_LIST_FOREACH(itb->items, l, it)
2299 if (it->generation < it->wd->generation) continue;
2300 showme |= it->item->showme;
2305 if (!it->item->mincalcd) changed = EINA_TRUE;
2308 _item_realize(it, in, EINA_TRUE);
2309 _elm_genlist_item_unrealize(it, EINA_TRUE);
2314 _item_realize(it, in, EINA_TRUE);
2315 _elm_genlist_item_unrealize(it, EINA_TRUE);
2320 if (!it->item->mincalcd) changed = EINA_TRUE;
2321 _item_realize(it, in, EINA_FALSE);
2323 minh += it->item->minh;
2324 if (minw < it->item->minw) minw = it->item->minw;
2330 if (changed) itb->wd->pan_changed = changed;
2333 itb->changed = EINA_FALSE;
2334 itb->position_update = EINA_FALSE;
2335 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2336 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2341 _item_block_realize(Item_Block *itb)
2343 if (itb->realized) return;
2344 itb->realized = EINA_TRUE;
2345 itb->want_unrealize = EINA_FALSE;
2349 _item_block_unrealize(Item_Block *itb)
2353 Eina_Bool dragging = EINA_FALSE;
2355 if (!itb->realized) return;
2356 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2357 EINA_LIST_FOREACH(itb->items, l, it)
2359 if (itb->must_recalc || !it->group)
2363 dragging = EINA_TRUE;
2364 it->want_unrealize = EINA_TRUE;
2367 _elm_genlist_item_unrealize(it, EINA_FALSE);
2372 itb->realized = EINA_FALSE;
2373 itb->want_unrealize = EINA_TRUE;
2376 itb->want_unrealize = EINA_FALSE;
2377 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2378 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2382 _get_space_for_reorder_item(Elm_Gen_Item *it)
2384 Evas_Coord rox, roy, row, roh, oy, oh;
2385 Eina_Bool top = EINA_FALSE;
2386 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2387 if (!reorder_it) return 0;
2389 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2390 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2392 if ((it->wd->reorder_start_y < it->item->block->y) &&
2393 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2395 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2396 if (it->item->block->count == 1)
2397 it->wd->reorder_rel = it;
2399 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2400 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2402 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2405 it->item->block->reorder_offset = 0;
2407 it->item->scrl_y += it->item->block->reorder_offset;
2409 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2410 rox, roy + (roh / 2), row, 1));
2413 it->wd->reorder_rel = it;
2414 it->item->scrl_y += it->wd->reorder_it->item->h;
2415 return it->wd->reorder_it->item->h;
2422 _reorder_move_animator_cb(void *data)
2424 Elm_Gen_Item *it = data;
2425 Eina_Bool down = EINA_FALSE;
2427 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2429 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2431 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2434 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2435 if (diff > it->item->h) y = diff / 2;
2437 if (it->item->old_scrl_y < it->item->scrl_y)
2439 it->item->old_scrl_y += y;
2442 else if (it->item->old_scrl_y > it->item->scrl_y)
2444 it->item->old_scrl_y -= y;
2448 if (it->deco_all_view)
2449 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2451 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2452 _group_items_recalc(it->wd);
2454 if ((it->wd->reorder_pan_move) ||
2455 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2456 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2458 it->item->old_scrl_y = it->item->scrl_y;
2459 it->item->move_effect_enabled = EINA_FALSE;
2460 it->wd->reorder_move_animator = NULL;
2461 return ECORE_CALLBACK_CANCEL;
2463 return ECORE_CALLBACK_RENEW;
2467 _item_position(Elm_Gen_Item *it,
2475 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2476 evas_object_resize(view, it->item->w, it->item->h);
2477 evas_object_move(view, it_x, it_y);
2478 evas_object_show(view);
2479 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2480 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2484 _item_block_position(Item_Block *itb,
2490 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2491 Eina_Bool vis = EINA_FALSE;
2493 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2494 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2495 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2497 EINA_LIST_FOREACH(itb->items, l, it)
2499 if (it->generation < it->wd->generation) continue;
2500 else if (it->wd->reorder_it == it) continue;
2503 it->item->w = itb->w;
2504 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2505 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2507 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2508 cvx, cvy, cvw, cvh));
2511 if ((itb->realized) && (!it->realized))
2513 if (vis) _item_realize(it, in, EINA_FALSE);
2517 if (vis || it->dragging)
2519 if (it->wd->reorder_mode)
2520 y += _get_space_for_reorder_item(it);
2521 git = it->item->group_item;
2524 if (git->item->scrl_y < oy)
2525 git->item->scrl_y = oy;
2526 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2527 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2528 git->item->want_realize = EINA_TRUE;
2530 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2532 if (!it->item->move_effect_enabled)
2534 it->item->move_effect_enabled = EINA_TRUE;
2535 it->wd->reorder_move_animator =
2537 _reorder_move_animator_cb, it);
2540 if (!it->item->move_effect_enabled)
2542 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2543 _decorate_all_item_position(it, it->item->scrl_x,
2547 if (!it->wd->tree_effect_enabled ||
2548 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2549 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2550 (it->item->old_scrl_y == it->item->scrl_y)))
2552 if (it->item->deco_it_view)
2553 _item_position(it, it->item->deco_it_view,
2557 _item_position(it, VIEW(it), it->item->scrl_x,
2561 it->item->old_scrl_y = it->item->scrl_y;
2566 if (!it->wd->tree_effect_animator)
2567 _elm_genlist_item_unrealize(it, EINA_FALSE);
2574 if (vis) it->item->want_realize = EINA_TRUE;
2578 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2579 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2583 _group_items_recalc(void *data)
2585 Widget_Data *wd = data;
2589 evas_event_freeze(evas_object_evas_get(wd->obj));
2590 EINA_LIST_FOREACH(wd->group_items, l, git)
2592 if (git->item->want_realize)
2595 _item_realize(git, 0, EINA_FALSE);
2596 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2597 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2598 evas_object_show(VIEW(git));
2599 evas_object_raise(VIEW(git));
2601 else if (!git->item->want_realize && git->realized)
2604 _elm_genlist_item_unrealize(git, EINA_FALSE);
2607 evas_event_thaw(evas_object_evas_get(wd->obj));
2608 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2612 _must_recalc_idler(void *data)
2614 Widget_Data *wd = data;
2615 if (wd->calc_job) ecore_job_del(wd->calc_job);
2616 wd->calc_job = ecore_job_add(_calc_job, wd);
2617 wd->must_recalc_idler = NULL;
2618 return ECORE_CALLBACK_CANCEL;
2622 _scroll_item(Widget_Data *wd)
2624 Elm_Gen_Item *it = NULL;
2625 Evas_Coord gith = 0;
2626 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2627 if (!wd->show_item) return;
2629 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2631 dx = it->x + it->item->block->x;
2632 dy = it->y + it->item->block->y;
2633 dw = it->item->block->w;
2635 switch (wd->scrollto_type)
2637 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2638 if (it->item->group_item) gith = it->item->group_item->item->h;
2641 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2642 dy += ((it->item->h / 2) - (oh / 2));
2644 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2646 if ((wd->expanded_item) &&
2647 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2648 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2650 it = wd->expanded_item;
2651 if (it->item->group_item) gith = it->item->group_item->item->h;
2652 dx = it->x + it->item->block->x;
2653 dy = it->y + it->item->block->y - gith;
2654 dw = it->item->block->w;
2658 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2659 gith = it->item->group_item->item->h;
2666 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2668 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2670 it->item->showme = EINA_FALSE;
2671 wd->show_item = NULL;
2672 wd->auto_scroll_enabled = EINA_FALSE;
2673 wd->check_scroll = EINA_FALSE;
2677 _calc_job(void *data)
2679 Widget_Data *wd = data;
2680 Item_Block *itb, *chb = NULL;
2681 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2682 Evas_Coord pan_w = 0, pan_h = 0;
2684 Eina_Bool minw_change = EINA_FALSE;
2685 Eina_Bool did_must_recalc = EINA_FALSE;
2688 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2689 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2694 evas_event_freeze(evas_object_evas_get(wd->obj));
2695 EINA_INLIST_FOREACH(wd->blocks, itb)
2697 Eina_Bool showme = EINA_FALSE;
2700 showme = itb->showme;
2701 itb->showme = EINA_FALSE;
2704 if (itb->realized) _item_block_unrealize(itb);
2706 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2708 if (itb->must_recalc)
2712 EINA_LIST_FOREACH(itb->items, l, it)
2713 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2714 itb->changed = EINA_TRUE;
2715 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2716 if (itb->realized) _item_block_unrealize(itb);
2717 itb->must_recalc = EINA_FALSE;
2719 showme = _item_block_recalc(itb, in, EINA_FALSE);
2725 if (minw == -1) minw = itb->minw;
2726 else if ((!itb->must_recalc) && (minw < itb->minw))
2729 minw_change = EINA_TRUE;
2734 minw_change = EINA_TRUE;
2740 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2741 wd->check_scroll = EINA_TRUE;
2745 EINA_INLIST_FOREACH(wd->blocks, itb)
2751 if ((chb) && (EINA_INLIST_GET(chb)->next))
2753 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2755 if (itb->realized) _item_block_unrealize(itb);
2758 wd->realminw = minw;
2759 if (minw < wd->w) minw = wd->w;
2760 if ((minw != wd->minw) || (minh != wd->minh))
2764 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2765 _sizing_eval(wd->obj);
2766 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2771 it = wd->anchor_item;
2772 it_y = wd->anchor_y;
2773 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2774 it->item->block->y + it->y + it_y);
2775 wd->anchor_item = it;
2776 wd->anchor_y = it_y;
2779 if (did_must_recalc)
2781 if (!wd->must_recalc_idler)
2782 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2784 if (wd->check_scroll)
2786 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2787 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2788 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2789 switch (wd->scrollto_type)
2791 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2794 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2797 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2804 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2805 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2811 wd->calc_job = NULL;
2812 evas_object_smart_changed(wd->pan_smart);
2813 evas_event_thaw(evas_object_evas_get(wd->obj));
2814 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2818 _update_job(void *data)
2820 Widget_Data *wd = data;
2824 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2826 wd->update_job = NULL;
2829 evas_event_freeze(evas_object_evas_get(wd->obj));
2830 EINA_INLIST_FOREACH(wd->blocks, itb)
2832 Evas_Coord itminw, itminh;
2839 _item_block_position(itb, num);
2843 recalc = EINA_FALSE;
2844 EINA_LIST_FOREACH(itb->items, l2, it)
2846 if (it->item->updateme)
2848 itminw = it->item->minw;
2849 itminh = it->item->minh;
2851 it->item->updateme = EINA_FALSE;
2854 _elm_genlist_item_unrealize(it, EINA_FALSE);
2855 _item_realize(it, num, EINA_FALSE);
2856 position = EINA_TRUE;
2860 _item_realize(it, num, EINA_TRUE);
2861 _elm_genlist_item_unrealize(it, EINA_TRUE);
2863 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2868 itb->updateme = EINA_FALSE;
2871 position = EINA_TRUE;
2872 itb->changed = EINA_TRUE;
2873 _item_block_recalc(itb, num0, EINA_FALSE);
2874 _item_block_position(itb, num0);
2879 if (wd->calc_job) ecore_job_del(wd->calc_job);
2880 wd->calc_job = ecore_job_add(_calc_job, wd);
2882 evas_event_thaw(evas_object_evas_get(wd->obj));
2883 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2887 _pan_set(Evas_Object *obj,
2891 Pan *sd = evas_object_smart_data_get(obj);
2895 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2899 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2901 if ((itb->y + itb->h) > y)
2906 EINA_LIST_FOREACH(itb->items, l2, it)
2908 if ((itb->y + it->y) >= y)
2910 sd->wd->anchor_item = it;
2911 sd->wd->anchor_y = -(itb->y + it->y - y);
2918 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2922 _pan_get(Evas_Object *obj,
2926 Pan *sd = evas_object_smart_data_get(obj);
2929 if (x) *x = sd->wd->pan_x;
2930 if (y) *y = sd->wd->pan_y;
2934 _pan_max_get(Evas_Object *obj,
2938 Pan *sd = evas_object_smart_data_get(obj);
2942 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2943 ow = sd->wd->minw - ow;
2945 oh = sd->wd->minh - oh;
2952 _pan_min_get(Evas_Object *obj __UNUSED__,
2961 _pan_child_size_get(Evas_Object *obj,
2965 Pan *sd = evas_object_smart_data_get(obj);
2968 if (w) *w = sd->wd->minw;
2969 if (h) *h = sd->wd->minh;
2973 _pan_add(Evas_Object *obj)
2976 Evas_Object_Smart_Clipped_Data *cd;
2979 cd = evas_object_smart_data_get(obj);
2982 sd->__clipped_data = *cd;
2984 evas_object_smart_data_set(obj, sd);
2988 _pan_del(Evas_Object *obj)
2990 Pan *sd = evas_object_smart_data_get(obj);
2995 ecore_job_del(sd->resize_job);
2996 sd->resize_job = NULL;
3002 _pan_resize_job(void *data)
3006 _sizing_eval(sd->wd->obj);
3007 sd->resize_job = NULL;
3011 _pan_resize(Evas_Object *obj,
3015 Pan *sd = evas_object_smart_data_get(obj);
3019 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3020 if ((ow == w) && (oh == h)) return;
3021 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3024 if (sd->resize_job) ecore_job_del(sd->resize_job);
3025 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3027 sd->wd->pan_changed = EINA_TRUE;
3028 evas_object_smart_changed(obj);
3029 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3030 sd->wd->calc_job = NULL;
3032 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3033 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
3038 _pan_calculate(Evas_Object *obj)
3040 Pan *sd = evas_object_smart_data_get(obj);
3042 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3048 evas_event_freeze(evas_object_evas_get(obj));
3050 if (sd->wd->pan_changed)
3053 sd->wd->pan_changed = EINA_FALSE;
3056 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3057 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3058 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3060 git->item->want_realize = EINA_FALSE;
3063 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3065 if (!sd->wd->tree_effect_animator)
3067 _item_tree_effect_before(sd->wd->expanded_item);
3068 evas_object_raise(sd->wd->alpha_bg);
3069 evas_object_show(sd->wd->alpha_bg);
3070 sd->wd->start_time = ecore_time_get();
3071 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3075 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3077 itb->w = sd->wd->minw;
3078 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3079 itb->y - sd->wd->pan_y + oy,
3081 cvx, cvy, cvw, cvh))
3083 if ((!itb->realized) || (itb->changed))
3084 _item_block_realize(itb);
3085 _item_block_position(itb, in);
3089 if (itb->realized) _item_block_unrealize(itb);
3093 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3094 _group_items_recalc(sd->wd);
3095 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3097 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3098 sd->wd->reorder_pan_move = EINA_TRUE;
3099 else sd->wd->reorder_pan_move = EINA_FALSE;
3100 evas_object_raise(sd->wd->VIEW(reorder_it));
3101 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3102 sd->wd->start_time = ecore_loop_time_get();
3105 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3106 _item_auto_scroll(sd->wd);
3108 evas_event_thaw(evas_object_evas_get(obj));
3109 evas_event_thaw_eval(evas_object_evas_get(obj));
3113 _pan_move(Evas_Object *obj,
3114 Evas_Coord x __UNUSED__,
3115 Evas_Coord y __UNUSED__)
3117 Pan *sd = evas_object_smart_data_get(obj);
3121 sd->wd->pan_changed = EINA_TRUE;
3122 evas_object_smart_changed(obj);
3123 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3124 sd->wd->calc_job = NULL;
3128 _hold_on(void *data __UNUSED__,
3130 void *event_info __UNUSED__)
3132 Widget_Data *wd = elm_widget_data_get(obj);
3134 elm_smart_scroller_hold_set(wd->scr, 1);
3138 _hold_off(void *data __UNUSED__,
3140 void *event_info __UNUSED__)
3142 Widget_Data *wd = elm_widget_data_get(obj);
3144 elm_smart_scroller_hold_set(wd->scr, 0);
3148 _freeze_on(void *data __UNUSED__,
3150 void *event_info __UNUSED__)
3152 Widget_Data *wd = elm_widget_data_get(obj);
3154 elm_smart_scroller_freeze_set(wd->scr, 1);
3158 _freeze_off(void *data __UNUSED__,
3160 void *event_info __UNUSED__)
3162 Widget_Data *wd = elm_widget_data_get(obj);
3164 elm_smart_scroller_freeze_set(wd->scr, 0);
3168 _scr_anim_start(void *data,
3169 Evas_Object *obj __UNUSED__,
3170 void *event_info __UNUSED__)
3172 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3176 _scr_anim_stop(void *data,
3177 Evas_Object *obj __UNUSED__,
3178 void *event_info __UNUSED__)
3180 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3184 _scr_drag_start(void *data,
3185 Evas_Object *obj __UNUSED__,
3186 void *event_info __UNUSED__)
3188 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3192 _scr_drag_stop(void *data,
3193 Evas_Object *obj __UNUSED__,
3194 void *event_info __UNUSED__)
3196 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3200 _edge_left(void *data,
3201 Evas_Object *scr __UNUSED__,
3202 void *event_info __UNUSED__)
3204 Evas_Object *obj = data;
3205 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3209 _edge_right(void *data,
3210 Evas_Object *scr __UNUSED__,
3211 void *event_info __UNUSED__)
3213 Evas_Object *obj = data;
3214 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3218 _edge_top(void *data,
3219 Evas_Object *scr __UNUSED__,
3220 void *event_info __UNUSED__)
3222 Evas_Object *obj = data;
3223 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3227 _edge_bottom(void *data,
3228 Evas_Object *scr __UNUSED__,
3229 void *event_info __UNUSED__)
3231 Evas_Object *obj = data;
3232 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3236 _decorate_item_realize(Elm_Gen_Item *it)
3240 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3242 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3243 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3244 edje_object_scale_set(it->item->deco_it_view,
3245 elm_widget_scale_get(WIDGET(it)) *
3246 _elm_config->scale);
3247 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3248 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3250 strncpy(buf, "item", sizeof(buf));
3251 if (it->wd->mode == ELM_LIST_COMPRESS)
3252 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3254 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3255 strncat(buf, "/", sizeof(buf) - strlen(buf));
3256 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3258 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3259 elm_widget_style_get(WIDGET(it)));
3260 edje_object_mirrored_set(it->item->deco_it_view,
3261 elm_widget_mirrored_get(WIDGET(it)));
3263 /* signal callback add */
3264 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3266 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3268 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3271 /* text_get, content_get, state_get */
3272 /* FIXME: If you see that assert, please notify us and we
3273 will clean our mess */
3274 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3276 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3277 if (!it->item->deco_it_contents)
3278 it->item->deco_it_contents =
3279 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3280 it->item->deco_it_content_objs =
3281 _item_mode_content_realize(it, it->item->deco_it_view,
3282 &it->item->deco_it_contents, NULL,
3283 &it->item->deco_it_content_objs);
3284 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3285 edje_object_part_swallow(it->item->deco_it_view,
3286 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3289 it->want_unrealize = EINA_FALSE;
3290 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3291 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3295 _decorate_item_unrealize(Elm_Gen_Item *it)
3297 Widget_Data *wd = it->wd;
3298 Evas_Object *content;
3299 if (!it->item->deco_it_view) return;
3301 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3302 elm_widget_stringlist_free(it->item->deco_it_texts);
3303 it->item->deco_it_texts = NULL;
3304 elm_widget_stringlist_free(it->item->deco_it_contents);
3305 it->item->deco_it_contents = NULL;
3306 elm_widget_stringlist_free(it->item->deco_it_states);
3308 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3309 evas_object_del(content);
3311 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3312 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3313 evas_object_del(it->item->deco_it_view);
3314 it->item->deco_it_view = NULL;
3316 if (wd->mode_item == it)
3317 wd->mode_item = NULL;
3318 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3319 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3323 _decorate_item_set(Elm_Gen_Item *it)
3326 Widget_Data *wd = it->wd;
3331 it->item->nocache_once = EINA_TRUE;
3333 if (wd->scr_hold_timer)
3335 ecore_timer_del(wd->scr_hold_timer);
3336 wd->scr_hold_timer = NULL;
3338 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3339 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3341 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3342 _decorate_item_realize(it);
3343 if (it->item->group_item)
3344 evas_object_raise(it->item->VIEW(group_item));
3345 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3346 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3347 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3349 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3350 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3354 _decorate_item_unset(Widget_Data *wd)
3357 if (!wd->mode_item) return;
3358 char buf[1024], buf2[1024];
3362 it->item->nocache_once = EINA_TRUE;
3364 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3365 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3367 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3368 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3370 wd->mode_item = NULL;
3374 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3376 if ((!it) || (!it->wd->decorate_all_mode)) return;
3377 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3378 evas_object_move(it->deco_all_view, itx, ity);
3382 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3385 const char *stacking_even;
3386 const char *stacking;
3388 if ((!it) || (it->item->decorate_all_item_realized) ||
3389 (it->generation < it->wd->generation))
3392 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3393 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3394 _elm_config->scale);
3395 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3396 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3398 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3399 strncpy(buf, "tree", sizeof(buf));
3400 else strncpy(buf, "item", sizeof(buf));
3401 if (it->wd->mode == ELM_LIST_COMPRESS)
3402 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3404 strncat(buf, "/", sizeof(buf) - strlen(buf));
3405 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3407 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3408 elm_widget_style_get(WIDGET(it)));
3410 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3411 if (!stacking_even) stacking_even = "above";
3412 it->item->stacking_even = !!strcmp("above", stacking_even);
3414 stacking = edje_object_data_get(VIEW(it), "stacking");
3415 if (!stacking) stacking = "yes";
3416 it->item->nostacking = !!strcmp("yes", stacking);
3418 edje_object_mirrored_set(it->deco_all_view,
3419 elm_widget_mirrored_get(WIDGET(it)));
3421 _elm_genlist_item_odd_even_update(it);
3422 _elm_genlist_item_state_update(it, NULL);
3424 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3425 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3427 _item_mouse_callbacks_del(it, VIEW(it));
3428 _item_mouse_callbacks_add(it, it->deco_all_view);
3430 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3431 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3432 if (!it->item->deco_all_contents)
3433 it->item->deco_all_contents =
3434 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "contents"));
3435 it->item->deco_all_content_objs =
3436 _item_mode_content_realize(it, it->deco_all_view,
3437 &it->item->deco_all_contents, NULL,
3438 &it->item->deco_all_content_objs);
3439 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3440 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3442 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3443 evas_object_show(it->deco_all_view);
3445 it->item->decorate_all_item_realized = EINA_TRUE;
3446 it->want_unrealize = EINA_FALSE;
3450 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3453 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3455 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3456 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3457 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3458 _elm_genlist_item_odd_even_update(it);
3459 _elm_genlist_item_state_update(it, NULL);
3461 evas_object_del(it->deco_all_view);
3462 it->deco_all_view = NULL;
3463 elm_widget_stringlist_free(it->item->deco_all_texts);
3464 it->item->deco_all_texts = NULL;
3465 elm_widget_stringlist_free(it->item->deco_all_contents);
3466 it->item->deco_all_contents = NULL;
3467 elm_widget_stringlist_free(it->item->deco_all_states);
3468 it->item->deco_all_states = NULL;
3469 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3470 evas_object_del(icon);
3471 edje_object_message_signal_process(it->deco_all_view);
3472 _item_mouse_callbacks_del(it, it->deco_all_view);
3473 _item_mouse_callbacks_add(it, VIEW(it));
3475 it->item->decorate_all_item_realized = EINA_FALSE;
3479 _item_auto_scroll(Widget_Data *wd)
3482 Elm_Gen_Item *tmp_item = NULL;
3484 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3486 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3487 if (!tmp_item) return;
3488 wd->show_item = tmp_item;
3489 wd->bring_in = EINA_TRUE;
3490 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3491 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3493 wd->show_item->item->showme = EINA_TRUE;
3494 wd->auto_scroll_enabled = EINA_FALSE;
3502 elm_genlist_add(Evas_Object *parent)
3507 Evas_Coord minw, minh;
3508 static Evas_Smart *smart = NULL;
3512 static Evas_Smart_Class sc;
3514 evas_object_smart_clipped_smart_set(&_pan_sc);
3516 sc.name = "elm_genlist_pan";
3517 sc.version = EVAS_SMART_CLASS_VERSION;
3520 sc.resize = _pan_resize;
3521 sc.move = _pan_move;
3522 sc.calculate = _pan_calculate;
3523 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3526 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3528 ELM_SET_WIDTYPE(widtype, "genlist");
3530 elm_widget_type_set(obj, "genlist");
3531 elm_widget_sub_object_add(parent, obj);
3532 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3533 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3534 elm_widget_data_set(obj, wd);
3535 elm_widget_del_hook_set(obj, _del_hook);
3536 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3537 elm_widget_theme_hook_set(obj, _theme_hook);
3538 elm_widget_can_focus_set(obj, EINA_TRUE);
3539 elm_widget_event_hook_set(obj, _event_hook);
3540 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3541 elm_widget_translate_hook_set(obj, _translate_hook);
3544 wd->scr = elm_smart_scroller_add(e);
3545 elm_smart_scroller_widget_set(wd->scr, obj);
3546 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3547 elm_widget_style_get(obj));
3548 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3549 _elm_config->thumbscroll_bounce_enable);
3550 elm_widget_resize_object_set(obj, wd->scr);
3552 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3553 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3554 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3555 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3556 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3557 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3558 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3559 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3562 wd->mode = ELM_LIST_SCROLL;
3563 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3564 wd->item_cache_max = wd->max_items_per_block * 2;
3565 wd->longpress_timeout = _elm_config->longpress_timeout;
3566 wd->highlight = EINA_TRUE;
3568 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3569 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3570 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3571 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3573 wd->pan_smart = evas_object_smart_add(e, smart);
3574 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3577 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3578 _pan_set, _pan_get, _pan_max_get,
3579 _pan_min_get, _pan_child_size_get);
3581 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3583 evas_object_size_hint_min_set(obj, minw, minh);
3585 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3587 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3593 _item_select(Elm_Gen_Item *it)
3595 Evas_Object *obj = WIDGET(it);
3597 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3598 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3599 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3603 it->selected = EINA_TRUE;
3604 it->wd->selected = eina_list_append(it->wd->selected, it);
3606 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3608 evas_object_ref(obj);
3611 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3612 if (it->generation == it->wd->generation)
3613 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3616 if ((it->wd->clear_me) && (!it->wd->walking))
3617 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3620 if ((!it->walking) && (it->generation < it->wd->generation))
3625 elm_widget_item_free(it);
3629 it->wd->last_selected_item = (Elm_Object_Item *)it;
3631 evas_object_unref(obj);
3634 static Evas_Object *
3635 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3637 return edje_object_part_swallow_get(VIEW(it), part);
3641 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3643 Evas_Object *prev_obj;
3645 if (content && part)
3647 if (eina_list_data_find(it->content_objs, content)) return;
3648 prev_obj = _item_content_unset_hook(it, part);
3649 if (prev_obj) evas_object_del(prev_obj);
3650 it->content_objs = eina_list_append(it->content_objs, content);
3651 edje_object_part_swallow(VIEW(it), part, content);
3655 static Evas_Object *
3656 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3659 obj = edje_object_part_swallow_get(VIEW(it), part);
3660 if (!obj) return NULL;
3661 it->content_objs = eina_list_remove(it->content_objs, obj);
3662 edje_object_part_unswallow(VIEW(it), obj);
3667 _item_text_hook(Elm_Gen_Item *it, const char *part)
3669 if (!it->itc->func.text_get) return NULL;
3670 return edje_object_part_text_get(VIEW(it), part);
3674 _item_disable_hook(Elm_Object_Item *it)
3678 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3680 if (_it->generation < _it->wd->generation) return;
3683 elm_genlist_item_selected_set(it, EINA_FALSE);
3687 if (elm_widget_item_disabled_get(it))
3689 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
3690 if (_it->deco_all_view)
3691 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
3695 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
3696 if (_it->deco_all_view)
3697 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
3699 EINA_LIST_FOREACH(_it->content_objs, l, obj)
3700 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
3705 _item_del_pre_hook(Elm_Object_Item *it)
3707 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3709 if ((_it->relcount > 0) || (_it->walking > 0))
3711 elm_genlist_item_subitems_clear(it);
3712 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
3713 _elm_genlist_item_del_notserious(_it);
3714 if (_it->item->block)
3716 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
3717 _it->item->block->changed = EINA_TRUE;
3718 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
3719 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
3723 _it->parent->item->items =
3724 eina_list_remove(_it->parent->item->items, it);
3734 _item_signal_emit_hook(Elm_Object_Item *it,
3735 const char *emission,
3738 edje_object_signal_emit(VIEW(it), emission, source);
3742 _elm_genlist_item_new(Widget_Data *wd,
3743 const Elm_Gen_Item_Class *itc,
3745 Elm_Gen_Item *parent,
3747 const void *func_data)
3751 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3752 if (!it) return NULL;
3754 it->generation = wd->generation;
3756 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
3757 it->base.data = data;
3758 it->parent = parent;
3759 it->func.func = func;
3760 it->func.data = func_data;
3761 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3762 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3763 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3764 elm_widget_item_text_get_hook_set(it, _item_text_hook);
3765 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3766 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3767 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
3770 it->sel_cb = (Ecore_Cb)_item_select;
3775 static Elm_Gen_Item *
3776 _item_new(Widget_Data *wd,
3777 const Elm_Genlist_Item_Class *itc,
3779 Elm_Gen_Item *parent,
3780 Elm_Genlist_Item_Type type,
3782 const void *func_data)
3784 Elm_Gen_Item *it, *it2;
3787 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3788 if (!it) return NULL;
3789 it->item = ELM_NEW(Elm_Gen_Item_Type);
3790 it->item->type = type;
3791 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
3792 it->item->expanded_depth = 0;
3793 ELM_GEN_ITEM_SETUP(it);
3796 if (it->parent->group)
3797 it->item->group_item = parent;
3798 else if (it->parent->item->group_item)
3799 it->item->group_item = it->parent->item->group_item;
3801 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3803 if (!it2->parent->group) depth += 1;
3805 it->item->expanded_depth = depth;
3811 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3815 itb = calloc(1, sizeof(Item_Block));
3816 if (!itb) return NULL;
3820 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3821 _item_block_position_update(wd->blocks, 0);
3825 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3826 itb->position_update = EINA_TRUE;
3827 if (wd->blocks != EINA_INLIST_GET(itb))
3829 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3840 _item_block_add(Widget_Data *wd,
3843 Item_Block *itb = NULL;
3850 itb = calloc(1, sizeof(Item_Block));
3851 if (!itb) return EINA_FALSE;
3853 if (!it->item->rel->item->block)
3856 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3857 itb->items = eina_list_append(itb->items, it);
3858 itb->position_update = EINA_TRUE;
3859 it->position = eina_list_count(itb->items);
3860 it->position_update = EINA_TRUE;
3862 if (wd->blocks != EINA_INLIST_GET(itb))
3864 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3875 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3876 if (it->item->before)
3878 wd->blocks = eina_inlist_prepend_relative
3879 (wd->blocks, EINA_INLIST_GET(itb),
3880 EINA_INLIST_GET(it->item->rel->item->block));
3882 eina_list_prepend_relative_list(itb->items, it, tmp);
3884 /* Update index from where we prepended */
3885 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3886 _item_block_position_update(EINA_INLIST_GET(itb),
3887 it->item->rel->item->block->position);
3891 wd->blocks = eina_inlist_append_relative
3892 (wd->blocks, EINA_INLIST_GET(itb),
3893 EINA_INLIST_GET(it->item->rel->item->block));
3895 eina_list_append_relative_list(itb->items, it, tmp);
3897 /* Update block index from where we appended */
3898 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3899 _item_block_position_update(EINA_INLIST_GET(itb),
3900 it->item->rel->item->block->position + 1);
3906 if (it->item->before)
3910 itb = (Item_Block *)(wd->blocks);
3911 if (itb->count >= wd->max_items_per_block)
3913 itb = _item_block_new(wd, EINA_TRUE);
3914 if (!itb) return EINA_FALSE;
3919 itb = _item_block_new(wd, EINA_TRUE);
3920 if (!itb) return EINA_FALSE;
3922 itb->items = eina_list_prepend(itb->items, it);
3924 _item_position_update(itb->items, 0);
3930 itb = (Item_Block *)(wd->blocks->last);
3931 if (itb->count >= wd->max_items_per_block)
3933 itb = _item_block_new(wd, EINA_FALSE);
3934 if (!itb) return EINA_FALSE;
3939 itb = _item_block_new(wd, EINA_FALSE);
3940 if (!itb) return EINA_FALSE;
3942 itb->items = eina_list_append(itb->items, it);
3943 it->position = eina_list_count(itb->items);
3951 if (it->item->rel->item->queued)
3953 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3954 on sorted insertion order, so the queue is not always ordered like the item list.
3955 This lead to issue where we depend on an item that is not yet created. As a quick
3956 work around, we reschedule the calc of the item and stop reordering the list to
3957 prevent any nasty issue to show up here.
3959 wd->queue = eina_list_append(wd->queue, it);
3960 wd->requeued = EINA_TRUE;
3961 it->item->queued = EINA_TRUE;
3964 itb = it->item->rel->item->block;
3965 if (!itb) goto newblock;
3966 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3967 if (it->item->before)
3969 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3970 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3974 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3975 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3979 itb->changed = EINA_TRUE;
3980 it->item->block = itb;
3981 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3982 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3985 it->item->rel->relcount--;
3986 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3988 _item_del(it->item->rel);
3989 elm_widget_item_free(it->item->rel);
3991 it->item->rel = NULL;
3993 if (itb->count > itb->wd->max_items_per_block)
3998 Eina_Bool done = EINA_FALSE;
4000 newc = itb->count / 2;
4002 if (EINA_INLIST_GET(itb)->prev)
4004 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4006 if (itbp->count + newc < wd->max_items_per_block / 2)
4008 /* moving items to previous block */
4009 while ((itb->count > newc) && (itb->items))
4011 it2 = eina_list_data_get(itb->items);
4012 itb->items = eina_list_remove_list(itb->items, itb->items);
4015 itbp->items = eina_list_append(itbp->items, it2);
4016 it2->item->block = itbp;
4024 if (!done && EINA_INLIST_GET(itb)->next)
4026 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4028 if (itbn->count + newc < wd->max_items_per_block / 2)
4030 /* moving items to next block */
4031 while ((itb->count > newc) && (itb->items))
4035 l = eina_list_last(itb->items);
4036 it2 = eina_list_data_get(l);
4037 itb->items = eina_list_remove_list(itb->items, l);
4040 itbn->items = eina_list_prepend(itbn->items, it2);
4041 it2->item->block = itbn;
4051 /* moving items to new block */
4052 itb2 = calloc(1, sizeof(Item_Block));
4053 if (!itb2) return EINA_FALSE;
4056 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4057 EINA_INLIST_GET(itb));
4058 itb2->changed = EINA_TRUE;
4059 while ((itb->count > newc) && (itb->items))
4063 l = eina_list_last(itb->items);
4065 itb->items = eina_list_remove_list(itb->items, l);
4068 itb2->items = eina_list_prepend(itb2->items, it2);
4069 it2->item->block = itb2;
4079 _queue_process(Widget_Data *wd)
4082 Eina_Bool showme = EINA_FALSE;
4085 t0 = ecore_loop_time_get();
4086 //evas_event_freeze(evas_object_evas_get(wd->obj));
4087 for (n = 0; (wd->queue) && (n < 128); n++)
4091 it = eina_list_data_get(wd->queue);
4092 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4093 it->item->queued = EINA_FALSE;
4094 if (!_item_block_add(wd, it)) continue;
4096 _item_block_realize(it->item->block);
4097 t = ecore_time_get();
4098 if (it->item->block->changed)
4100 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4101 it->item->block->changed = 0;
4102 if (wd->pan_changed)
4104 if (wd->calc_job) ecore_job_del(wd->calc_job);
4105 wd->calc_job = NULL;
4107 wd->pan_changed = EINA_FALSE;
4110 if (showme) it->item->block->showme = EINA_TRUE;
4111 /* same as eina_inlist_count > 1 */
4112 if (wd->blocks && wd->blocks->next)
4114 if ((t - t0) > (ecore_animator_frametime_get())) break;
4117 //evas_event_thaw(evas_object_evas_get(wd->obj));
4118 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4123 _idle_process(void *data, Eina_Bool *wakeup)
4125 Widget_Data *wd = data;
4128 //static double q_start = 0.0;
4129 //if (q_start == 0.0) q_start = ecore_time_get();
4131 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4135 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4137 return ECORE_CALLBACK_CANCEL;
4139 return ECORE_CALLBACK_RENEW;
4143 _item_idle_enterer(void *data)
4145 Widget_Data *wd = data;
4146 Eina_Bool wakeup = EINA_FALSE;
4147 Eina_Bool ok = _idle_process(data, &wakeup);
4152 if (wd->calc_job) ecore_job_del(wd->calc_job);
4153 wd->calc_job = ecore_job_add(_calc_job, wd);
4155 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4160 _item_queue(Widget_Data *wd,
4164 if (it->item->queued) return;
4165 it->item->queued = EINA_TRUE;
4166 if (cb && !wd->requeued)
4167 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4169 wd->queue = eina_list_append(wd->queue, it);
4170 // FIXME: why does a freeze then thaw here cause some genlist
4171 // elm_genlist_item_append() to be much much slower?
4172 // evas_event_freeze(evas_object_evas_get(wd->obj));
4173 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4175 if (wd->queue_idle_enterer)
4177 ecore_idle_enterer_del(wd->queue_idle_enterer);
4178 wd->queue_idle_enterer = NULL;
4182 // evas_event_thaw(evas_object_evas_get(wd->obj));
4183 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4184 if (!wd->queue_idle_enterer)
4185 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4189 _elm_genlist_item_compare(const void *data, const void *data1)
4191 const Elm_Gen_Item *it, *item1;
4192 it = ELM_GEN_ITEM_FROM_INLIST(data);
4193 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4194 return it->wd->item_compare_cb(it, item1);
4198 _elm_genlist_item_list_compare(const void *data, const void *data1)
4200 const Elm_Gen_Item *it = data;
4201 const Elm_Gen_Item *item1 = data1;
4202 return it->wd->item_compare_cb(it, item1);
4205 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4207 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4212 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4213 _item_block_del(it);
4215 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4216 it->item->rel = after;
4217 it->item->rel->relcount++;
4218 it->item->before = EINA_FALSE;
4219 if (after->item->group_item) it->item->group_item = after->item->group_item;
4220 _item_queue(it->wd, it, NULL);
4222 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4225 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4227 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4230 if (!before) return;
4232 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4233 _item_block_del(it);
4234 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4235 it->item->rel = before;
4236 it->item->rel->relcount++;
4237 it->item->before = EINA_TRUE;
4238 if (before->item->group_item) it->item->group_item = before->item->group_item;
4239 _item_queue(it->wd, it, NULL);
4241 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4245 elm_genlist_items_count(const Evas_Object *obj)
4247 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4248 Widget_Data *wd = elm_widget_data_get(obj);
4250 return wd->item_count;
4253 EAPI Elm_Object_Item *
4254 elm_genlist_item_append(Evas_Object *obj,
4255 const Elm_Genlist_Item_Class *itc,
4257 Elm_Object_Item *parent,
4258 Elm_Genlist_Item_Type type,
4260 const void *func_data)
4262 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4263 Widget_Data *wd = elm_widget_data_get(obj);
4264 if (!wd) return NULL;
4265 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4267 if (!it) return NULL;
4271 wd->group_items = eina_list_append(wd->group_items, it);
4272 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4273 it->item->rel = NULL;
4277 Elm_Gen_Item *it2 = NULL;
4278 Eina_List *ll = eina_list_last(it->parent->item->items);
4279 if (ll) it2 = ll->data;
4280 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4281 if (!it2) it2 = it->parent;
4283 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4284 EINA_INLIST_GET(it2));
4285 it->item->rel = it2;
4286 it->item->rel->relcount++;
4288 it->item->before = EINA_FALSE;
4289 _item_queue(wd, it, NULL);
4290 return (Elm_Object_Item *)it;
4293 EAPI Elm_Object_Item *
4294 elm_genlist_item_prepend(Evas_Object *obj,
4295 const Elm_Genlist_Item_Class *itc,
4297 Elm_Object_Item *parent,
4298 Elm_Genlist_Item_Type type,
4300 const void *func_data)
4302 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4303 Widget_Data *wd = elm_widget_data_get(obj);
4304 if (!wd) return NULL;
4305 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4307 if (!it) return NULL;
4311 wd->group_items = eina_list_prepend(wd->group_items, it);
4312 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4313 it->item->rel = NULL;
4317 Elm_Gen_Item *it2 = NULL;
4318 Eina_List *ll = it->parent->item->items;
4319 if (ll) it2 = ll->data;
4320 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4321 if (!it2) it2 = it->parent;
4323 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4324 EINA_INLIST_GET(it2));
4325 it->item->rel = it2;
4326 it->item->rel->relcount++;
4328 it->item->before = EINA_TRUE;
4329 _item_queue(wd, it, NULL);
4330 return (Elm_Object_Item *)it;
4333 EAPI Elm_Object_Item *
4334 elm_genlist_item_insert_after(Evas_Object *obj,
4335 const Elm_Genlist_Item_Class *itc,
4337 Elm_Object_Item *parent,
4338 Elm_Object_Item *after,
4339 Elm_Genlist_Item_Type type,
4341 const void *func_data)
4343 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4344 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4345 Widget_Data *wd = elm_widget_data_get(obj);
4346 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4347 if (!wd) return NULL;
4348 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4349 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4351 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4353 if (!it) return NULL;
4356 if ((it->group) && (_after->group))
4357 wd->group_items = eina_list_append_relative(wd->group_items, it,
4362 it->parent->item->items =
4363 eina_list_append_relative(it->parent->item->items, it, _after);
4365 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4366 EINA_INLIST_GET(_after));
4367 it->item->rel = _after;
4368 it->item->rel->relcount++;
4369 it->item->before = EINA_FALSE;
4370 _item_queue(wd, it, NULL);
4371 return (Elm_Object_Item *)it;
4374 EAPI Elm_Object_Item *
4375 elm_genlist_item_insert_before(Evas_Object *obj,
4376 const Elm_Genlist_Item_Class *itc,
4378 Elm_Object_Item *parent,
4379 Elm_Object_Item *before,
4380 Elm_Genlist_Item_Type type,
4382 const void *func_data)
4384 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4385 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4386 Widget_Data *wd = elm_widget_data_get(obj);
4387 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4388 if (!wd) return NULL;
4389 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4390 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4392 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4394 if (!it) return NULL;
4397 if (it->group && _before->group)
4398 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4403 it->parent->item->items =
4404 eina_list_prepend_relative(it->parent->item->items, it, _before);
4406 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4407 EINA_INLIST_GET(_before));
4408 it->item->rel = _before;
4409 it->item->rel->relcount++;
4410 it->item->before = EINA_TRUE;
4411 _item_queue(wd, it, NULL);
4412 return (Elm_Object_Item *)it;
4415 EAPI Elm_Object_Item *
4416 elm_genlist_item_sorted_insert(Evas_Object *obj,
4417 const Elm_Genlist_Item_Class *itc,
4419 Elm_Object_Item *parent,
4420 Elm_Genlist_Item_Type type,
4421 Eina_Compare_Cb comp,
4423 const void *func_data)
4425 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4426 Widget_Data *wd = elm_widget_data_get(obj);
4427 if (!wd) return NULL;
4428 Elm_Gen_Item *rel = NULL;
4429 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4431 if (!it) return NULL;
4433 wd->item_compare_cb = comp;
4440 l = eina_list_search_sorted_near_list(it->parent->item->items,
4441 _elm_genlist_item_list_compare,
4445 rel = eina_list_data_get(l);
4449 if (cmp_result >= 0)
4451 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4452 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4453 it->item->before = EINA_FALSE;
4455 else if (cmp_result < 0)
4457 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4458 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4459 it->item->before = EINA_TRUE;
4466 wd->state = eina_inlist_sorted_state_new();
4467 eina_inlist_sorted_state_init(wd->state, wd->items);
4468 wd->requeued = EINA_FALSE;
4472 wd->group_items = eina_list_append(wd->group_items, it);
4474 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4475 _elm_genlist_item_compare, wd->state);
4477 if (EINA_INLIST_GET(it)->next)
4479 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4480 it->item->before = EINA_TRUE;
4482 else if (EINA_INLIST_GET(it)->prev)
4484 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4485 it->item->before = EINA_FALSE;
4491 it->item->rel = rel;
4492 it->item->rel->relcount++;
4495 _item_queue(wd, it, _elm_genlist_item_list_compare);
4497 return (Elm_Object_Item *)it;
4501 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4503 Eina_Inlist *next, *l;
4504 Widget_Data *wd = elm_widget_data_get(obj);
4507 if (!standby) wd->generation++;
4511 eina_inlist_sorted_state_free(wd->state);
4515 if (wd->walking > 0)
4517 wd->clear_me = EINA_TRUE;
4520 evas_event_freeze(evas_object_evas_get(wd->obj));
4521 for (l = wd->items, next = l ? l->next : NULL;
4523 l = next, next = next ? next->next : NULL)
4525 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4527 if (it->generation < wd->generation)
4529 Elm_Gen_Item *itn = NULL;
4531 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4532 if (itn) itn->walking++; /* prevent early death of subitem */
4534 elm_widget_item_free(it);
4535 if (itn) itn->walking--;
4538 wd->clear_me = EINA_FALSE;
4539 wd->pan_changed = EINA_TRUE;
4542 ecore_job_del(wd->calc_job);
4543 wd->calc_job = NULL;
4545 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4546 if (wd->clear_cb) wd->clear_cb(wd);
4552 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4553 wd->alpha_bg = NULL;
4557 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4558 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4560 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4561 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4562 evas_event_thaw(evas_object_evas_get(wd->obj));
4563 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4567 elm_genlist_clear(Evas_Object *obj)
4569 ELM_CHECK_WIDTYPE(obj, widtype);
4570 _elm_genlist_clear(obj, EINA_FALSE);
4574 elm_genlist_multi_select_set(Evas_Object *obj,
4577 ELM_CHECK_WIDTYPE(obj, widtype);
4578 Widget_Data *wd = elm_widget_data_get(obj);
4580 wd->multi = !!multi;
4584 elm_genlist_multi_select_get(const Evas_Object *obj)
4586 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4587 Widget_Data *wd = elm_widget_data_get(obj);
4588 if (!wd) return EINA_FALSE;
4592 EAPI Elm_Object_Item *
4593 elm_genlist_selected_item_get(const Evas_Object *obj)
4595 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4596 Widget_Data *wd = elm_widget_data_get(obj);
4597 if (!wd) return NULL;
4598 if (wd->selected) return wd->selected->data;
4602 EAPI const Eina_List *
4603 elm_genlist_selected_items_get(const Evas_Object *obj)
4605 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4606 Widget_Data *wd = elm_widget_data_get(obj);
4607 if (!wd) return NULL;
4608 return wd->selected;
4612 elm_genlist_realized_items_get(const Evas_Object *obj)
4614 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4615 Widget_Data *wd = elm_widget_data_get(obj);
4616 Eina_List *list = NULL;
4618 Eina_Bool done = EINA_FALSE;
4619 if (!wd) return NULL;
4620 EINA_INLIST_FOREACH(wd->blocks, itb)
4628 EINA_LIST_FOREACH(itb->items, l, it)
4630 if (it->realized) list = eina_list_append(list, it);
4641 EAPI Elm_Object_Item *
4642 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4647 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4648 Widget_Data *wd = elm_widget_data_get(obj);
4649 Evas_Coord ox, oy, ow, oh;
4652 if (!wd) return NULL;
4653 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4655 EINA_INLIST_FOREACH(wd->blocks, itb)
4660 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4661 oy + itb->y - itb->wd->pan_y,
4662 itb->w, itb->h, x, y, 1, 1))
4664 EINA_LIST_FOREACH(itb->items, l, it)
4666 Evas_Coord itx, ity;
4668 itx = ox + itb->x + it->x - itb->wd->pan_x;
4669 ity = oy + itb->y + it->y - itb->wd->pan_y;
4670 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4674 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4675 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4679 return (Elm_Object_Item *)it;
4681 lasty = ity + it->item->h;
4686 if (y > lasty) *posret = 1;
4692 EAPI Elm_Object_Item *
4693 elm_genlist_first_item_get(const Evas_Object *obj)
4695 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4696 Widget_Data *wd = elm_widget_data_get(obj);
4697 if (!wd) return NULL;
4698 if (!wd->items) return NULL;
4699 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4700 while ((it) && (it->generation < wd->generation))
4701 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4702 return (Elm_Object_Item *)it;
4705 EAPI Elm_Object_Item *
4706 elm_genlist_last_item_get(const Evas_Object *obj)
4708 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4709 Widget_Data *wd = elm_widget_data_get(obj);
4710 if (!wd) return NULL;
4711 if (!wd->items) return NULL;
4712 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4713 while ((it) && (it->generation < wd->generation))
4714 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4715 return (Elm_Object_Item *)it;
4718 EAPI Elm_Object_Item *
4719 elm_genlist_item_next_get(const Elm_Object_Item *it)
4721 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4722 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4725 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
4726 if ((_it) && (_it->generation == _it->wd->generation)) break;
4728 return (Elm_Object_Item *) _it;
4731 EAPI Elm_Object_Item *
4732 elm_genlist_item_prev_get(const Elm_Object_Item *it)
4734 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4735 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4738 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
4739 if ((_it) && (_it->generation == _it->wd->generation)) break;
4741 return (Elm_Object_Item *) _it;
4744 EAPI Elm_Object_Item *
4745 elm_genlist_item_parent_get(const Elm_Object_Item *it)
4747 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4748 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
4752 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
4754 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4755 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
4757 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4759 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
4760 _item_subitems_clear(_it);
4763 if (!wd->tree_effect_animator)
4765 wd->expanded_item = _it;
4766 _item_tree_effect_before(_it);
4767 evas_object_raise(wd->alpha_bg);
4768 evas_object_show(wd->alpha_bg);
4769 wd->start_time = ecore_time_get();
4770 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
4773 _item_subitems_clear(_it);
4778 elm_genlist_item_selected_set(Elm_Object_Item *it,
4781 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4782 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4783 Widget_Data *wd = _it->wd;
4785 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
4787 selected = !!selected;
4788 if (_it->selected == selected) return;
4794 while (wd->selected)
4796 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
4797 _it->unsel_cb(wd->selected->data);
4800 _it->highlight_cb(_it);
4804 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
4809 elm_genlist_item_selected_get(const Elm_Object_Item *it)
4811 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4812 return ((Elm_Gen_Item *)it)->selected;
4816 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
4819 if (it->item->expanded)
4821 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4825 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4828 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
4829 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4836 _elm_genlist_move_items_set(Elm_Gen_Item *it)
4839 Elm_Gen_Item *it2 = NULL;
4840 Evas_Coord ox, oy, ow, oh, dh = 0;
4842 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
4844 if (it->item->expanded)
4846 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
4847 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
4849 if (it2 == it->wd->expanded_next_item) break;
4850 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
4855 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
4856 it2 = it->wd->expanded_next_item;
4857 while (it2 && (dh < oy + oh))
4860 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
4861 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4867 elm_genlist_item_expanded_set(Elm_Object_Item *it,
4870 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4871 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4872 expanded = !!expanded;
4873 if (_it->item->expanded == expanded) return;
4874 _it->item->expanded = expanded;
4875 _it->wd->expanded_item = _it;
4876 _elm_genlist_move_items_set(_it);
4878 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
4879 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
4881 if (_it->item->expanded)
4883 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
4885 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
4886 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
4887 _it->wd->auto_scroll_enabled = EINA_TRUE;
4891 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
4893 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
4894 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
4895 _it->wd->auto_scroll_enabled = EINA_FALSE;
4900 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
4902 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4903 return ((Elm_Gen_Item *)it)->item->expanded;
4907 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
4909 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
4910 return ((Elm_Gen_Item *)it)->item->expanded_depth;
4914 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
4915 Elm_Genlist_Item_Scrollto_Type type,
4922 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4923 Evas_Coord gith = 0;
4924 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4925 if ((_it->item->queued) || (!_it->item->mincalcd))
4927 _it->wd->show_item = _it;
4928 _it->wd->bring_in = bring_in;
4929 _it->wd->scrollto_type = type;
4930 _it->item->showme = EINA_TRUE;
4933 if (_it->wd->show_item)
4935 _it->wd->show_item->item->showme = EINA_FALSE;
4936 _it->wd->show_item = NULL;
4939 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
4942 case ELM_GENLIST_ITEM_SCROLLTO_IN:
4943 if ((_it->item->group_item) &&
4944 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4945 gith = _it->item->group_item->item->h;
4947 *y = _it->y + _it->item->block->y - gith;
4949 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
4950 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4951 *y = _it->y + _it->item->block->y - gith;
4953 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
4954 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
4960 *x = _it->x + _it->item->block->x;
4961 *w = _it->item->block->w;
4966 elm_genlist_item_promote(Elm_Object_Item *it)
4968 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4969 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4970 if (_it->generation < _it->wd->generation) return;
4971 _item_move_before(_it,
4972 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
4976 elm_genlist_item_demote(Elm_Object_Item *it)
4978 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4979 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4980 if (_it->generation < _it->wd->generation) return;
4981 _item_move_after(_it,
4982 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
4986 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4988 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4989 Evas_Coord x, y, w, h;
4990 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4992 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
4993 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
4997 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5000 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5001 Evas_Coord x, y, w, h;
5002 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5004 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
5005 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
5009 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5011 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5013 Evas_Object *content;
5014 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5016 elm_widget_sub_object_del(WIDGET(it), content);
5017 evas_object_smart_member_del(content);
5018 evas_object_hide(content);
5019 if (l) *l = eina_list_append(*l, content);
5024 elm_genlist_item_update(Elm_Object_Item *it)
5026 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5027 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5029 if (!_it->item->block) return;
5030 if (_it->generation < _it->wd->generation) return;
5031 _it->item->mincalcd = EINA_FALSE;
5032 _it->item->updateme = EINA_TRUE;
5033 _it->item->block->updateme = EINA_TRUE;
5034 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5035 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5039 elm_genlist_item_fields_update(Elm_Object_Item *it,
5041 Elm_Genlist_Item_Field_Type itf)
5043 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5044 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5046 if (!_it->item->block) return;
5047 if (_it->generation < _it->wd->generation) return;
5049 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5050 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5051 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5053 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5054 &_it->contents, parts);
5055 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5056 &_it->contents, parts);
5060 _it->item->flip_content_objs =
5061 _item_mode_content_unrealize(_it, VIEW(_it),
5062 &_it->item->flip_contents, parts,
5063 &_it->item->flip_content_objs);
5064 _it->item->flip_content_objs =
5065 _item_mode_content_realize(_it, VIEW(_it),
5066 &_it->item->flip_contents, parts,
5067 &_it->item->flip_content_objs);
5069 if (_it->item->deco_it_view)
5071 _it->item->deco_it_content_objs =
5072 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5073 &_it->item->deco_it_contents, parts,
5074 &_it->item->deco_it_content_objs);
5075 _it->item->deco_it_content_objs =
5076 _item_mode_content_realize(_it, _it->item->deco_it_view,
5077 &_it->item->deco_it_contents, parts,
5078 &_it->item->deco_it_content_objs);
5080 if (_it->wd->decorate_all_mode)
5082 _it->item->deco_all_content_objs =
5083 _item_mode_content_unrealize(_it, _it->deco_all_view,
5084 &_it->item->deco_all_contents, parts,
5085 &_it->item->deco_all_content_objs);
5086 _it->item->deco_all_content_objs =
5087 _item_mode_content_realize(_it, _it->deco_all_view,
5088 &_it->item->deco_all_contents, parts,
5089 &_it->item->deco_all_content_objs);
5092 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5093 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5097 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5098 const Elm_Genlist_Item_Class *itc)
5100 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5101 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5103 if (!_it->item->block) return;
5104 EINA_SAFETY_ON_NULL_RETURN(itc);
5105 if (_it->generation < _it->wd->generation) return;
5107 _it->item->nocache_once = EINA_TRUE;
5109 elm_widget_stringlist_free(_it->texts);
5111 elm_widget_stringlist_free(_it->contents);
5112 _it->contents = NULL;
5113 elm_widget_stringlist_free(_it->states);
5118 elm_widget_stringlist_free(_it->item->flip_contents);
5119 _it->item->flip_contents = NULL;
5121 if (_it->item->deco_it_view)
5123 elm_widget_stringlist_free(_it->item->deco_it_texts);
5124 _it->item->deco_it_texts = NULL;
5125 elm_widget_stringlist_free(_it->item->deco_it_contents);
5126 _it->item->deco_it_contents = NULL;
5128 if (_it->wd->decorate_all_mode)
5130 elm_widget_stringlist_free(_it->item->deco_all_texts);
5131 _it->item->deco_all_texts = NULL;
5132 elm_widget_stringlist_free(_it->item->deco_all_contents);
5133 _it->item->deco_all_contents = NULL;
5136 elm_genlist_item_update(it);
5139 EAPI const Elm_Genlist_Item_Class *
5140 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5142 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5143 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5144 if (_it->generation < _it->wd->generation) return NULL;
5148 static Evas_Object *
5149 _elm_genlist_item_label_create(void *data,
5150 Evas_Object *obj __UNUSED__,
5151 Evas_Object *tooltip,
5152 void *it __UNUSED__)
5154 Evas_Object *label = elm_label_add(tooltip);
5157 elm_object_style_set(label, "tooltip");
5158 elm_object_text_set(label, data);
5163 _elm_genlist_item_label_del_cb(void *data,
5164 Evas_Object *obj __UNUSED__,
5165 void *event_info __UNUSED__)
5167 eina_stringshare_del(data);
5171 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5174 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5175 text = eina_stringshare_add(text);
5176 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5178 _elm_genlist_item_label_del_cb);
5182 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5183 Elm_Tooltip_Item_Content_Cb func,
5185 Evas_Smart_Cb del_cb)
5187 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5188 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5190 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5193 if (_it->tooltip.del_cb)
5194 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5196 _it->tooltip.content_cb = func;
5197 _it->tooltip.data = data;
5198 _it->tooltip.del_cb = del_cb;
5202 elm_widget_item_tooltip_content_cb_set(_it,
5203 _it->tooltip.content_cb,
5204 _it->tooltip.data, NULL);
5205 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5206 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5212 if (del_cb) del_cb((void *)data, NULL, NULL);
5216 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5218 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5219 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5221 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5222 elm_widget_item_tooltip_unset(_it);
5224 if (_it->tooltip.del_cb)
5225 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5226 _it->tooltip.del_cb = NULL;
5227 _it->tooltip.content_cb = NULL;
5228 _it->tooltip.data = NULL;
5229 _it->tooltip.free_size = EINA_FALSE;
5230 if (_it->tooltip.style)
5231 elm_genlist_item_tooltip_style_set(it, NULL);
5235 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5238 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5239 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5241 eina_stringshare_replace(&_it->tooltip.style, style);
5242 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5246 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5248 return elm_object_item_tooltip_style_get(it);
5252 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5255 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5256 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5258 _it->tooltip.free_size = disable;
5259 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5264 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5266 return elm_object_tooltip_window_mode_get(VIEW(it));
5270 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5273 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5274 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5275 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5276 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5280 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5282 return elm_widget_item_cursor_get(it);
5286 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5288 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5289 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5291 if (!_it->mouse_cursor) return;
5293 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5295 eina_stringshare_del(_it->mouse_cursor);
5296 _it->mouse_cursor = NULL;
5300 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5303 elm_widget_item_cursor_style_set(it, style);
5307 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5309 return elm_widget_item_cursor_style_get(it);
5313 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5314 Eina_Bool engine_only)
5316 elm_widget_item_cursor_engine_only_set(it, engine_only);
5320 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5322 return elm_widget_item_cursor_engine_only_get(it);
5326 elm_genlist_item_index_get(const Elm_Object_Item *it)
5328 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5329 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5331 if (_it->item->block)
5332 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5337 elm_genlist_mode_set(Evas_Object *obj,
5340 ELM_CHECK_WIDTYPE(obj, widtype);
5341 Widget_Data *wd = elm_widget_data_get(obj);
5343 if (wd->mode == mode) return;
5345 if (wd->mode == ELM_LIST_COMPRESS)
5346 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5352 elm_genlist_mode_get(const Evas_Object *obj)
5354 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5355 Widget_Data *wd = elm_widget_data_get(obj);
5356 if (!wd) return ELM_LIST_LAST;
5361 elm_genlist_bounce_set(Evas_Object *obj,
5365 ELM_CHECK_WIDTYPE(obj, widtype);
5366 Widget_Data *wd = elm_widget_data_get(obj);
5368 wd->h_bounce = !!h_bounce;
5369 wd->v_bounce = !!v_bounce;
5370 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5374 elm_genlist_bounce_get(const Evas_Object *obj,
5375 Eina_Bool *h_bounce,
5376 Eina_Bool *v_bounce)
5378 ELM_CHECK_WIDTYPE(obj, widtype);
5379 Widget_Data *wd = elm_widget_data_get(obj);
5381 if (h_bounce) *h_bounce = wd->h_bounce;
5382 if (v_bounce) *v_bounce = wd->v_bounce;
5386 elm_genlist_homogeneous_set(Evas_Object *obj,
5387 Eina_Bool homogeneous)
5389 ELM_CHECK_WIDTYPE(obj, widtype);
5390 Widget_Data *wd = elm_widget_data_get(obj);
5392 wd->homogeneous = !!homogeneous;
5396 elm_genlist_homogeneous_get(const Evas_Object *obj)
5398 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5399 Widget_Data *wd = elm_widget_data_get(obj);
5400 if (!wd) return EINA_FALSE;
5401 return wd->homogeneous;
5405 elm_genlist_block_count_set(Evas_Object *obj,
5408 ELM_CHECK_WIDTYPE(obj, widtype);
5409 Widget_Data *wd = elm_widget_data_get(obj);
5411 wd->max_items_per_block = count;
5412 wd->item_cache_max = wd->max_items_per_block * 2;
5413 _item_cache_clean(wd);
5417 elm_genlist_block_count_get(const Evas_Object *obj)
5419 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5420 Widget_Data *wd = elm_widget_data_get(obj);
5422 return wd->max_items_per_block;
5426 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5429 ELM_CHECK_WIDTYPE(obj, widtype);
5430 Widget_Data *wd = elm_widget_data_get(obj);
5432 wd->longpress_timeout = timeout;
5436 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5438 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5439 Widget_Data *wd = elm_widget_data_get(obj);
5441 return wd->longpress_timeout;
5445 elm_genlist_scroller_policy_set(Evas_Object *obj,
5446 Elm_Scroller_Policy policy_h,
5447 Elm_Scroller_Policy policy_v)
5449 ELM_CHECK_WIDTYPE(obj, widtype);
5450 Widget_Data *wd = elm_widget_data_get(obj);
5451 if ((!wd) || (!wd->scr)) return;
5452 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5453 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5455 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5459 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5460 Elm_Scroller_Policy *policy_h,
5461 Elm_Scroller_Policy *policy_v)
5463 ELM_CHECK_WIDTYPE(obj, widtype);
5464 Widget_Data *wd = elm_widget_data_get(obj);
5465 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5466 if ((!wd) || (!wd->scr)) return;
5467 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5468 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5469 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5473 elm_genlist_realized_items_update(Evas_Object *obj)
5475 ELM_CHECK_WIDTYPE(obj, widtype);
5477 Eina_List *list, *l;
5478 Elm_Object_Item *it;
5480 list = elm_genlist_realized_items_get(obj);
5481 EINA_LIST_FOREACH(list, l, it)
5482 elm_genlist_item_update(it);
5486 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5487 const char *decorate_it_type,
5488 Eina_Bool decorate_it_set)
5490 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5491 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5493 Widget_Data *wd = _it->wd;
5495 Elm_Object_Item *it2;
5498 if (!decorate_it_type) return;
5499 if ((_it->generation < _it->wd->generation) ||
5500 elm_widget_item_disabled_get(_it)) return;
5501 if (wd->decorate_all_mode) return;
5503 if ((wd->mode_item == _it) &&
5504 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5507 if (!_it->itc->decorate_item_style) return;
5508 _it->decorate_it_set = decorate_it_set;
5512 EINA_LIST_FOREACH(wd->selected, l, it2)
5513 if (((Elm_Gen_Item *)it2)->realized)
5514 elm_genlist_item_selected_set(it2, EINA_FALSE);
5518 it2 = elm_genlist_selected_item_get(wd->obj);
5519 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5520 elm_genlist_item_selected_set(it2, EINA_FALSE);
5523 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5524 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5525 _decorate_item_unset(wd);
5527 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5528 if (decorate_it_set) _decorate_item_set(_it);
5532 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5534 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5535 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5536 return _it->wd->decorate_it_type;
5539 EAPI const Elm_Object_Item *
5540 elm_genlist_decorated_item_get(const Evas_Object *obj)
5542 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5543 Widget_Data *wd = elm_widget_data_get(obj);
5544 if (!wd) return NULL;
5545 return (Elm_Object_Item *) wd->mode_item;
5549 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5551 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5552 Widget_Data *wd = elm_widget_data_get(obj);
5553 if (!wd) return EINA_FALSE;
5555 return wd->decorate_all_mode;
5559 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5561 ELM_CHECK_WIDTYPE(obj, widtype);
5562 Eina_List *list, *l;
5565 Widget_Data *wd = elm_widget_data_get(obj);
5567 decorated = !!decorated;
5568 if (wd->decorate_all_mode == decorated) return;
5569 wd->decorate_all_mode = decorated;
5571 list = elm_genlist_realized_items_get(obj);
5572 if (!wd->decorate_all_mode)
5574 EINA_LIST_FOREACH(list, l, it)
5576 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5577 _decorate_all_item_unrealize(it);
5579 _item_cache_zero(wd);
5583 EINA_LIST_FOREACH(list, l, it)
5585 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5587 if (it->selected) _item_unselect(it);
5588 if (it->itc->decorate_all_item_style)
5589 _decorate_all_item_realize(it, EINA_TRUE);
5593 if (wd->calc_job) ecore_job_del(wd->calc_job);
5594 wd->calc_job = ecore_job_add(_calc_job, wd);
5598 elm_genlist_reorder_mode_set(Evas_Object *obj,
5599 Eina_Bool reorder_mode)
5601 ELM_CHECK_WIDTYPE(obj, widtype);
5602 Widget_Data *wd = elm_widget_data_get(obj);
5604 wd->reorder_mode = !!reorder_mode;
5608 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5610 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5611 Widget_Data *wd = elm_widget_data_get(obj);
5612 if (!wd) return EINA_FALSE;
5613 return wd->reorder_mode;
5616 EAPI Elm_Genlist_Item_Type
5617 elm_genlist_item_type_get(const Elm_Object_Item *it)
5619 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5620 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5621 return _it->item->type;
5624 EAPI Elm_Genlist_Item_Class *
5625 elm_genlist_item_class_new(void)
5627 Elm_Genlist_Item_Class *itc;
5629 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5632 itc->version = CLASS_ALLOCATED;
5634 itc->delete_me = EINA_FALSE;
5640 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5642 if (itc && (itc->version == CLASS_ALLOCATED))
5644 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5645 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5655 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5657 if (itc && (itc->version == CLASS_ALLOCATED))
5660 if (itc->refcount == 0) itc->refcount--;
5665 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5667 if (itc && (itc->version == CLASS_ALLOCATED))
5669 if (itc->refcount > 0) itc->refcount--;
5670 if (itc->delete_me && (!itc->refcount))
5671 elm_genlist_item_class_free(itc);
5675 void _flip_job(void *data)
5677 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
5678 _elm_genlist_item_unrealize(it, EINA_FALSE);
5679 if (it->selected) _item_unselect(it);
5680 it->flipped = EINA_TRUE;
5681 it->item->nocache = EINA_TRUE;
5685 elm_genlist_item_flip_set(Elm_Object_Item *it,
5688 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5689 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5692 if (_it->flipped == flip) return;
5696 ecore_job_add(_flip_job, _it);
5697 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
5698 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
5702 _it->flipped = flip;
5703 _item_cache_zero(_it->wd);
5704 elm_genlist_item_update(it);
5705 _it->item->nocache = EINA_FALSE;
5710 elm_genlist_item_flip_get(const Elm_Object_Item *it)
5712 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5713 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5714 return _it->flipped;
5718 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
5720 ELM_CHECK_WIDTYPE(obj, widtype);
5721 Widget_Data *wd = elm_widget_data_get(obj);
5723 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5725 if (wd->select_mode != mode)
5726 wd->select_mode = mode;
5729 EAPI Elm_Object_Select_Mode
5730 elm_genlist_select_mode_get(const Evas_Object *obj)
5732 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
5733 Widget_Data *wd = elm_widget_data_get(obj);
5734 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
5735 return wd->select_mode;
5739 elm_genlist_highlight_mode_set(Evas_Object *obj,
5740 Eina_Bool highlight)
5742 ELM_CHECK_WIDTYPE(obj, widtype);
5743 Widget_Data *wd = elm_widget_data_get(obj);
5745 wd->highlight = !!highlight;
5749 elm_genlist_highlight_mode_get(const Evas_Object *obj)
5751 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5752 Widget_Data *wd = elm_widget_data_get(obj);
5753 if (!wd) return EINA_FALSE;
5754 return wd->highlight;
5758 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
5759 Elm_Object_Select_Mode mode)
5761 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5762 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5764 if (_it->generation < _it->wd->generation) return;
5765 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5767 if (_it->select_mode != mode)
5768 _it->select_mode = mode;
5770 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5772 _it->item->mincalcd = EINA_FALSE;
5773 _it->item->updateme = EINA_TRUE;
5774 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
5775 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5776 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5780 EAPI Elm_Object_Select_Mode
5781 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
5783 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
5784 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5785 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
5786 return _it->select_mode;
5789 /* for gengrid as of now */
5791 _elm_genlist_page_relative_set(Evas_Object *obj,
5795 Evas_Coord pagesize_h;
5796 Evas_Coord pagesize_v;
5798 ELM_CHECK_WIDTYPE(obj, widtype);
5799 Widget_Data *wd = elm_widget_data_get(obj);
5802 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5803 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5807 /* for gengrid as of now */
5809 _elm_genlist_page_relative_get(const Evas_Object *obj,
5813 ELM_CHECK_WIDTYPE(obj, widtype);
5814 Widget_Data *wd = elm_widget_data_get(obj);
5817 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5820 /* for gengrid as of now */
5822 _elm_genlist_page_size_set(Evas_Object *obj,
5823 Evas_Coord h_pagesize,
5824 Evas_Coord v_pagesize)
5829 ELM_CHECK_WIDTYPE(obj, widtype);
5830 Widget_Data *wd = elm_widget_data_get(obj);
5832 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5833 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5837 /* for gengrid as of now */
5839 _elm_genlist_current_page_get(const Evas_Object *obj,
5843 ELM_CHECK_WIDTYPE(obj, widtype);
5844 Widget_Data *wd = elm_widget_data_get(obj);
5846 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5849 /* for gengrid as of now */
5851 _elm_genlist_last_page_get(const Evas_Object *obj,
5855 ELM_CHECK_WIDTYPE(obj, widtype);
5856 Widget_Data *wd = elm_widget_data_get(obj);
5858 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5861 /* for gengrid as of now */
5863 _elm_genlist_page_show(const Evas_Object *obj,
5867 ELM_CHECK_WIDTYPE(obj, widtype);
5868 Widget_Data *wd = elm_widget_data_get(obj);
5870 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5873 /* for gengrid as of now */
5875 _elm_genlist_page_bring_in(const Evas_Object *obj,
5879 ELM_CHECK_WIDTYPE(obj, widtype);
5880 Widget_Data *wd = elm_widget_data_get(obj);
5882 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5886 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5889 Evas_Object *content;
5891 if (!it->realized) return;
5892 if (it->wd->reorder_it == it) return;
5894 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5896 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5899 ecore_timer_del(it->long_timer);
5900 it->long_timer = NULL;
5903 elm_widget_stringlist_free(it->texts);
5905 elm_widget_stringlist_free(it->contents);
5906 it->contents = NULL;
5907 elm_widget_stringlist_free(it->states);
5909 EINA_LIST_FREE(it->content_objs, content)
5910 evas_object_del(content);
5914 elm_widget_stringlist_free(it->item->flip_contents);
5915 it->item->flip_contents = NULL;
5916 EINA_LIST_FREE(it->item->flip_content_objs, content)
5917 evas_object_del(content);
5920 it->unrealize_cb(it);
5922 it->realized = EINA_FALSE;
5923 it->want_unrealize = EINA_FALSE;
5924 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5925 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5929 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5931 elm_widget_item_pre_notify_del(it);
5932 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5933 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5935 if (it->itc->func.del)
5936 it->itc->func.del((void *)it->base.data, WIDGET(it));
5940 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5942 _elm_genlist_item_del_notserious(it);
5943 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5944 if (it->tooltip.del_cb)
5945 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5946 it->wd->walking -= it->walking;
5949 ecore_timer_del(it->long_timer);
5950 it->long_timer = NULL;
5953 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5957 eina_inlist_sorted_state_free(it->wd->state);
5958 it->wd->state = NULL;
5960 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5961 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5965 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
5966 it->wd->last_selected_item = NULL;
5967 it->wd->item_count--;
5971 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
5973 ELM_CHECK_WIDTYPE(obj, widtype);
5974 Widget_Data *wd = elm_widget_data_get(obj);
5976 wd->tree_effect_enabled = !!enabled;
5980 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
5982 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5983 Widget_Data *wd = elm_widget_data_get(obj);
5984 if (!wd) return EINA_FALSE;
5985 return wd->tree_effect_enabled;
5989 _create_tray_alpha_bg(const Evas_Object *obj)
5991 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5992 Widget_Data *wd = elm_widget_data_get(obj);
5993 if (!wd) return NULL;
5995 Evas_Object *bg = NULL;
5996 Evas_Coord ox, oy, ow, oh;
5998 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5999 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6000 evas_object_color_set(bg,0,0,0,0);
6001 evas_object_resize(bg , ow, oh);
6002 evas_object_move(bg , ox, oy);
6007 _item_contract_emit(Elm_Gen_Item *it)
6012 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6013 it->item->tree_effect_finished = EINA_FALSE;
6015 EINA_LIST_FOREACH(it->item->items, l, it2)
6016 if (it2) _item_contract_emit(it2);
6020 _item_tree_effect_before(Elm_Gen_Item *it)
6025 EINA_LIST_FOREACH(it->item->items, l, it2)
6027 if (it2->parent && (it == it2->parent))
6030 it2->item->tree_effect_hideme = EINA_TRUE;
6031 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6032 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6033 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6034 _item_contract_emit(it2);
6037 return ECORE_CALLBACK_CANCEL;
6041 _item_tree_effect(Widget_Data *wd, int y)
6043 Elm_Gen_Item *it = NULL, *expanded_next_it;
6045 expanded_next_it = wd->expanded_next_item;
6047 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6049 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6052 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6053 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6054 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6056 if (!it->item->tree_effect_finished)
6058 edje_object_signal_emit(VIEW(it), "flip_item", "");
6059 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6060 it->item->tree_effect_finished = EINA_TRUE;
6063 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6066 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6068 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6071 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6072 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6074 if (!it->item->tree_effect_finished)
6076 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6077 it->item->tree_effect_finished = EINA_TRUE;
6082 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6088 _item_tree_effect_finish(Widget_Data *wd)
6090 Elm_Gen_Item *it = NULL;
6093 if (wd->tree_effect_animator)
6095 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6096 _item_subitems_clear(wd->expanded_item);
6097 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6099 it->item->tree_effect_finished = EINA_TRUE;
6100 it->item->old_scrl_y = it->item->scrl_y;
6101 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6102 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6105 _item_auto_scroll(wd);
6106 evas_object_lower(wd->alpha_bg);
6107 evas_object_hide(wd->alpha_bg);
6108 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6109 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6111 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6112 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6113 evas_object_smart_changed(wd->pan_smart);
6115 wd->tree_effect_animator = NULL;
6119 _tree_effect_animator_cb(void *data)
6121 Widget_Data *wd = data;
6122 if (!wd) return EINA_FALSE;
6123 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6124 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6126 double effect_duration = 0.3, t;
6127 int y = 0, dy = 0, dh = 0;
6128 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6131 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6132 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6133 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6134 if (t > effect_duration) end = EINA_TRUE;
6136 // Below while statement is needed, when the genlist is resized.
6137 it2 = wd->expanded_item;
6140 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6141 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6142 cvx, cvy, cvw, cvh));
6143 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6146 if (wd->expanded_next_item)
6148 expanded_next_it = wd->expanded_next_item;
6151 EINA_LIST_FOREACH(wd->move_items, l, it)
6153 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6155 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6156 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6157 expanded_next_it->item->scrl_y = cvy + cvh;
6159 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6160 cvy + cvh : expanded_next_it->item->scrl_y) -
6161 expanded_next_it->item->old_scrl_y;
6163 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6165 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6166 expanded_next_it->item->old_scrl_y = cvy + cvh;
6168 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6170 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6172 expanded_next_it->item->old_scrl_y = cvy + cvh;
6176 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6177 expanded_next_it->item->old_scrl_y;
6181 if (t <= effect_duration)
6183 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6193 _item_realize(it, in, 0);
6197 if (it != expanded_next_it)
6199 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6203 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6204 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6207 _item_tree_effect(wd, y);
6211 int expanded_item_num = 0;
6214 if (wd->expanded_item)
6215 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6220 expanded_item_num++;
6221 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6227 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6228 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6230 if (!it->item->tree_effect_finished)
6232 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6234 edje_object_signal_emit(VIEW(it), "flip_item", "");
6235 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6236 it->item->tree_effect_finished = EINA_TRUE;
6240 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6246 _item_tree_effect_finish(wd);
6247 return ECORE_CALLBACK_CANCEL;
6249 return ECORE_CALLBACK_RENEW;