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 changeme : 1;
102 Eina_Bool showme : 1;
103 Eina_Bool must_recalc : 1;
110 Evas_Object *base_view, *spacer;
112 const char *item_style; // it->itc->item_style
113 Eina_Bool tree : 1; // it->group
115 Eina_Bool selected : 1; // it->selected
116 Eina_Bool disabled : 1; // it->disabled
117 Eina_Bool expanded : 1; // it->item->expanded
120 static const char *widtype = NULL;
121 static void _item_cache_zero(Widget_Data *wd);
122 static void _del_hook(Evas_Object *obj);
123 static void _mirrored_set(Evas_Object *obj,
125 static void _theme_hook(Evas_Object *obj);
126 static void _show_region_hook(void *data,
128 static void _sizing_eval(Evas_Object *obj);
129 static void _item_realize(Elm_Gen_Item *it,
132 static void _item_unrealize_cb(Elm_Gen_Item *it);
133 static void _item_block_unrealize(Item_Block *itb);
134 static void _calc_job(void *data);
135 static void _on_focus_hook(void *data,
137 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
138 static void _changed_job(void *data);
139 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
140 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
141 static Eina_Bool _item_single_select_up(Widget_Data *wd);
142 static Eina_Bool _item_single_select_down(Widget_Data *wd);
143 static Eina_Bool _event_hook(Evas_Object *obj,
145 Evas_Callback_Type type,
147 static void _signal_emit_hook(Evas_Object *obj,
148 const char *emission,
150 static Eina_Bool _deselect_all_items(Widget_Data *wd);
151 static void _pan_calculate(Evas_Object *obj);
152 static void _pan_max_get(Evas_Object *obj,
155 static void _item_position(Elm_Gen_Item *it,
159 static void _decorate_item_realize(Elm_Gen_Item *it);
160 static void _decorate_item_unrealize(Elm_Gen_Item *it);
161 static void _decorate_item_set(Elm_Gen_Item *it);
162 static void _decorate_item_unset(Widget_Data *wd);
163 static void _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity);
164 static void _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
165 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
168 static void _group_items_recalc(void *data);
170 static void _item_move_after(Elm_Gen_Item *it,
171 Elm_Gen_Item *after);
172 static void _item_move_before(Elm_Gen_Item *it,
173 Elm_Gen_Item *before);
174 static void _item_auto_scroll(Widget_Data *wd);
175 static void _elm_genlist_clear(Evas_Object *obj,
177 static void _pan_child_size_get(Evas_Object *obj,
180 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
181 static void _item_contract_emit(Elm_Gen_Item *it);
182 static int _item_tree_effect_before(Elm_Gen_Item *it);
183 static void _item_tree_effect(Widget_Data *wd, int y);
184 static void _item_tree_effect_finish(Widget_Data *wd);
185 static Eina_Bool _tree_effect_animator_cb(void *data);
187 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
189 static const char SIG_ACTIVATED[] = "activated";
190 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
191 static const char SIG_SELECTED[] = "selected";
192 static const char SIG_UNSELECTED[] = "unselected";
193 static const char SIG_EXPANDED[] = "expanded";
194 static const char SIG_CONTRACTED[] = "contracted";
195 static const char SIG_EXPAND_REQUEST[] = "expand,request";
196 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
197 static const char SIG_REALIZED[] = "realized";
198 static const char SIG_UNREALIZED[] = "unrealized";
199 static const char SIG_DRAG_START_UP[] = "drag,start,up";
200 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
201 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
202 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
203 static const char SIG_DRAG_STOP[] = "drag,stop";
204 static const char SIG_DRAG[] = "drag";
205 static const char SIG_LONGPRESSED[] = "longpressed";
206 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
207 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
208 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
209 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
210 static const char SIG_EDGE_TOP[] = "edge,top";
211 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
212 static const char SIG_EDGE_LEFT[] = "edge,left";
213 static const char SIG_EDGE_RIGHT[] = "edge,right";
214 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
215 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
216 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
217 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
218 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
219 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
220 static const char SIG_SWIPE[] = "swipe";
221 static const char SIG_MOVED[] = "moved";
222 static const char SIG_MOVED_AFTER[] = "moved,after";
223 static const char SIG_MOVED_BEFORE[] = "moved,before";
224 static const char SIG_INDEX_UPDATE[] = "index,update";
225 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
227 static const Evas_Smart_Cb_Description _signals[] = {
228 {SIG_CLICKED_DOUBLE, ""},
231 {SIG_UNSELECTED, ""},
233 {SIG_CONTRACTED, ""},
234 {SIG_EXPAND_REQUEST, ""},
235 {SIG_CONTRACT_REQUEST, ""},
237 {SIG_UNREALIZED, ""},
238 {SIG_DRAG_START_UP, ""},
239 {SIG_DRAG_START_DOWN, ""},
240 {SIG_DRAG_START_LEFT, ""},
241 {SIG_DRAG_START_RIGHT, ""},
244 {SIG_LONGPRESSED, ""},
245 {SIG_SCROLL_ANIM_START, ""},
246 {SIG_SCROLL_ANIM_STOP, ""},
247 {SIG_SCROLL_DRAG_START, ""},
248 {SIG_SCROLL_DRAG_STOP, ""},
250 {SIG_EDGE_BOTTOM, ""},
252 {SIG_EDGE_RIGHT, ""},
253 {SIG_MULTI_SWIPE_LEFT, ""},
254 {SIG_MULTI_SWIPE_RIGHT, ""},
255 {SIG_MULTI_SWIPE_UP, ""},
256 {SIG_MULTI_SWIPE_DOWN, ""},
257 {SIG_MULTI_PINCH_OUT, ""},
258 {SIG_MULTI_PINCH_IN, ""},
261 {SIG_MOVED_AFTER, ""},
262 {SIG_MOVED_BEFORE, ""},
263 {SIG_TREE_EFFECT_FINISHED, ""},
268 #undef ELM_CHECK_WIDTYPE
269 #define ELM_CHECK_WIDTYPE(obj, widtype) \
270 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
271 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
272 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
273 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
274 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
276 static const char *_gengrid = NULL;
277 static const char *_genlist = NULL;
279 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
281 elm_genlist_type_check(const Evas_Object *obj,
284 const char *provided, *expected = "(unknown)";
285 static int abort_on_warn = -1;
286 provided = elm_widget_type_get(obj);
287 if (!_genlist) _genlist = eina_stringshare_add("genlist");
288 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
289 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
291 if ((!provided) || (!provided[0]))
293 provided = evas_object_type_get(obj);
294 if ((!provided) || (!provided[0]))
295 provided = "(unknown)";
297 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
298 if (abort_on_warn == -1)
300 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
301 else abort_on_warn = 0;
303 if (abort_on_warn == 1) abort();
308 _event_hook(Evas_Object *obj,
309 Evas_Object *src __UNUSED__,
310 Evas_Callback_Type type,
313 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
314 Evas_Event_Key_Down *ev = event_info;
315 Widget_Data *wd = elm_widget_data_get(obj);
316 Evas_Coord pan_max_x = 0, pan_max_y = 0;
317 if (!wd) return EINA_FALSE;
318 if (!wd->items) return EINA_FALSE;
319 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
320 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
322 Elm_Object_Item *it = NULL;
325 Evas_Coord step_x = 0;
326 Evas_Coord step_y = 0;
329 Evas_Coord page_x = 0;
330 Evas_Coord page_y = 0;
332 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
333 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
334 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
335 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
337 if ((!strcmp(ev->keyname, "Left")) ||
338 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
342 else if ((!strcmp(ev->keyname, "Right")) ||
343 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
347 else if ((!strcmp(ev->keyname, "Up")) ||
348 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
350 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
351 (_item_multi_select_up(wd)))
352 || (_item_single_select_up(wd)))
354 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
360 else if ((!strcmp(ev->keyname, "Down")) ||
361 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
363 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
364 (_item_multi_select_down(wd)))
365 || (_item_single_select_down(wd)))
367 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
373 else if ((!strcmp(ev->keyname, "Home")) ||
374 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
376 it = elm_genlist_first_item_get(obj);
377 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
378 elm_genlist_item_selected_set(it, EINA_TRUE);
379 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
382 else if ((!strcmp(ev->keyname, "End")) ||
383 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
385 it = elm_genlist_last_item_get(obj);
386 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
387 elm_genlist_item_selected_set(it, EINA_TRUE);
388 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
391 else if ((!strcmp(ev->keyname, "Prior")) ||
392 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
395 y -= -(page_y * v_h) / 100;
399 else if ((!strcmp(ev->keyname, "Next")) ||
400 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
403 y += -(page_y * v_h) / 100;
407 else if (!strcmp(ev->keyname, "Escape"))
409 if (!_deselect_all_items(wd)) return EINA_FALSE;
410 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
413 else if (((!strcmp(ev->keyname, "Return")) ||
414 (!strcmp(ev->keyname, "KP_Enter")) ||
415 (!strcmp(ev->keyname, "space")))
416 && (!wd->multi) && (wd->selected))
418 it = elm_genlist_selected_item_get(obj);
419 elm_genlist_item_expanded_set(it,
420 !elm_genlist_item_expanded_get(it));
421 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
423 else return EINA_FALSE;
425 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
426 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
428 if (x > pan_max_x) x = pan_max_x;
430 if (y > pan_max_y) y = pan_max_y;
431 elm_smart_scroller_child_pos_set(wd->scr, x, y);
436 _deselect_all_items(Widget_Data *wd)
438 if (!wd->selected) return EINA_FALSE;
440 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
446 _item_multi_select_up(Widget_Data *wd)
448 if (!wd->selected) return EINA_FALSE;
449 if (!wd->multi) return EINA_FALSE;
451 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
452 if (!prev) return EINA_TRUE;
454 if (elm_genlist_item_selected_get(prev))
456 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
457 wd->last_selected_item = prev;
458 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
462 elm_genlist_item_selected_set(prev, EINA_TRUE);
463 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
469 _item_multi_select_down(Widget_Data *wd)
471 if (!wd->selected) return EINA_FALSE;
472 if (!wd->multi) return EINA_FALSE;
474 Elm_Object_Item *next;
475 next = elm_genlist_item_next_get(wd->last_selected_item);
476 if (!next) return EINA_TRUE;
478 if (elm_genlist_item_selected_get(next))
480 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
481 wd->last_selected_item = next;
482 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
486 elm_genlist_item_selected_set(next, EINA_TRUE);
487 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
493 _item_single_select_up(Widget_Data *wd)
498 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
499 while ((prev) && (prev->generation < wd->generation))
500 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
502 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
504 if (!prev) return EINA_FALSE;
506 _deselect_all_items(wd);
508 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
509 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
514 _item_single_select_down(Widget_Data *wd)
519 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
520 while ((next) && (next->generation < wd->generation))
521 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
523 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
525 if (!next) return EINA_FALSE;
527 _deselect_all_items(wd);
529 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
530 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
535 _on_focus_hook(void *data __UNUSED__,
538 Widget_Data *wd = elm_widget_data_get(obj);
540 if (elm_widget_focus_get(obj))
542 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
543 evas_object_focus_set(wd->obj, EINA_TRUE);
544 if ((wd->items) && (wd->selected) && (!wd->last_selected_item))
545 wd->last_selected_item = eina_list_data_get(wd->selected);
549 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
550 evas_object_focus_set(wd->obj, EINA_FALSE);
555 _del_hook(Evas_Object *obj)
557 Widget_Data *wd = elm_widget_data_get(obj);
559 _item_cache_zero(wd);
560 if (wd->calc_job) ecore_job_del(wd->calc_job);
561 if (wd->update_job) ecore_job_del(wd->update_job);
562 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
563 if (wd->changed_job) ecore_job_del(wd->changed_job);
564 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
565 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
566 if (wd->decorate_it_type) eina_stringshare_del(wd->decorate_it_type);
567 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
568 if (wd->tree_effect_animator) ecore_animator_del(wd->tree_effect_animator);
573 _del_pre_hook(Evas_Object *obj)
575 Widget_Data *wd = elm_widget_data_get(obj);
577 if (wd->decorate_all_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
578 elm_genlist_clear(obj);
579 evas_object_del(wd->pan_smart);
580 wd->pan_smart = NULL;
584 _mirrored_set(Evas_Object *obj,
587 Widget_Data *wd = elm_widget_data_get(obj);
589 _item_cache_zero(wd);
590 elm_smart_scroller_mirrored_set(wd->scr, rtl);
594 _theme_hook(Evas_Object *obj)
596 Widget_Data *wd = elm_widget_data_get(obj);
599 evas_event_freeze(evas_object_evas_get(wd->obj));
600 _item_cache_zero(wd);
601 _elm_widget_mirrored_reload(obj);
602 _mirrored_set(obj, elm_widget_mirrored_get(obj));
603 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
604 elm_widget_style_get(obj));
605 //edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
606 wd->item_width = wd->item_height = 0;
607 wd->group_item_width = wd->group_item_height = 0;
608 wd->minw = wd->minh = wd->realminw = 0;
609 EINA_INLIST_FOREACH(wd->blocks, itb)
614 if (itb->realized) _item_block_unrealize(itb);
615 EINA_LIST_FOREACH(itb->items, l, it)
616 it->item->mincalcd = EINA_FALSE;
618 itb->changed = EINA_TRUE;
620 if (wd->calc_job) ecore_job_del(wd->calc_job);
621 wd->calc_job = ecore_job_add(_calc_job, wd);
623 evas_event_thaw(evas_object_evas_get(wd->obj));
624 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
628 _show_region_hook(void *data,
631 Widget_Data *wd = elm_widget_data_get(data);
632 Evas_Coord x, y, w, h;
634 elm_widget_show_region_get(obj, &x, &y, &w, &h);
635 //x & y are screen coordinates, Add with pan coordinates
638 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
642 _translate_hook(Evas_Object *obj)
644 evas_object_smart_callback_call(obj, "language,changed", NULL);
648 _sizing_eval(Evas_Object *obj)
650 Widget_Data *wd = elm_widget_data_get(obj);
651 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
652 Evas_Coord vmw = 0, vmh = 0;
655 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
656 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
658 edje_object_size_min_calc
659 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
661 if (wd->mode == ELM_LIST_COMPRESS)
665 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
666 if ((vw != 0) && (vw != wd->prev_viewport_w))
670 wd->prev_viewport_w = vw;
671 EINA_INLIST_FOREACH(wd->blocks, itb)
673 itb->must_recalc = EINA_TRUE;
675 if (wd->calc_job) ecore_job_del(wd->calc_job);
676 wd->calc_job = ecore_job_add(_calc_job, wd);
678 edje_object_size_min_calc
679 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
683 else if (wd->mode == ELM_LIST_LIMIT)
694 evas_object_size_hint_min_set(obj, minw, minh);
695 evas_object_size_hint_max_set(obj, maxw, maxh);
699 _signal_emit_hook(Evas_Object *obj,
700 const char *emission,
703 Widget_Data *wd = elm_widget_data_get(obj);
704 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
709 _item_highlight(Elm_Gen_Item *it)
711 const char *selectraise;
712 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
713 (!it->wd->highlight) ||
714 (it->generation < it->wd->generation) ||
715 (it->highlighted) || elm_widget_item_disabled_get(it) ||
716 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->deco_it_view) ||
717 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
719 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
720 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
721 selectraise = edje_object_data_get(VIEW(it), "selectraise");
722 if ((selectraise) && (!strcmp(selectraise, "on")))
724 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
725 else evas_object_raise(VIEW(it));
728 if ((it->item->group_item) && (it->item->group_item->realized))
729 evas_object_raise(it->item->VIEW(group_item));
732 it->highlighted = EINA_TRUE;
736 _item_unhighlight(Elm_Gen_Item *it)
738 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
739 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
740 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
741 if (!it->item->nostacking)
743 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
745 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
746 else evas_object_lower(VIEW(it));
750 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
751 else evas_object_raise(VIEW(it));
754 it->highlighted = EINA_FALSE;
758 _item_block_position_update(Eina_Inlist *list, int idx)
762 EINA_INLIST_FOREACH(list, tmp)
764 tmp->position = idx++;
765 tmp->position_update = EINA_TRUE;
770 _item_position_update(Eina_List *list, int idx)
775 EINA_LIST_FOREACH(list, l, it)
777 it->position = idx++;
778 it->position_update = EINA_TRUE;
783 _item_block_del(Elm_Gen_Item *it)
786 Item_Block *itb = it->item->block;
787 Eina_Bool block_changed;
789 itb->items = eina_list_remove(itb->items, it);
791 itb->changed = EINA_TRUE;
792 if (!it->wd->reorder_deleted)
794 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
795 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
799 il = EINA_INLIST_GET(itb);
800 Item_Block *itbn = (Item_Block *)(il->next);
802 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
805 _item_block_position_update(il->next, itb->position);
806 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
809 if (itbn) itbn->changed = EINA_TRUE;
813 if (itb->count < itb->wd->max_items_per_block/2)
815 il = EINA_INLIST_GET(itb);
816 Item_Block *itbp = (Item_Block *)(il->prev);
817 Item_Block *itbn = (Item_Block *)(il->next);
818 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
822 EINA_LIST_FREE(itb->items, it2)
824 it2->item->block = itbp;
825 itbp->items = eina_list_append(itbp->items, it2);
827 itbp->changed = EINA_TRUE;
829 _item_block_position_update(EINA_INLIST_GET(itb)->next,
831 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
832 EINA_INLIST_GET(itb));
834 block_changed = EINA_TRUE;
836 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
840 Eina_List *last = eina_list_last(itb->items);
841 Elm_Gen_Item *it2 = last->data;
843 it2->item->block = itbn;
844 itb->items = eina_list_remove_list(itb->items, last);
845 itbn->items = eina_list_prepend(itbn->items, it2);
847 itbn->changed = EINA_TRUE;
849 _item_block_position_update(EINA_INLIST_GET(itb)->next,
852 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
854 block_changed = EINA_TRUE;
860 it->wd->pan_changed = EINA_TRUE;
861 evas_object_smart_changed(it->wd->pan_smart);
862 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
863 it->wd->calc_job = NULL;
868 _item_subitems_clear(Elm_Gen_Item *it)
870 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
871 Eina_List *tl = NULL, *l;
872 Elm_Object_Item *it2;
874 EINA_LIST_FOREACH(it->item->items, l, it2)
875 tl = eina_list_append(tl, it2);
876 EINA_LIST_FREE(tl, it2)
877 elm_object_item_del(it2);
881 _item_del(Elm_Gen_Item *it)
883 Evas_Object *obj = WIDGET(it);
884 Widget_Data *wd = it->wd;
886 evas_event_freeze(evas_object_evas_get(obj));
887 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
888 if (wd->show_item == it) wd->show_item = NULL;
889 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
890 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
891 if (it->item->block) _item_block_del(it);
892 if (it->item->queued)
893 wd->queue = eina_list_remove(wd->queue, it);
894 if (wd->anchor_item == it)
896 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
897 if (!wd->anchor_item)
898 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
900 if (wd->expanded_item == it)
902 wd->expanded_item = NULL;
903 if (wd->tree_effect_animator)
905 ecore_animator_del(wd->tree_effect_animator);
906 wd->tree_effect_animator = NULL;
908 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
910 if (wd->expanded_next_item == it) wd->expanded_next_item = NULL;
911 if (wd->move_items) wd->move_items = eina_list_remove(wd->move_items, it);
913 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
914 if (it->item->swipe_timer)
916 ecore_timer_del(it->item->swipe_timer);
917 it->item->swipe_timer = NULL;
919 _elm_genlist_item_del_serious(it);
920 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
921 evas_event_thaw(evas_object_evas_get(obj));
922 evas_event_thaw_eval(evas_object_evas_get(obj));
926 _clear_cb(Widget_Data *wd)
928 wd->anchor_item = NULL;
929 if (wd->queue_idle_enterer)
931 ecore_idle_enterer_del(wd->queue_idle_enterer);
932 wd->queue_idle_enterer = NULL;
934 if (wd->must_recalc_idler)
936 ecore_idler_del(wd->must_recalc_idler);
937 wd->must_recalc_idler = NULL;
939 if (wd->queue) wd->queue = eina_list_free(wd->queue);
940 if (wd->reorder_move_animator)
942 ecore_animator_del(wd->reorder_move_animator);
943 wd->reorder_move_animator = NULL;
945 wd->show_item = NULL;
946 wd->reorder_old_pan_y = 0;
950 _item_unselect(Elm_Gen_Item *it)
952 if ((it->generation < it->wd->generation) || (!it->selected)) return;
953 it->selected = EINA_FALSE;
954 it->wd->selected = eina_list_remove(it->wd->selected, it);
955 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
959 _mouse_move(void *data,
960 Evas *evas __UNUSED__,
964 Elm_Gen_Item *it = data;
965 Evas_Event_Mouse_Move *ev = event_info;
966 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
967 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
969 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
971 if (!it->wd->on_hold)
973 it->wd->on_hold = EINA_TRUE;
974 if ((!it->wd->wasselected) && (!it->flipped))
976 _item_unhighlight(it);
981 if (it->wd->multitouched)
983 it->wd->cur_x = ev->cur.canvas.x;
984 it->wd->cur_y = ev->cur.canvas.y;
987 if ((it->dragging) && (it->down))
989 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
992 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
993 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
994 if (abs((it->wd->history[it->wd->movements].x -
995 it->wd->history[0].x)) > 40)
996 it->wd->swipe = EINA_TRUE;
1002 ecore_timer_del(it->long_timer);
1003 it->long_timer = NULL;
1005 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
1008 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
1012 ecore_timer_del(it->long_timer);
1013 it->long_timer = NULL;
1015 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1017 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
1018 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
1020 if (!it->wd->reorder_start_y)
1021 it->wd->reorder_start_y = it->item->block->y + it->y;
1025 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
1026 y_pos = oy + oh - it->wd->reorder_it->item->h;
1030 if (it->deco_all_view)
1031 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
1033 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1035 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1036 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1040 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1041 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1042 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1043 x = ev->cur.canvas.x - x;
1044 y = ev->cur.canvas.y - y;
1047 if (adx < 0) adx = -dx;
1050 if (ady < 0) ady = -dy;
1053 if ((adx > minw) || (ady > minh))
1055 it->dragging = EINA_TRUE;
1058 ecore_timer_del(it->long_timer);
1059 it->long_timer = NULL;
1061 if ((!it->wd->wasselected) && (!it->flipped))
1063 _item_unhighlight(it);
1068 if ((ady > adx) && (!it->wd->drag_started))
1069 evas_object_smart_callback_call(WIDGET(it),
1070 SIG_DRAG_START_UP, it);
1074 evas_object_smart_callback_call(WIDGET(it),
1075 SIG_DRAG_START_LEFT, it);
1077 evas_object_smart_callback_call(WIDGET(it),
1078 SIG_DRAG_START_RIGHT, it);
1083 if ((ady > adx) && (!it->wd->drag_started))
1084 evas_object_smart_callback_call(WIDGET(it),
1085 SIG_DRAG_START_DOWN, it);
1089 evas_object_smart_callback_call(WIDGET(it),
1090 SIG_DRAG_START_LEFT, it);
1092 evas_object_smart_callback_call(WIDGET(it),
1093 SIG_DRAG_START_RIGHT, it);
1100 _long_press(void *data)
1102 Elm_Gen_Item *it = data, *it_tmp;
1103 Eina_List *list, *l;
1105 it->long_timer = NULL;
1106 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1107 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1108 return ECORE_CALLBACK_CANCEL;
1109 it->wd->longpressed = EINA_TRUE;
1110 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1111 if ((it->wd->reorder_mode) && (!it->group))
1113 it->wd->reorder_it = it;
1114 it->wd->reorder_start_y = 0;
1115 if (it->deco_all_view)
1116 evas_object_raise(it->deco_all_view);
1118 evas_object_raise(VIEW(it));
1120 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1121 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1123 list = elm_genlist_realized_items_get(it->wd->obj);
1124 EINA_LIST_FOREACH(list, l, it_tmp)
1126 if (it != it_tmp) _item_unselect(it_tmp);
1128 if (it->item->items)
1130 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
1132 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
1134 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
1136 return ECORE_CALLBACK_RENEW;
1140 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1142 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1143 return ECORE_CALLBACK_RENEW;
1146 if (!it->wd->decorate_all_mode)
1147 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1149 return ECORE_CALLBACK_CANCEL;
1153 _swipe(Elm_Gen_Item *it)
1158 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1159 elm_widget_item_disabled_get(it)) return;
1160 it->wd->swipe = EINA_FALSE;
1161 for (i = 0; i < it->wd->movements; i++)
1163 sum += it->wd->history[i].x;
1164 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1167 sum /= it->wd->movements;
1168 if (abs(sum - it->wd->history[0].x) <= 10) return;
1169 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1173 _swipe_cancel(void *data)
1175 Elm_Gen_Item *it = data;
1177 if (!it) return ECORE_CALLBACK_CANCEL;
1178 it->wd->swipe = EINA_FALSE;
1179 it->wd->movements = 0;
1180 return ECORE_CALLBACK_RENEW;
1184 _multi_cancel(void *data)
1186 Widget_Data *wd = data;
1188 if (!wd) return ECORE_CALLBACK_CANCEL;
1189 wd->multi_timeout = EINA_TRUE;
1190 return ECORE_CALLBACK_RENEW;
1194 _multi_touch_gesture_eval(void *data)
1196 Elm_Gen_Item *it = data;
1198 it->wd->multitouched = EINA_FALSE;
1199 if (it->wd->multi_timer)
1201 ecore_timer_del(it->wd->multi_timer);
1202 it->wd->multi_timer = NULL;
1204 if (it->wd->multi_timeout)
1206 it->wd->multi_timeout = EINA_FALSE;
1210 Evas_Coord minw = 0, minh = 0;
1211 Evas_Coord off_x, off_y, off_mx, off_my;
1213 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1214 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1215 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1216 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1217 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1219 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1221 if ((off_x + off_mx) > (off_y + off_my))
1223 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1224 evas_object_smart_callback_call(WIDGET(it),
1225 SIG_MULTI_SWIPE_RIGHT, it);
1226 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1227 evas_object_smart_callback_call(WIDGET(it),
1228 SIG_MULTI_SWIPE_LEFT, it);
1229 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1230 evas_object_smart_callback_call(WIDGET(it),
1231 SIG_MULTI_PINCH_OUT, it);
1233 evas_object_smart_callback_call(WIDGET(it),
1234 SIG_MULTI_PINCH_IN, it);
1238 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1239 evas_object_smart_callback_call(WIDGET(it),
1240 SIG_MULTI_SWIPE_DOWN, it);
1241 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1242 evas_object_smart_callback_call(WIDGET(it),
1243 SIG_MULTI_SWIPE_UP, it);
1244 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1245 evas_object_smart_callback_call(WIDGET(it),
1246 SIG_MULTI_PINCH_OUT, it);
1248 evas_object_smart_callback_call(WIDGET(it),
1249 SIG_MULTI_PINCH_IN, it);
1252 it->wd->multi_timeout = EINA_FALSE;
1256 _multi_down(void *data,
1257 Evas *evas __UNUSED__,
1258 Evas_Object *obj __UNUSED__,
1261 Elm_Gen_Item *it = data;
1262 Evas_Event_Multi_Down *ev = event_info;
1264 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1265 it->wd->multi_device = ev->device;
1266 it->wd->multi_down = EINA_TRUE;
1267 it->wd->multitouched = EINA_TRUE;
1268 it->wd->prev_mx = ev->canvas.x;
1269 it->wd->prev_my = ev->canvas.y;
1270 if (!it->wd->wasselected)
1272 _item_unhighlight(it);
1275 it->wd->wasselected = EINA_FALSE;
1276 it->wd->longpressed = EINA_FALSE;
1279 ecore_timer_del(it->long_timer);
1280 it->long_timer = NULL;
1284 it->dragging = EINA_FALSE;
1285 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1287 if (it->item->swipe_timer)
1289 ecore_timer_del(it->item->swipe_timer);
1290 it->item->swipe_timer = NULL;
1292 if (it->wd->on_hold)
1294 it->wd->swipe = EINA_FALSE;
1295 it->wd->movements = 0;
1296 it->wd->on_hold = EINA_FALSE;
1301 _multi_up(void *data,
1302 Evas *evas __UNUSED__,
1303 Evas_Object *obj __UNUSED__,
1306 Elm_Gen_Item *it = data;
1307 Evas_Event_Multi_Up *ev = event_info;
1309 if (it->wd->multi_device != ev->device) return;
1310 it->wd->multi_device = 0;
1311 it->wd->multi_down = EINA_FALSE;
1312 if (it->wd->mouse_down) return;
1313 _multi_touch_gesture_eval(data);
1317 _multi_move(void *data,
1318 Evas *evas __UNUSED__,
1319 Evas_Object *obj __UNUSED__,
1322 Elm_Gen_Item *it = data;
1323 Evas_Event_Multi_Move *ev = event_info;
1325 if (it->wd->multi_device != ev->device) return;
1326 it->wd->cur_mx = ev->cur.canvas.x;
1327 it->wd->cur_my = ev->cur.canvas.y;
1331 _mouse_down(void *data,
1332 Evas *evas __UNUSED__,
1336 Elm_Gen_Item *it = data;
1337 Evas_Event_Mouse_Down *ev = event_info;
1340 Evas_Object *item_obj;
1342 if (ev->button != 1) return;
1345 EINA_LIST_FOREACH(it->content_objs, l, item_obj)
1347 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1349 if (elm_widget_type_get(obj) == _genlist)
1351 EINA_LIST_FOREACH(it->item->flip_content_objs, l, item_obj)
1353 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1355 EINA_LIST_FOREACH(it->item->deco_all_content_objs, l, item_obj)
1357 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1360 it->can_focus = EINA_TRUE;
1362 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1364 it->wd->on_hold = EINA_TRUE;
1367 it->down = EINA_TRUE;
1368 it->dragging = EINA_FALSE;
1369 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1370 it->dx = ev->canvas.x - x;
1371 it->dy = ev->canvas.y - y;
1372 it->wd->mouse_down = EINA_TRUE;
1373 if (!it->wd->multitouched)
1375 it->wd->prev_x = ev->canvas.x;
1376 it->wd->prev_y = ev->canvas.y;
1377 it->wd->multi_timeout = EINA_FALSE;
1378 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1379 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1381 it->wd->longpressed = EINA_FALSE;
1382 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1383 else it->wd->on_hold = EINA_FALSE;
1384 if (it->wd->on_hold) return;
1385 it->wd->wasselected = it->selected;
1386 _item_highlight(it);
1387 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1388 if ((!elm_widget_item_disabled_get(it)) &&
1389 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1391 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1392 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1394 if (it->long_timer) ecore_timer_del(it->long_timer);
1395 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1396 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1398 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1401 it->long_timer = NULL;
1402 it->wd->swipe = EINA_FALSE;
1403 it->wd->movements = 0;
1407 _mouse_up(void *data,
1408 Evas *evas __UNUSED__,
1409 Evas_Object *obj __UNUSED__,
1412 Elm_Gen_Item *it = data;
1413 Evas_Event_Mouse_Up *ev = event_info;
1414 Eina_Bool dragged = EINA_FALSE;
1416 if (ev->button != 1) return;
1417 it->down = EINA_FALSE;
1418 it->wd->mouse_down = EINA_FALSE;
1419 if (it->wd->multitouched)
1421 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1422 if (it->wd->multi_down) return;
1423 _multi_touch_gesture_eval(data);
1426 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1427 else it->wd->on_hold = EINA_FALSE;
1430 ecore_timer_del(it->long_timer);
1431 it->long_timer = NULL;
1435 it->dragging = EINA_FALSE;
1436 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1439 if (it->item->swipe_timer)
1441 ecore_timer_del(it->item->swipe_timer);
1442 it->item->swipe_timer = NULL;
1444 if (it->wd->multi_timer)
1446 ecore_timer_del(it->wd->multi_timer);
1447 it->wd->multi_timer = NULL;
1448 it->wd->multi_timeout = EINA_FALSE;
1450 if (it->wd->on_hold)
1452 if (it->wd->swipe) _swipe(data);
1453 it->wd->longpressed = EINA_FALSE;
1454 it->wd->on_hold = EINA_FALSE;
1457 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1459 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1461 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1463 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1464 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1466 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1467 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1471 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1472 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1474 it->wd->reorder_deleted = EINA_FALSE;
1475 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1476 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1477 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1478 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1480 if (it->wd->longpressed)
1482 it->wd->longpressed = EINA_FALSE;
1483 if ((!it->wd->wasselected) && (!it->flipped))
1485 _item_unhighlight(it);
1488 it->wd->wasselected = EINA_FALSE;
1493 if (it->want_unrealize)
1495 _elm_genlist_item_unrealize(it, EINA_FALSE);
1496 if (it->item->block->want_unrealize)
1497 _item_block_unrealize(it->item->block);
1500 if (elm_widget_item_disabled_get(it) || (dragged) ||
1501 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1503 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1508 _item_highlight(it);
1513 _item_unhighlight(it);
1521 Widget_Data *wd = it->wd;
1524 while (wd->selected)
1526 _item_unhighlight(wd->selected->data);
1527 _item_unselect(wd->selected->data);
1533 const Eina_List *l, *l_next;
1536 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1539 _item_unhighlight(it2);
1540 _item_unselect(it2);
1542 //_item_highlight(it);
1545 _item_highlight(it);
1551 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1553 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1555 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1557 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1559 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1561 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1563 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1568 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1570 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1572 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1574 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1576 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1578 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1580 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1586 _mouse_down_scroller(void *data,
1587 Evas *evas __UNUSED__,
1588 Evas_Object *obj __UNUSED__,
1589 void *event_info __UNUSED__)
1591 Widget_Data *wd = elm_widget_data_get(data);
1594 wd->drag_started = EINA_FALSE;
1598 _mouse_up_scroller(void *data,
1599 Evas *evas __UNUSED__,
1600 Evas_Object *obj __UNUSED__,
1601 void *event_info __UNUSED__)
1603 Widget_Data *wd = elm_widget_data_get(data);
1606 wd->drag_started = EINA_FALSE;
1610 _mouse_move_scroller(void *data,
1611 Evas *evas __UNUSED__,
1612 Evas_Object *obj __UNUSED__,
1615 Widget_Data *wd = elm_widget_data_get(data);
1616 Evas_Event_Mouse_Move *ev = event_info;
1617 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
1620 if (wd->drag_started) return;
1622 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1623 dx = ev->cur.canvas.x - ev->prev.canvas.x;
1624 dy = ev->cur.canvas.y - ev->prev.canvas.y;
1627 if (adx < 0) adx = -dx;
1628 if (ady < 0) ady = -dy;
1629 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
1633 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
1634 wd->drag_started = EINA_TRUE;
1638 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
1639 wd->drag_started = EINA_TRUE;
1645 _signal_expand_toggle(void *data,
1646 Evas_Object *obj __UNUSED__,
1647 const char *emission __UNUSED__,
1648 const char *source __UNUSED__)
1650 Elm_Gen_Item *it = data;
1652 if (it->item->expanded)
1653 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1655 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1659 _signal_expand(void *data,
1660 Evas_Object *obj __UNUSED__,
1661 const char *emission __UNUSED__,
1662 const char *source __UNUSED__)
1664 Elm_Gen_Item *it = data;
1666 if (!it->item->expanded)
1667 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1671 _signal_contract(void *data,
1672 Evas_Object *obj __UNUSED__,
1673 const char *emission __UNUSED__,
1674 const char *source __UNUSED__)
1676 Elm_Gen_Item *it = data;
1678 if (it->item->expanded)
1679 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1683 _scr_hold_timer_cb(void *data)
1685 if (!data) return ECORE_CALLBACK_CANCEL;
1686 Widget_Data *wd = data;
1687 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1688 wd->scr_hold_timer = NULL;
1689 return ECORE_CALLBACK_CANCEL;
1693 _decorate_item_finished_signal_cb(void *data,
1695 const char *emission __UNUSED__,
1696 const char *source __UNUSED__)
1700 Elm_Gen_Item *it = data;
1701 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1703 Evas *te = evas_object_evas_get(obj);
1705 evas_event_freeze(te);
1706 it->item->nocache_once = EINA_FALSE;
1707 _decorate_item_unrealize(it);
1708 //FIXME: group raise
1710 if (it->item->group_item)
1711 evas_object_raise(it->item->VIEW(group_item));
1713 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1714 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1715 evas_event_thaw(te);
1716 evas_event_thaw_eval(te);
1720 _item_cache_clean(Widget_Data *wd)
1722 evas_event_freeze(evas_object_evas_get(wd->obj));
1723 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1727 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1728 wd->item_cache = eina_inlist_remove(wd->item_cache,
1729 wd->item_cache->last);
1730 wd->item_cache_count--;
1731 if (itc->spacer) evas_object_del(itc->spacer);
1732 if (itc->base_view) evas_object_del(itc->base_view);
1733 eina_stringshare_del(itc->item_style);
1736 evas_event_thaw(evas_object_evas_get(wd->obj));
1737 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1741 _item_cache_zero(Widget_Data *wd)
1743 int pmax = wd->item_cache_max;
1744 wd->item_cache_max = 0;
1745 _item_cache_clean(wd);
1746 wd->item_cache_max = pmax;
1750 _item_cache_add(Elm_Gen_Item *it)
1754 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1755 if (it->wd->item_cache_max <= 0)
1757 evas_object_del(VIEW(it));
1761 evas_object_del(it->spacer);
1764 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1765 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1769 it->wd->item_cache_count++;
1770 itc = calloc(1, sizeof(Item_Cache));
1773 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1774 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1777 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1778 EINA_INLIST_GET(itc));
1779 itc->spacer = it->spacer;
1781 itc->base_view = VIEW(it);
1783 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1784 evas_object_hide(itc->base_view);
1785 evas_object_move(itc->base_view, -9999, -9999);
1786 itc->item_style = eina_stringshare_add(it->itc->item_style);
1787 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1788 itc->selected = it->selected;
1789 itc->disabled = elm_widget_item_disabled_get(it);
1790 itc->expanded = it->item->expanded;
1793 ecore_timer_del(it->long_timer);
1794 it->long_timer = NULL;
1796 if (it->item->swipe_timer)
1798 ecore_timer_del(it->item->swipe_timer);
1799 it->item->swipe_timer = NULL;
1801 // FIXME: other callbacks?
1802 edje_object_signal_callback_del_full(itc->base_view,
1803 "elm,action,expand,toggle",
1804 "elm", _signal_expand_toggle, it);
1805 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1807 _signal_expand, it);
1808 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1809 "elm", _signal_contract, it);
1810 _item_mouse_callbacks_del(it, itc->base_view);
1811 _item_cache_clean(it->wd);
1812 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1813 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1817 _item_cache_find(Elm_Gen_Item *it)
1822 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1823 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1825 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1827 if ((itc->tree == tree) &&
1828 (((!it->itc->item_style) && (!itc->item_style)) ||
1829 (it->itc->item_style && itc->item_style &&
1830 (!strcmp(it->itc->item_style, itc->item_style)))))
1832 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1833 EINA_INLIST_GET(itc));
1834 it->wd->item_cache_count--;
1842 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1844 if (it->position_update || it->item->block->position_update)
1846 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1847 it->position_update = EINA_FALSE;
1852 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1854 if (!it->item->nostacking)
1856 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1858 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1859 else evas_object_lower(VIEW(it));
1863 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1864 else evas_object_raise(VIEW(it));
1868 if (it->item->order_num_in & 0x1)
1870 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1871 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1875 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1876 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1881 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1885 if (it->selected != itc->selected)
1889 edje_object_signal_emit(VIEW(it),
1890 "elm,state,selected", "elm");
1891 if (it->deco_all_view)
1892 edje_object_signal_emit(it->deco_all_view,
1893 "elm,state,selected", "elm");
1896 if (elm_widget_item_disabled_get(it) != itc->disabled)
1898 if (elm_widget_item_disabled_get(it))
1899 edje_object_signal_emit(VIEW(it),
1900 "elm,state,disabled", "elm");
1901 if (it->deco_all_view)
1902 edje_object_signal_emit(it->deco_all_view,
1903 "elm,state,disabled", "elm");
1905 if (it->item->expanded != itc->expanded)
1907 if (it->item->expanded)
1908 edje_object_signal_emit(VIEW(it),
1909 "elm,state,expanded", "elm");
1910 if (it->deco_all_view)
1911 edje_object_signal_emit(it->deco_all_view,
1912 "elm,state,expanded", "elm");
1919 edje_object_signal_emit(VIEW(it),
1920 "elm,state,selected", "elm");
1921 if (it->deco_all_view)
1922 edje_object_signal_emit(it->deco_all_view,
1923 "elm,state,selected", "elm");
1925 if (elm_widget_item_disabled_get(it))
1927 edje_object_signal_emit(VIEW(it),
1928 "elm,state,disabled", "elm");
1929 if (it->deco_all_view)
1930 edje_object_signal_emit(it->deco_all_view,
1931 "elm,state,disabled", "elm");
1933 if (it->item->expanded)
1935 edje_object_signal_emit(VIEW(it),
1936 "elm,state,expanded", "elm");
1937 if (it->deco_all_view)
1938 edje_object_signal_emit(it->deco_all_view,
1939 "elm,state,expanded", "elm");
1945 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1947 Elm_Gen_Item *it = data;
1948 if (it) it->defer_unrealize = EINA_TRUE;
1952 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1954 Elm_Gen_Item *it = data;
1955 if (it) it->defer_unrealize = EINA_FALSE;
1960 _item_mode_content_realize(Elm_Gen_Item *it,
1961 Evas_Object *target,
1964 Eina_List **contents_list)
1966 Eina_List *res = *contents_list;
1968 if (it->itc->func.content_get)
1974 EINA_LIST_FOREACH(*source, l, key)
1976 if (parts && fnmatch(parts, key, FNM_PERIOD))
1979 ic = it->itc->func.content_get
1980 ((void *)it->base.data, WIDGET(it), key);
1984 res = eina_list_append(res, ic);
1985 edje_object_part_swallow(target, key, ic);
1986 evas_object_show(ic);
1987 elm_widget_sub_object_add(WIDGET(it), ic);
1990 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1991 // genlist does not need to handle this focus thing.
1992 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1993 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1995 if (elm_widget_item_disabled_get(it))
1996 elm_widget_disabled_set(ic, EINA_TRUE);
2005 _item_mode_content_unrealize(Elm_Gen_Item *it,
2006 Evas_Object *target,
2009 Eina_List **contents_list)
2011 Eina_List *res = *contents_list;
2013 if (it->itc->func.content_get)
2017 Evas_Object *ic = NULL;
2019 EINA_LIST_FOREACH(*source, l, key)
2021 if (parts && fnmatch(parts, key, FNM_PERIOD))
2024 ic = edje_object_part_swallow_get(target, key);
2027 res = eina_list_remove(res, ic);
2028 edje_object_part_unswallow(target, ic);
2029 evas_object_del(ic);
2038 _item_cache_free(Item_Cache *itc)
2040 if (itc->spacer) evas_object_del(itc->spacer);
2041 if (itc->base_view) evas_object_del(itc->base_view);
2042 eina_stringshare_del(itc->item_style);
2047 _item_text_realize(Elm_Gen_Item *it,
2048 Evas_Object *target,
2052 if (it->itc->func.text_get)
2058 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
2059 EINA_LIST_FOREACH(*source, l, key)
2061 if (parts && fnmatch(parts, key, FNM_PERIOD))
2064 char *s = it->itc->func.text_get
2065 ((void *)it->base.data, WIDGET(it), key);
2069 edje_object_part_text_escaped_set(target, key, s);
2074 edje_object_part_text_set(target, key, "");
2081 _item_content_unrealize(Elm_Gen_Item *it,
2082 Evas_Object *target,
2086 Eina_List *res = it->content_objs;
2088 if (it->itc->func.content_get)
2092 Evas_Object *ic = NULL;
2094 EINA_LIST_FOREACH(*source, l, key)
2096 if (parts && fnmatch(parts, key, FNM_PERIOD))
2099 ic = edje_object_part_swallow_get(target, key);
2102 res = eina_list_remove(res, ic);
2103 edje_object_part_unswallow(target, ic);
2104 evas_object_del(ic);
2113 _item_content_realize(Elm_Gen_Item *it,
2114 Evas_Object *target,
2118 Eina_List *res = it->content_objs;
2120 if (it->itc->func.content_get)
2124 Evas_Object *ic = NULL;
2127 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
2129 EINA_LIST_FOREACH(*source, l, key)
2131 if (parts && fnmatch(parts, key, FNM_PERIOD))
2134 if (it->itc->func.content_get)
2135 ic = it->itc->func.content_get
2136 ((void *)it->base.data, WIDGET(it), key);
2139 res = eina_list_append(res, ic);
2140 edje_object_part_swallow(target, key, ic);
2141 evas_object_show(ic);
2142 elm_widget_sub_object_add(WIDGET(it), ic);
2143 evas_object_event_callback_add(ic,
2144 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2145 _changed_size_hints, it);
2148 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2149 // genlist does not need to handle this focus thing.
2150 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2151 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2154 if (elm_widget_item_disabled_get(it))
2155 elm_widget_disabled_set(ic, EINA_TRUE);
2164 _item_state_realize(Elm_Gen_Item *it,
2165 Evas_Object *target,
2169 if (it->itc->func.state_get)
2176 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2177 EINA_LIST_FOREACH(*source, l, key)
2179 if (parts && fnmatch(parts, key, FNM_PERIOD))
2182 Eina_Bool on = it->itc->func.state_get
2183 ((void *)it->base.data, WIDGET(it), key);
2187 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2188 edje_object_signal_emit(target, buf, "elm");
2192 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2193 edje_object_signal_emit(target, buf, "elm");
2200 _item_realize(Elm_Gen_Item *it,
2204 const char *treesize;
2207 Item_Cache *itc = NULL;
2209 if (it->generation < it->wd->generation) return;
2210 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2213 if (it->item->order_num_in != in)
2215 it->item->order_num_in = in;
2216 _elm_genlist_item_odd_even_update(it);
2217 _elm_genlist_item_state_update(it, NULL);
2218 _elm_genlist_item_index_update(it);
2220 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2221 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2224 it->item->order_num_in = in;
2226 if ((it->item->nocache_once) && (!it->flipped))
2227 it->item->nocache_once = EINA_FALSE;
2228 else if (!it->item->nocache)
2229 itc = _item_cache_find(it);
2230 if (itc && (!it->wd->tree_effect_enabled))
2232 VIEW(it) = itc->base_view;
2233 itc->base_view = NULL;
2234 it->spacer = itc->spacer;
2239 const char *stacking_even;
2240 const char *stacking;
2242 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2243 edje_object_scale_set(VIEW(it),
2244 elm_widget_scale_get(WIDGET(it)) *
2245 _elm_config->scale);
2246 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2247 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2249 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2250 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2252 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2254 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2255 elm_widget_style_get(WIDGET(it)));
2257 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2258 if (!stacking_even) stacking_even = "above";
2259 it->item->stacking_even = !!strcmp("above", stacking_even);
2261 stacking = edje_object_data_get(VIEW(it), "stacking");
2262 if (!stacking) stacking = "yes";
2263 it->item->nostacking = !!strcmp("yes", stacking);
2265 edje_object_mirrored_set(VIEW(it),
2266 elm_widget_mirrored_get(WIDGET(it)));
2269 _elm_genlist_item_odd_even_update(it);
2271 treesize = edje_object_data_get(VIEW(it), "treesize");
2272 if (treesize) tsize = atoi(treesize);
2273 if (!it->spacer && treesize)
2276 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2277 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2278 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2282 evas_object_size_hint_min_set(it->spacer,
2283 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2284 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2288 edje_object_signal_callback_add(VIEW(it),
2289 "elm,action,expand,toggle",
2290 "elm", _signal_expand_toggle, it);
2291 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2292 "elm", _signal_expand, it);
2293 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2294 "elm", _signal_contract, it);
2295 _item_mouse_callbacks_add(it, VIEW(it));
2297 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2298 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2299 _decorate_all_item_realize(it, EINA_FALSE);
2301 _elm_genlist_item_state_update(it, itc);
2302 _elm_genlist_item_index_update(it);
2305 if ((calc) && (it->wd->homogeneous) &&
2306 ((it->wd->item_width) ||
2307 ((it->wd->item_width) && (it->wd->group_item_width))))
2309 /* homogenous genlist shortcut */
2310 if (!it->item->mincalcd)
2314 it->item->w = it->item->minw = it->wd->group_item_width;
2315 it->item->h = it->item->minh = it->wd->group_item_height;
2319 it->item->w = it->item->minw = it->wd->item_width;
2320 it->item->h = it->item->minh = it->wd->item_height;
2322 it->item->mincalcd = EINA_TRUE;
2327 /* FIXME: If you see that assert, please notify us and we
2328 will clean our mess */
2329 assert(eina_list_count(it->content_objs) == 0);
2331 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2332 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2333 _item_state_realize(it, VIEW(it), &it->states, NULL);
2336 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2337 if (!(it->item->flip_contents))
2338 it->item->flip_contents =
2339 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2340 it->item->flip_content_objs =
2341 _item_mode_content_realize(it, VIEW(it),
2342 &it->item->flip_contents, NULL,
2343 &it->item->flip_content_objs);
2346 if (!it->item->mincalcd || ((it->wd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
2348 Evas_Coord mw = -1, mh = -1;
2350 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2351 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2352 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2353 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2355 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2356 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2357 it->item->w = it->item->minw = mw;
2358 it->item->h = it->item->minh = mh;
2359 it->item->mincalcd = EINA_TRUE;
2361 if ((!it->wd->group_item_width) && (it->group))
2363 it->wd->group_item_width = mw;
2364 it->wd->group_item_height = mh;
2366 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2368 it->wd->item_width = mw;
2369 it->wd->item_height = mh;
2372 if (!calc) evas_object_show(VIEW(it));
2375 if (it->tooltip.content_cb)
2377 elm_widget_item_tooltip_content_cb_set(it,
2378 it->tooltip.content_cb,
2379 it->tooltip.data, NULL);
2380 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2381 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2384 if (it->mouse_cursor)
2385 elm_widget_item_cursor_set(it, it->mouse_cursor);
2387 it->realized = EINA_TRUE;
2388 it->want_unrealize = EINA_FALSE;
2390 if (itc) _item_cache_free(itc);
2391 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2392 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2395 if (it->item->tree_effect_hideme)
2397 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2398 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2399 it->item->tree_effect_hideme = EINA_FALSE;
2401 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2404 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2406 if (it->itc->decorate_all_item_style)
2408 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2409 edje_object_message_signal_process(it->deco_all_view);
2412 edje_object_message_signal_process(VIEW(it));
2416 _item_unrealize_cb(Elm_Gen_Item *it)
2418 Evas_Object *content;
2419 elm_widget_stringlist_free(it->item->flip_contents);
2420 it->item->flip_contents = NULL;
2421 EINA_LIST_FREE(it->item->flip_content_objs, content)
2422 evas_object_del(content);
2424 if (it->item->nocache_once || it->item->nocache)
2426 evas_object_del(VIEW(it));
2430 evas_object_del(it->spacer);
2436 edje_object_mirrored_set(VIEW(it),
2437 elm_widget_mirrored_get(WIDGET(it)));
2438 edje_object_scale_set(VIEW(it),
2439 elm_widget_scale_get(WIDGET(it))
2440 * _elm_config->scale);
2441 _item_cache_add(it);
2444 _decorate_item_unrealize(it);
2446 it->realized = EINA_FALSE;
2447 it->want_unrealize = EINA_FALSE;
2448 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2452 _item_block_recalc(Item_Block *itb,
2458 Evas_Coord minw = 0, minh = 0;
2459 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2462 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2464 EINA_LIST_FOREACH(itb->items, l, it)
2466 if (it->generation < it->wd->generation) continue;
2467 showme |= it->item->showme;
2472 if (!it->item->mincalcd) changed = EINA_TRUE;
2475 _item_realize(it, in, EINA_TRUE);
2476 _elm_genlist_item_unrealize(it, EINA_TRUE);
2481 _item_realize(it, in, EINA_TRUE);
2482 _elm_genlist_item_unrealize(it, EINA_TRUE);
2487 if (!it->item->mincalcd) changed = EINA_TRUE;
2488 _item_realize(it, in, EINA_FALSE);
2490 minh += it->item->minh;
2491 if (minw < it->item->minw) minw = it->item->minw;
2497 if (changed) itb->wd->pan_changed = changed;
2500 itb->changed = EINA_FALSE;
2501 itb->position_update = EINA_FALSE;
2502 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2503 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2508 _item_block_realize(Item_Block *itb)
2510 if (itb->realized) return;
2511 itb->realized = EINA_TRUE;
2512 itb->want_unrealize = EINA_FALSE;
2516 _item_block_unrealize(Item_Block *itb)
2520 Eina_Bool dragging = EINA_FALSE;
2522 if (!itb->realized) return;
2523 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2524 EINA_LIST_FOREACH(itb->items, l, it)
2526 if (itb->must_recalc || !it->group)
2530 dragging = EINA_TRUE;
2531 it->want_unrealize = EINA_TRUE;
2534 _elm_genlist_item_unrealize(it, EINA_FALSE);
2539 itb->realized = EINA_FALSE;
2540 itb->want_unrealize = EINA_TRUE;
2543 itb->want_unrealize = EINA_FALSE;
2544 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2545 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2549 _get_space_for_reorder_item(Elm_Gen_Item *it)
2551 Evas_Coord rox, roy, row, roh, oy, oh;
2552 Eina_Bool top = EINA_FALSE;
2553 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2554 if (!reorder_it) return 0;
2556 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2557 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2559 if ((it->wd->reorder_start_y < it->item->block->y) &&
2560 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2562 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2563 if (it->item->block->count == 1)
2564 it->wd->reorder_rel = it;
2566 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2567 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2569 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2572 it->item->block->reorder_offset = 0;
2574 it->item->scrl_y += it->item->block->reorder_offset;
2576 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2577 rox, roy + (roh / 2), row, 1));
2580 it->wd->reorder_rel = it;
2581 it->item->scrl_y += it->wd->reorder_it->item->h;
2582 return it->wd->reorder_it->item->h;
2589 _reorder_move_animator_cb(void *data)
2591 Elm_Gen_Item *it = data;
2592 Eina_Bool down = EINA_FALSE;
2594 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2596 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2598 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2601 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2602 if (diff > it->item->h) y = diff / 2;
2604 if (it->item->old_scrl_y < it->item->scrl_y)
2606 it->item->old_scrl_y += y;
2609 else if (it->item->old_scrl_y > it->item->scrl_y)
2611 it->item->old_scrl_y -= y;
2615 if (it->deco_all_view)
2616 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2618 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2619 //FIXME : group raise
2621 _group_items_recalc(it->wd);
2624 if ((it->wd->reorder_pan_move) ||
2625 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2626 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2628 it->item->old_scrl_y = it->item->scrl_y;
2629 it->item->move_effect_enabled = EINA_FALSE;
2630 it->wd->reorder_move_animator = NULL;
2631 return ECORE_CALLBACK_CANCEL;
2633 return ECORE_CALLBACK_RENEW;
2637 _item_position(Elm_Gen_Item *it,
2645 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2646 evas_object_resize(view, it->item->w, it->item->h);
2647 evas_object_move(view, it_x, it_y);
2648 evas_object_show(view);
2649 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2650 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2654 _item_block_position(Item_Block *itb,
2659 //FIXME : group raise
2663 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2664 Eina_Bool vis = EINA_FALSE;
2665 Evas_Coord minh = 0;
2667 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2668 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2669 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2671 EINA_LIST_FOREACH(itb->items, l, it)
2673 if (it->generation < it->wd->generation) continue;
2674 else if (it->wd->reorder_it == it) continue;
2677 it->item->w = itb->w;
2678 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2679 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2681 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2682 cvx, cvy, cvw, cvh));
2683 //FIXME : group raise
2688 if ((itb->realized) && (!it->realized))
2690 if (vis) _item_realize(it, in, EINA_FALSE);
2694 if (vis || it->dragging)
2696 if (it->wd->reorder_mode)
2697 y += _get_space_for_reorder_item(it);
2698 //FIXME : group raise
2700 git = it->item->group_item;
2703 if (git->item->scrl_y < oy)
2704 git->item->scrl_y = oy;
2705 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2706 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2707 git->item->want_realize = EINA_TRUE;
2710 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2712 if (!it->item->move_effect_enabled)
2714 it->item->move_effect_enabled = EINA_TRUE;
2715 it->wd->reorder_move_animator =
2717 _reorder_move_animator_cb, it);
2720 if (!it->item->move_effect_enabled)
2722 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2723 _decorate_all_item_position(it, it->item->scrl_x,
2727 if (!it->wd->tree_effect_enabled ||
2728 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2729 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2730 (it->item->old_scrl_y == it->item->scrl_y)))
2732 if (it->item->deco_it_view)
2733 _item_position(it, it->item->deco_it_view,
2737 _item_position(it, VIEW(it), it->item->scrl_x,
2741 it->item->old_scrl_y = it->item->scrl_y;
2746 if (!it->wd->tree_effect_animator)
2748 it->want_unrealize = EINA_TRUE;
2749 _elm_genlist_item_unrealize(it, EINA_FALSE);
2755 //FIXME : group raise
2759 if (vis) it->item->want_realize = EINA_TRUE;
2763 minh += it->item->minh;
2765 if (!itb->wd->reorder_it) itb->minh = minh;
2766 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2767 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2770 //FIXME: group raise
2773 _group_items_recalc(void *data)
2775 Widget_Data *wd = data;
2779 evas_event_freeze(evas_object_evas_get(wd->obj));
2780 EINA_LIST_FOREACH(wd->group_items, l, git)
2782 if (git->item->want_realize)
2785 _item_realize(git, 0, EINA_FALSE);
2786 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2787 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2788 evas_object_show(VIEW(git));
2789 evas_object_raise(VIEW(git));
2791 else if (!git->item->want_realize && git->realized)
2794 _elm_genlist_item_unrealize(git, EINA_FALSE);
2797 evas_event_thaw(evas_object_evas_get(wd->obj));
2798 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2803 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2805 Elm_Gen_Item *it = data;
2807 if (it->want_unrealize) return;
2808 it->item->mincalcd = EINA_FALSE;
2809 it->item->block->changeme = EINA_TRUE;
2810 if (it->wd->changed_job) ecore_job_del(it->wd->changed_job);
2811 it->wd->changed_job = ecore_job_add(_changed_job, it->wd);
2815 _must_recalc_idler(void *data)
2817 Widget_Data *wd = data;
2818 if (wd->calc_job) ecore_job_del(wd->calc_job);
2819 wd->calc_job = ecore_job_add(_calc_job, wd);
2820 wd->must_recalc_idler = NULL;
2821 return ECORE_CALLBACK_CANCEL;
2825 _scroll_item(Widget_Data *wd)
2827 Elm_Gen_Item *it = NULL;
2828 //FIXME: group raise
2830 Evas_Coord gith = 0;
2832 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2833 if (!wd->show_item) return;
2835 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2837 dx = it->x + it->item->block->x;
2838 dy = it->y + it->item->block->y;
2839 dw = it->item->block->w;
2841 switch (wd->scrollto_type)
2843 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2844 //FIXME: group raise
2846 if (it->item->group_item) gith = it->item->group_item->item->h;
2850 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2851 dy += ((it->item->h / 2) - (oh / 2));
2853 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2855 if ((wd->expanded_item) &&
2856 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2857 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2859 it = wd->expanded_item;
2860 dx = it->x + it->item->block->x;
2861 dy = it->y + it->item->block->y;
2862 //FIXME: group raise
2864 if (it->item->group_item) gith = it->item->group_item->item->h;
2865 dx = it->x + it->item->block->x;
2866 dy = it->y + it->item->block->y - gith;
2868 dw = it->item->block->w;
2872 //FIXME: group raise
2874 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2875 gith = it->item->group_item->item->h;
2883 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2885 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2887 it->item->showme = EINA_FALSE;
2888 wd->show_item = NULL;
2889 wd->auto_scroll_enabled = EINA_FALSE;
2890 wd->check_scroll = EINA_FALSE;
2894 _calc_job(void *data)
2896 Widget_Data *wd = data;
2897 Item_Block *itb, *chb = NULL;
2898 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2899 Evas_Coord pan_w = 0, pan_h = 0;
2901 Eina_Bool minw_change = EINA_FALSE;
2902 Eina_Bool did_must_recalc = EINA_FALSE;
2905 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2906 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2911 evas_event_freeze(evas_object_evas_get(wd->obj));
2912 EINA_INLIST_FOREACH(wd->blocks, itb)
2914 Eina_Bool showme = EINA_FALSE;
2917 showme = itb->showme;
2918 itb->showme = EINA_FALSE;
2921 if (itb->realized) _item_block_unrealize(itb);
2923 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2925 if (itb->must_recalc)
2929 EINA_LIST_FOREACH(itb->items, l, it)
2930 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2931 itb->changed = EINA_TRUE;
2932 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2933 if (itb->realized) _item_block_unrealize(itb);
2934 itb->must_recalc = EINA_FALSE;
2936 showme = _item_block_recalc(itb, in, EINA_FALSE);
2942 if (minw == -1) minw = itb->minw;
2943 else if ((!itb->must_recalc) && (minw < itb->minw))
2946 minw_change = EINA_TRUE;
2951 minw_change = EINA_TRUE;
2957 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2958 wd->check_scroll = EINA_TRUE;
2962 EINA_INLIST_FOREACH(wd->blocks, itb)
2968 if ((chb) && (EINA_INLIST_GET(chb)->next))
2970 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2972 if (itb->realized) _item_block_unrealize(itb);
2975 wd->realminw = minw;
2976 if (minw < wd->w) minw = wd->w;
2977 if ((minw != wd->minw) || (minh != wd->minh))
2981 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2982 _sizing_eval(wd->obj);
2983 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2988 it = wd->anchor_item;
2989 it_y = wd->anchor_y;
2990 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2991 it->item->block->y + it->y + it_y);
2992 wd->anchor_item = it;
2993 wd->anchor_y = it_y;
2996 if (did_must_recalc)
2998 if (!wd->must_recalc_idler)
2999 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
3001 if (wd->check_scroll)
3003 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
3004 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
3005 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3006 switch (wd->scrollto_type)
3008 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
3011 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
3014 case ELM_GENLIST_ITEM_SCROLLTO_IN:
3019 if ((wd->show_item) && (wd->show_item->item->block))
3021 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
3022 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
3028 wd->calc_job = NULL;
3029 evas_object_smart_changed(wd->pan_smart);
3030 evas_event_thaw(evas_object_evas_get(wd->obj));
3031 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3035 _update_job(void *data)
3037 Widget_Data *wd = data;
3041 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
3043 wd->update_job = NULL;
3046 evas_event_freeze(evas_object_evas_get(wd->obj));
3047 EINA_INLIST_FOREACH(wd->blocks, itb)
3049 Evas_Coord itminw, itminh;
3056 _item_block_position(itb, num);
3060 recalc = EINA_FALSE;
3061 EINA_LIST_FOREACH(itb->items, l2, it)
3063 if (it->item->updateme)
3065 itminw = it->item->minw;
3066 itminh = it->item->minh;
3070 _elm_genlist_item_unrealize(it, EINA_FALSE);
3071 _item_realize(it, num, EINA_FALSE);
3072 position = EINA_TRUE;
3076 _item_realize(it, num, EINA_TRUE);
3077 _elm_genlist_item_unrealize(it, EINA_TRUE);
3079 if ((it->item->minw != itminw) || (it->item->minh != itminh))
3081 it->item->updateme = EINA_FALSE;
3085 itb->updateme = EINA_FALSE;
3088 position = EINA_TRUE;
3089 itb->changed = EINA_TRUE;
3090 _item_block_recalc(itb, num0, EINA_FALSE);
3091 _item_block_position(itb, num0);
3096 if (wd->calc_job) ecore_job_del(wd->calc_job);
3097 wd->calc_job = ecore_job_add(_calc_job, wd);
3099 evas_event_thaw(evas_object_evas_get(wd->obj));
3100 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3104 _changed_job(void *data)
3106 Widget_Data *wd = data; Eina_List *l2;
3108 int num, num0, position = 0;
3109 Eina_Bool width_changed = EINA_FALSE, height_changed = EINA_FALSE;
3111 wd->changed_job = NULL;
3113 EINA_INLIST_FOREACH(wd->blocks, itb)
3115 Evas_Coord itminw, itminh;
3122 _item_block_position(itb, num);
3126 width_changed = height_changed = EINA_FALSE;
3127 EINA_LIST_FOREACH(itb->items, l2, it)
3129 if ((!it->item->mincalcd) && (it->realized))
3131 Evas_Coord mw = -1, mh = -1;
3132 itminw = it->item->minw;
3133 itminh = it->item->minh;
3135 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->w;
3136 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3137 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3138 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
3139 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
3140 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3141 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3143 width_changed = EINA_TRUE;
3146 it->item->w = it->item->minw = mw;
3147 it->item->h = it->item->minh = mh;
3148 it->item->mincalcd = EINA_TRUE;
3150 //if ((it->item->minw != itminw) || (it->item->minh != itminh))
3151 //if ((it->item->minh != itminh))
3153 if ((it->item->minw != itminw))
3154 width_changed = EINA_TRUE;
3155 if ((it->item->minh != itminh))
3156 height_changed = EINA_TRUE;
3158 if ((!it->wd->group_item_width) && (it->group))
3160 it->wd->group_item_width = mw;
3161 it->wd->group_item_height = mh;
3163 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
3165 it->wd->item_width = mw;
3166 it->wd->item_height = mh;
3171 itb->changeme = EINA_FALSE;
3172 // TODO: why this is separated.
3176 itb->changed = EINA_TRUE;
3177 _item_block_recalc(itb, num0, 0);
3178 _item_block_position(itb, num0);
3180 else if (width_changed)
3182 _item_block_position(itb, num0);
3187 if (wd->calc_job) ecore_job_del(wd->calc_job);
3188 wd->calc_job = ecore_job_add(_calc_job, wd);
3193 _pan_set(Evas_Object *obj,
3197 Pan *sd = evas_object_smart_data_get(obj);
3201 // Evas_Coord ow, oh;
3202 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3203 // ow = sd->wd->minw - ow;
3204 // if (ow < 0) ow = 0;
3205 // oh = sd->wd->minh - oh;
3206 // if (oh < 0) oh = 0;
3207 // if (x < 0) x = 0;
3208 // if (y < 0) y = 0;
3209 // if (x > ow) x = ow;
3210 // if (y > oh) y = oh;
3211 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
3215 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3217 if ((itb->y + itb->h) > y)
3222 EINA_LIST_FOREACH(itb->items, l2, it)
3224 if ((itb->y + it->y) >= y)
3226 sd->wd->anchor_item = it;
3227 sd->wd->anchor_y = -(itb->y + it->y - y);
3234 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
3238 _pan_get(Evas_Object *obj,
3242 Pan *sd = evas_object_smart_data_get(obj);
3245 if (x) *x = sd->wd->pan_x;
3246 if (y) *y = sd->wd->pan_y;
3250 _pan_max_get(Evas_Object *obj,
3254 Pan *sd = evas_object_smart_data_get(obj);
3258 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3259 ow = sd->wd->minw - ow;
3261 oh = sd->wd->minh - oh;
3268 _pan_min_get(Evas_Object *obj __UNUSED__,
3277 _pan_child_size_get(Evas_Object *obj,
3281 Pan *sd = evas_object_smart_data_get(obj);
3284 if (w) *w = sd->wd->minw;
3285 if (h) *h = sd->wd->minh;
3289 _pan_add(Evas_Object *obj)
3292 Evas_Object_Smart_Clipped_Data *cd;
3295 cd = evas_object_smart_data_get(obj);
3298 sd->__clipped_data = *cd;
3300 evas_object_smart_data_set(obj, sd);
3304 _pan_del(Evas_Object *obj)
3306 Pan *sd = evas_object_smart_data_get(obj);
3311 ecore_job_del(sd->resize_job);
3312 sd->resize_job = NULL;
3318 _pan_resize_job(void *data)
3322 _sizing_eval(sd->wd->obj);
3323 sd->resize_job = NULL;
3327 _pan_resize(Evas_Object *obj,
3331 Pan *sd = evas_object_smart_data_get(obj);
3335 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3336 if ((ow == w) && (oh == h)) return;
3337 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3340 if (sd->resize_job) ecore_job_del(sd->resize_job);
3341 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3343 sd->wd->pan_changed = EINA_TRUE;
3344 evas_object_smart_changed(obj);
3345 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3346 sd->wd->calc_job = NULL;
3350 _pan_calculate(Evas_Object *obj)
3352 Pan *sd = evas_object_smart_data_get(obj);
3354 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3356 //FIXME: group raise
3363 evas_event_freeze(evas_object_evas_get(obj));
3365 if (sd->wd->pan_changed)
3368 sd->wd->pan_changed = EINA_FALSE;
3371 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3372 sd->wd->prev_viewport_w = ow;
3373 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3374 //FIXME: group raise
3376 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3378 git->item->want_realize = EINA_FALSE;
3382 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3384 if (!sd->wd->tree_effect_animator)
3386 _item_tree_effect_before(sd->wd->expanded_item);
3387 evas_object_raise(sd->wd->alpha_bg);
3388 evas_object_show(sd->wd->alpha_bg);
3389 sd->wd->start_time = ecore_time_get();
3390 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3394 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3396 itb->w = sd->wd->minw;
3397 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3398 itb->y - sd->wd->pan_y + oy,
3400 cvx, cvy, cvw, cvh))
3402 if ((!itb->realized) || (itb->changed))
3404 _item_block_realize(itb);
3406 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3407 sd->wd->calc_job = NULL;
3410 _item_block_position(itb, in);
3414 if (itb->realized) _item_block_unrealize(itb);
3418 //FIXME: group raise
3420 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3421 _group_items_recalc(sd->wd);
3423 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3425 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3426 sd->wd->reorder_pan_move = EINA_TRUE;
3427 else sd->wd->reorder_pan_move = EINA_FALSE;
3428 evas_object_raise(sd->wd->VIEW(reorder_it));
3429 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3430 sd->wd->start_time = ecore_loop_time_get();
3433 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3434 _item_auto_scroll(sd->wd);
3436 evas_event_thaw(evas_object_evas_get(obj));
3437 evas_event_thaw_eval(evas_object_evas_get(obj));
3441 _pan_move(Evas_Object *obj,
3442 Evas_Coord x __UNUSED__,
3443 Evas_Coord y __UNUSED__)
3445 Pan *sd = evas_object_smart_data_get(obj);
3449 sd->wd->pan_changed = EINA_TRUE;
3450 evas_object_smart_changed(obj);
3451 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3452 sd->wd->calc_job = NULL;
3456 _hold_on(void *data __UNUSED__,
3458 void *event_info __UNUSED__)
3460 Widget_Data *wd = elm_widget_data_get(obj);
3462 elm_smart_scroller_hold_set(wd->scr, 1);
3466 _hold_off(void *data __UNUSED__,
3468 void *event_info __UNUSED__)
3470 Widget_Data *wd = elm_widget_data_get(obj);
3472 elm_smart_scroller_hold_set(wd->scr, 0);
3476 _freeze_on(void *data __UNUSED__,
3478 void *event_info __UNUSED__)
3480 Widget_Data *wd = elm_widget_data_get(obj);
3482 elm_smart_scroller_freeze_set(wd->scr, 1);
3486 _freeze_off(void *data __UNUSED__,
3488 void *event_info __UNUSED__)
3490 Widget_Data *wd = elm_widget_data_get(obj);
3492 elm_smart_scroller_freeze_set(wd->scr, 0);
3496 _scr_anim_start(void *data,
3497 Evas_Object *obj __UNUSED__,
3498 void *event_info __UNUSED__)
3500 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3504 _scr_anim_stop(void *data,
3505 Evas_Object *obj __UNUSED__,
3506 void *event_info __UNUSED__)
3508 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3512 _scr_drag_start(void *data,
3513 Evas_Object *obj __UNUSED__,
3514 void *event_info __UNUSED__)
3516 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3520 _scr_drag_stop(void *data,
3521 Evas_Object *obj __UNUSED__,
3522 void *event_info __UNUSED__)
3524 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3528 _edge_left(void *data,
3529 Evas_Object *scr __UNUSED__,
3530 void *event_info __UNUSED__)
3532 Evas_Object *obj = data;
3533 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3537 _edge_right(void *data,
3538 Evas_Object *scr __UNUSED__,
3539 void *event_info __UNUSED__)
3541 Evas_Object *obj = data;
3542 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3546 _edge_top(void *data,
3547 Evas_Object *scr __UNUSED__,
3548 void *event_info __UNUSED__)
3550 Evas_Object *obj = data;
3551 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3555 _edge_bottom(void *data,
3556 Evas_Object *scr __UNUSED__,
3557 void *event_info __UNUSED__)
3559 Evas_Object *obj = data;
3560 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3564 _decorate_item_realize(Elm_Gen_Item *it)
3568 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3570 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3571 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3572 edje_object_scale_set(it->item->deco_it_view,
3573 elm_widget_scale_get(WIDGET(it)) *
3574 _elm_config->scale);
3575 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3576 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3578 strncpy(buf, "item", sizeof(buf));
3579 if (it->wd->mode == ELM_LIST_COMPRESS)
3580 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3582 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3583 strncat(buf, "/", sizeof(buf) - strlen(buf));
3584 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3586 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3587 elm_widget_style_get(WIDGET(it)));
3588 edje_object_mirrored_set(it->item->deco_it_view,
3589 elm_widget_mirrored_get(WIDGET(it)));
3591 /* signal callback add */
3592 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3594 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3596 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3599 /* text_get, content_get, state_get */
3600 /* FIXME: If you see that assert, please notify us and we
3601 will clean our mess */
3602 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3604 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3605 if (!it->item->deco_it_contents)
3606 it->item->deco_it_contents =
3607 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3608 it->item->deco_it_content_objs =
3609 _item_mode_content_realize(it, it->item->deco_it_view,
3610 &it->item->deco_it_contents, NULL,
3611 &it->item->deco_it_content_objs);
3612 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3613 edje_object_part_swallow(it->item->deco_it_view,
3614 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3617 it->want_unrealize = EINA_FALSE;
3618 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3619 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3623 _decorate_item_unrealize(Elm_Gen_Item *it)
3625 Widget_Data *wd = it->wd;
3626 Evas_Object *content;
3627 if (!it->item->deco_it_view) return;
3629 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3630 elm_widget_stringlist_free(it->item->deco_it_texts);
3631 it->item->deco_it_texts = NULL;
3632 elm_widget_stringlist_free(it->item->deco_it_contents);
3633 it->item->deco_it_contents = NULL;
3634 elm_widget_stringlist_free(it->item->deco_it_states);
3636 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3637 evas_object_del(content);
3639 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3640 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3641 evas_object_del(it->item->deco_it_view);
3642 it->item->deco_it_view = NULL;
3644 if (wd->mode_item == it)
3645 wd->mode_item = NULL;
3646 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3647 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3651 _decorate_item_set(Elm_Gen_Item *it)
3654 Widget_Data *wd = it->wd;
3659 it->item->nocache_once = EINA_TRUE;
3661 if (wd->scr_hold_timer)
3663 ecore_timer_del(wd->scr_hold_timer);
3664 wd->scr_hold_timer = NULL;
3666 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3667 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3669 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3670 _decorate_item_realize(it);
3671 if (it->item->group_item)
3672 evas_object_raise(it->item->VIEW(group_item));
3673 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3674 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3675 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3677 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3678 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3682 _decorate_item_unset(Widget_Data *wd)
3685 if (!wd->mode_item) return;
3686 char buf[1024], buf2[1024];
3690 it->item->nocache_once = EINA_TRUE;
3692 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3693 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3695 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3696 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3698 wd->mode_item = NULL;
3702 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3704 if ((!it) || (!it->wd->decorate_all_mode)) return;
3705 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3706 evas_object_move(it->deco_all_view, itx, ity);
3710 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3713 const char *stacking_even;
3714 const char *stacking;
3716 if ((!it) || (it->item->decorate_all_item_realized) ||
3717 (it->generation < it->wd->generation))
3720 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3721 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3722 _elm_config->scale);
3723 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3724 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3726 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3727 strncpy(buf, "tree", sizeof(buf));
3728 else strncpy(buf, "item", sizeof(buf));
3729 if (it->wd->mode == ELM_LIST_COMPRESS)
3730 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3732 strncat(buf, "/", sizeof(buf) - strlen(buf));
3733 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3735 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3736 elm_widget_style_get(WIDGET(it)));
3738 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3739 if (!stacking_even) stacking_even = "above";
3740 it->item->stacking_even = !!strcmp("above", stacking_even);
3742 stacking = edje_object_data_get(VIEW(it), "stacking");
3743 if (!stacking) stacking = "yes";
3744 it->item->nostacking = !!strcmp("yes", stacking);
3746 edje_object_mirrored_set(it->deco_all_view,
3747 elm_widget_mirrored_get(WIDGET(it)));
3749 _elm_genlist_item_odd_even_update(it);
3750 _elm_genlist_item_state_update(it, NULL);
3752 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3753 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3755 _item_mouse_callbacks_del(it, VIEW(it));
3756 _item_mouse_callbacks_add(it, it->deco_all_view);
3758 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3759 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3760 if (!it->item->deco_all_contents)
3761 it->item->deco_all_contents =
3762 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "decorate_contents"));
3763 it->item->deco_all_content_objs =
3764 _item_mode_content_realize(it, it->deco_all_view,
3765 &it->item->deco_all_contents, NULL,
3766 &it->item->deco_all_content_objs);
3767 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3768 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3770 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3771 evas_object_show(it->deco_all_view);
3773 if (it->selected) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
3775 it->item->decorate_all_item_realized = EINA_TRUE;
3776 it->want_unrealize = EINA_FALSE;
3780 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3783 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3785 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3786 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3787 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3788 _elm_genlist_item_odd_even_update(it);
3789 _elm_genlist_item_state_update(it, NULL);
3791 evas_object_del(it->deco_all_view);
3792 it->deco_all_view = NULL;
3793 elm_widget_stringlist_free(it->item->deco_all_texts);
3794 it->item->deco_all_texts = NULL;
3795 elm_widget_stringlist_free(it->item->deco_all_contents);
3796 it->item->deco_all_contents = NULL;
3797 elm_widget_stringlist_free(it->item->deco_all_states);
3798 it->item->deco_all_states = NULL;
3799 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3800 evas_object_del(icon);
3801 edje_object_message_signal_process(it->deco_all_view);
3802 _item_mouse_callbacks_del(it, it->deco_all_view);
3803 _item_mouse_callbacks_add(it, VIEW(it));
3805 it->item->decorate_all_item_realized = EINA_FALSE;
3809 _item_auto_scroll(Widget_Data *wd)
3812 Elm_Gen_Item *tmp_item = NULL;
3814 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3816 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3817 if (!tmp_item) return;
3818 wd->show_item = tmp_item;
3819 wd->bring_in = EINA_TRUE;
3820 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3821 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3823 wd->show_item->item->showme = EINA_TRUE;
3824 wd->auto_scroll_enabled = EINA_FALSE;
3832 elm_genlist_add(Evas_Object *parent)
3837 Evas_Coord minw, minh;
3838 static Evas_Smart *smart = NULL;
3842 static Evas_Smart_Class sc;
3844 evas_object_smart_clipped_smart_set(&_pan_sc);
3846 sc.name = "elm_genlist_pan";
3847 sc.version = EVAS_SMART_CLASS_VERSION;
3850 sc.resize = _pan_resize;
3851 sc.move = _pan_move;
3852 sc.calculate = _pan_calculate;
3853 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3856 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3858 ELM_SET_WIDTYPE(widtype, "genlist");
3860 elm_widget_type_set(obj, "genlist");
3861 elm_widget_sub_object_add(parent, obj);
3862 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3863 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3864 elm_widget_data_set(obj, wd);
3865 elm_widget_del_hook_set(obj, _del_hook);
3866 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3867 elm_widget_theme_hook_set(obj, _theme_hook);
3868 elm_widget_can_focus_set(obj, EINA_TRUE);
3869 elm_widget_event_hook_set(obj, _event_hook);
3870 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3871 elm_widget_translate_hook_set(obj, _translate_hook);
3874 wd->scr = elm_smart_scroller_add(e);
3875 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_DOWN,
3876 _mouse_down_scroller, obj);
3877 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_UP,
3878 _mouse_up_scroller, obj);
3879 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_MOVE,
3880 _mouse_move_scroller, obj);
3881 elm_smart_scroller_widget_set(wd->scr, obj);
3882 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3883 elm_widget_style_get(obj));
3884 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3885 _elm_config->thumbscroll_bounce_enable);
3886 elm_widget_resize_object_set(obj, wd->scr);
3888 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3889 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3890 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3891 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3892 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3893 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3894 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3895 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3898 wd->mode = ELM_LIST_SCROLL;
3899 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3900 wd->item_cache_max = wd->max_items_per_block * 2;
3901 wd->longpress_timeout = _elm_config->longpress_timeout;
3902 wd->highlight = EINA_TRUE;
3903 wd->tree_effect_enabled = _elm_config->effect_enable;
3905 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3906 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3907 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3908 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3910 wd->pan_smart = evas_object_smart_add(e, smart);
3911 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3914 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3915 _pan_set, _pan_get, _pan_max_get,
3916 _pan_min_get, _pan_child_size_get);
3918 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3920 evas_object_size_hint_min_set(obj, minw, minh);
3922 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3924 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3930 _item_select(Elm_Gen_Item *it)
3933 Evas_Object *obj = WIDGET(it);
3934 Evas_Object *item_obj;
3936 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3937 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3938 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3942 it->selected = EINA_TRUE;
3943 it->wd->selected = eina_list_append(it->wd->selected, it);
3945 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3947 evas_object_ref(obj);
3950 if (it->wd->last_selected_item &&
3951 (it != (Elm_Gen_Item *) it->wd->last_selected_item))
3953 Elm_Gen_Item *_lsit = (Elm_Gen_Item *)it->wd->last_selected_item;
3955 EINA_LIST_FOREACH(_lsit->content_objs, l, item_obj)
3957 elm_widget_focused_object_clear(item_obj);
3958 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3960 if (elm_widget_type_get(obj) == _genlist)
3962 EINA_LIST_FOREACH(_lsit->item->flip_content_objs, l, item_obj)
3964 elm_widget_focused_object_clear(item_obj);
3965 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3967 EINA_LIST_FOREACH(_lsit->item->deco_all_content_objs, l, item_obj)
3969 elm_widget_focused_object_clear(item_obj);
3970 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3973 _lsit->can_focus = EINA_FALSE;
3975 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3976 if (it->generation == it->wd->generation)
3977 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3980 if ((it->wd->clear_me) && (!it->wd->walking))
3981 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3984 if ((!it->walking) && (it->generation < it->wd->generation))
3989 elm_widget_item_free(it);
3993 it->wd->last_selected_item = (Elm_Object_Item *)it;
3995 evas_object_unref(obj);
3998 static Evas_Object *
3999 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
4001 return edje_object_part_swallow_get(VIEW(it), part);
4005 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
4007 if (content && part)
4009 it->content_objs = eina_list_append(it->content_objs, content);
4010 edje_object_part_swallow(VIEW(it), part, content);
4014 static Evas_Object *
4015 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
4018 obj = edje_object_part_swallow_get(VIEW(it), part);
4019 if (!obj) return NULL;
4020 it->content_objs = eina_list_remove(it->content_objs, obj);
4021 edje_object_part_unswallow(VIEW(it), obj);
4026 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
4028 if (!it->itc->func.text_get) return NULL;
4029 return edje_object_part_text_get(VIEW(it), part);
4033 _item_disable_hook(Elm_Object_Item *it)
4037 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4039 if (_it->generation < _it->wd->generation) return;
4042 elm_genlist_item_selected_set(it, EINA_FALSE);
4046 if (elm_widget_item_disabled_get(it))
4048 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
4049 if (_it->deco_all_view)
4050 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
4054 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
4055 if (_it->deco_all_view)
4056 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
4058 EINA_LIST_FOREACH(_it->content_objs, l, obj)
4059 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
4064 _item_del_pre_hook(Elm_Object_Item *it)
4066 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4068 if ((_it->relcount > 0) || (_it->walking > 0))
4070 elm_genlist_item_subitems_clear(it);
4071 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
4072 _elm_genlist_item_del_notserious(_it);
4073 if (_it->item->block)
4075 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
4076 _it->item->block->changed = EINA_TRUE;
4077 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
4078 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
4082 _it->parent->item->items =
4083 eina_list_remove(_it->parent->item->items, it);
4093 _item_signal_emit_hook(Elm_Object_Item *it,
4094 const char *emission,
4097 edje_object_signal_emit(VIEW(it), emission, source);
4101 _elm_genlist_item_new(Widget_Data *wd,
4102 const Elm_Gen_Item_Class *itc,
4104 Elm_Gen_Item *parent,
4106 const void *func_data)
4110 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
4111 if (!it) return NULL;
4113 it->generation = wd->generation;
4115 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
4116 it->base.data = data;
4117 it->parent = parent;
4118 it->func.func = func;
4119 it->func.data = func_data;
4120 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
4121 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
4122 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
4123 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
4124 elm_widget_item_disable_hook_set(it, _item_disable_hook);
4125 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
4126 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
4129 it->sel_cb = (Ecore_Cb)_item_select;
4134 static Elm_Gen_Item *
4135 _item_new(Widget_Data *wd,
4136 const Elm_Genlist_Item_Class *itc,
4138 Elm_Gen_Item *parent,
4139 Elm_Genlist_Item_Type type,
4141 const void *func_data)
4143 Elm_Gen_Item *it, *it2;
4146 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
4147 if (!it) return NULL;
4148 it->item = ELM_NEW(Elm_Gen_Item_Type);
4149 it->item->type = type;
4150 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
4151 it->item->expanded_depth = 0;
4152 ELM_GEN_ITEM_SETUP(it);
4153 it->mouse_cursor = NULL;
4154 it->can_focus = EINA_TRUE;
4157 if (it->parent->group)
4158 it->item->group_item = parent;
4159 else if (it->parent->item->group_item)
4160 it->item->group_item = it->parent->item->group_item;
4162 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
4164 if (!it2->parent->group) depth += 1;
4166 it->item->expanded_depth = depth;
4172 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
4176 itb = calloc(1, sizeof(Item_Block));
4177 if (!itb) return NULL;
4181 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
4182 _item_block_position_update(wd->blocks, 0);
4186 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4187 itb->position_update = EINA_TRUE;
4188 if (wd->blocks != EINA_INLIST_GET(itb))
4190 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4201 _item_block_add(Widget_Data *wd,
4204 Item_Block *itb = NULL;
4211 itb = calloc(1, sizeof(Item_Block));
4212 if (!itb) return EINA_FALSE;
4214 if (!it->item->rel->item->block)
4217 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4218 itb->items = eina_list_append(itb->items, it);
4219 itb->position_update = EINA_TRUE;
4220 it->position = eina_list_count(itb->items);
4221 it->position_update = EINA_TRUE;
4223 if (wd->blocks != EINA_INLIST_GET(itb))
4225 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4236 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4237 if (it->item->before)
4239 wd->blocks = eina_inlist_prepend_relative
4240 (wd->blocks, EINA_INLIST_GET(itb),
4241 EINA_INLIST_GET(it->item->rel->item->block));
4243 eina_list_prepend_relative_list(itb->items, it, tmp);
4245 /* Update index from where we prepended */
4246 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4247 _item_block_position_update(EINA_INLIST_GET(itb),
4248 it->item->rel->item->block->position);
4252 wd->blocks = eina_inlist_append_relative
4253 (wd->blocks, EINA_INLIST_GET(itb),
4254 EINA_INLIST_GET(it->item->rel->item->block));
4256 eina_list_append_relative_list(itb->items, it, tmp);
4258 /* Update block index from where we appended */
4259 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4260 _item_block_position_update(EINA_INLIST_GET(itb),
4261 it->item->rel->item->block->position + 1);
4267 if (it->item->before)
4271 itb = (Item_Block *)(wd->blocks);
4272 if (itb->count >= wd->max_items_per_block)
4274 itb = _item_block_new(wd, EINA_TRUE);
4275 if (!itb) return EINA_FALSE;
4280 itb = _item_block_new(wd, EINA_TRUE);
4281 if (!itb) return EINA_FALSE;
4283 itb->items = eina_list_prepend(itb->items, it);
4285 _item_position_update(itb->items, 0);
4291 itb = (Item_Block *)(wd->blocks->last);
4292 if (itb->count >= wd->max_items_per_block)
4294 itb = _item_block_new(wd, EINA_FALSE);
4295 if (!itb) return EINA_FALSE;
4300 itb = _item_block_new(wd, EINA_FALSE);
4301 if (!itb) return EINA_FALSE;
4303 itb->items = eina_list_append(itb->items, it);
4304 it->position = eina_list_count(itb->items);
4312 if (it->item->rel->item->queued)
4314 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
4315 on sorted insertion order, so the queue is not always ordered like the item list.
4316 This lead to issue where we depend on an item that is not yet created. As a quick
4317 work around, we reschedule the calc of the item and stop reordering the list to
4318 prevent any nasty issue to show up here.
4320 wd->queue = eina_list_append(wd->queue, it);
4321 wd->requeued = EINA_TRUE;
4322 it->item->queued = EINA_TRUE;
4325 itb = it->item->rel->item->block;
4326 if (!itb) goto newblock;
4327 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4328 if (it->item->before)
4330 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4331 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4335 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4336 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4340 itb->changed = EINA_TRUE;
4341 it->item->block = itb;
4342 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
4343 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
4346 it->item->rel->relcount--;
4347 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
4349 _item_del(it->item->rel);
4350 elm_widget_item_free(it->item->rel);
4352 it->item->rel = NULL;
4354 if (itb->count > itb->wd->max_items_per_block)
4359 Eina_Bool done = EINA_FALSE;
4361 newc = itb->count / 2;
4363 if (EINA_INLIST_GET(itb)->prev)
4365 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4367 if (itbp->count + newc < wd->max_items_per_block / 2)
4369 /* moving items to previous block */
4370 while ((itb->count > newc) && (itb->items))
4372 it2 = eina_list_data_get(itb->items);
4373 itb->items = eina_list_remove_list(itb->items, itb->items);
4376 itbp->items = eina_list_append(itbp->items, it2);
4377 it2->item->block = itbp;
4385 if (!done && EINA_INLIST_GET(itb)->next)
4387 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4389 if (itbn->count + newc < wd->max_items_per_block / 2)
4391 /* moving items to next block */
4392 while ((itb->count > newc) && (itb->items))
4396 l = eina_list_last(itb->items);
4397 it2 = eina_list_data_get(l);
4398 itb->items = eina_list_remove_list(itb->items, l);
4401 itbn->items = eina_list_prepend(itbn->items, it2);
4402 it2->item->block = itbn;
4412 /* moving items to new block */
4413 itb2 = calloc(1, sizeof(Item_Block));
4414 if (!itb2) return EINA_FALSE;
4417 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4418 EINA_INLIST_GET(itb));
4419 itb2->changed = EINA_TRUE;
4420 while ((itb->count > newc) && (itb->items))
4424 l = eina_list_last(itb->items);
4426 itb->items = eina_list_remove_list(itb->items, l);
4429 itb2->items = eina_list_prepend(itb2->items, it2);
4430 it2->item->block = itb2;
4440 _queue_process(Widget_Data *wd)
4443 Eina_Bool showme = EINA_FALSE;
4446 t0 = ecore_loop_time_get();
4447 //evas_event_freeze(evas_object_evas_get(wd->obj));
4448 for (n = 0; (wd->queue) && (n < 128); n++)
4452 it = eina_list_data_get(wd->queue);
4453 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4454 it->item->queued = EINA_FALSE;
4455 if (!_item_block_add(wd, it)) continue;
4457 _item_block_realize(it->item->block);
4458 t = ecore_time_get();
4459 if (it->item->block->changed)
4461 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4462 it->item->block->changed = 0;
4463 if (wd->pan_changed)
4465 if (wd->calc_job) ecore_job_del(wd->calc_job);
4466 wd->calc_job = NULL;
4468 wd->pan_changed = EINA_FALSE;
4471 if (showme) it->item->block->showme = EINA_TRUE;
4472 /* same as eina_inlist_count > 1 */
4473 if (wd->blocks && wd->blocks->next)
4475 if ((t - t0) > (ecore_animator_frametime_get())) break;
4478 //evas_event_thaw(evas_object_evas_get(wd->obj));
4479 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4484 _idle_process(void *data, Eina_Bool *wakeup)
4486 Widget_Data *wd = data;
4489 //static double q_start = 0.0;
4490 //if (q_start == 0.0) q_start = ecore_time_get();
4492 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4496 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4498 return ECORE_CALLBACK_CANCEL;
4500 return ECORE_CALLBACK_RENEW;
4504 _item_idle_enterer(void *data)
4506 Widget_Data *wd = data;
4507 Eina_Bool wakeup = EINA_FALSE;
4508 Eina_Bool ok = _idle_process(data, &wakeup);
4513 if (wd->calc_job) ecore_job_del(wd->calc_job);
4514 wd->calc_job = ecore_job_add(_calc_job, wd);
4516 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4521 _item_queue(Widget_Data *wd,
4525 if (it->item->queued) return;
4526 it->item->queued = EINA_TRUE;
4527 if (cb && !wd->requeued)
4528 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4530 wd->queue = eina_list_append(wd->queue, it);
4531 // FIXME: why does a freeze then thaw here cause some genlist
4532 // elm_genlist_item_append() to be much much slower?
4533 // evas_event_freeze(evas_object_evas_get(wd->obj));
4534 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4536 if (wd->queue_idle_enterer)
4538 ecore_idle_enterer_del(wd->queue_idle_enterer);
4539 wd->queue_idle_enterer = NULL;
4543 // evas_event_thaw(evas_object_evas_get(wd->obj));
4544 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4545 if (!wd->queue_idle_enterer)
4546 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4550 _elm_genlist_item_compare(const void *data, const void *data1)
4552 const Elm_Gen_Item *it, *item1;
4553 it = ELM_GEN_ITEM_FROM_INLIST(data);
4554 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4555 return it->wd->item_compare_cb(it, item1);
4559 _elm_genlist_item_list_compare(const void *data, const void *data1)
4561 const Elm_Gen_Item *it = data;
4562 const Elm_Gen_Item *item1 = data1;
4563 return it->wd->item_compare_cb(it, item1);
4566 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4568 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4573 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4574 _item_block_del(it);
4576 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4577 it->item->rel = after;
4578 it->item->rel->relcount++;
4579 it->item->before = EINA_FALSE;
4580 if (after->item->group_item) it->item->group_item = after->item->group_item;
4581 _item_queue(it->wd, it, NULL);
4583 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4586 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4588 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4591 if (!before) return;
4593 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4594 _item_block_del(it);
4595 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4596 it->item->rel = before;
4597 it->item->rel->relcount++;
4598 it->item->before = EINA_TRUE;
4599 if (before->item->group_item) it->item->group_item = before->item->group_item;
4600 _item_queue(it->wd, it, NULL);
4602 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4606 elm_genlist_items_count(const Evas_Object *obj)
4608 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4609 Widget_Data *wd = elm_widget_data_get(obj);
4611 return wd->item_count;
4614 EAPI Elm_Object_Item *
4615 elm_genlist_item_append(Evas_Object *obj,
4616 const Elm_Genlist_Item_Class *itc,
4618 Elm_Object_Item *parent,
4619 Elm_Genlist_Item_Type type,
4621 const void *func_data)
4623 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4624 Widget_Data *wd = elm_widget_data_get(obj);
4625 if (!wd) return NULL;
4626 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4628 if (!it) return NULL;
4632 wd->group_items = eina_list_append(wd->group_items, it);
4633 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4634 it->item->rel = NULL;
4638 Elm_Gen_Item *it2 = NULL;
4639 Eina_List *ll = eina_list_last(it->parent->item->items);
4640 if (ll) it2 = ll->data;
4641 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4642 if (!it2) it2 = it->parent;
4644 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4645 EINA_INLIST_GET(it2));
4646 it->item->rel = it2;
4647 it->item->rel->relcount++;
4649 it->item->before = EINA_FALSE;
4650 _item_queue(wd, it, NULL);
4651 return (Elm_Object_Item *)it;
4654 EAPI Elm_Object_Item *
4655 elm_genlist_item_prepend(Evas_Object *obj,
4656 const Elm_Genlist_Item_Class *itc,
4658 Elm_Object_Item *parent,
4659 Elm_Genlist_Item_Type type,
4661 const void *func_data)
4663 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4664 Widget_Data *wd = elm_widget_data_get(obj);
4665 if (!wd) return NULL;
4666 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4668 if (!it) return NULL;
4672 wd->group_items = eina_list_prepend(wd->group_items, it);
4673 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4674 it->item->rel = NULL;
4678 Elm_Gen_Item *it2 = NULL;
4679 Eina_List *ll = it->parent->item->items;
4680 if (ll) it2 = ll->data;
4681 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4682 if (!it2) it2 = it->parent;
4684 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4685 EINA_INLIST_GET(it2));
4686 it->item->rel = it2;
4687 it->item->rel->relcount++;
4689 it->item->before = EINA_TRUE;
4690 _item_queue(wd, it, NULL);
4691 return (Elm_Object_Item *)it;
4694 EAPI Elm_Object_Item *
4695 elm_genlist_item_insert_after(Evas_Object *obj,
4696 const Elm_Genlist_Item_Class *itc,
4698 Elm_Object_Item *parent,
4699 Elm_Object_Item *after,
4700 Elm_Genlist_Item_Type type,
4702 const void *func_data)
4704 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4705 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4706 Widget_Data *wd = elm_widget_data_get(obj);
4707 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4708 if (!wd) return NULL;
4709 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4710 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4712 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4714 if (!it) return NULL;
4717 if ((it->group) && (_after->group))
4718 wd->group_items = eina_list_append_relative(wd->group_items, it,
4723 it->parent->item->items =
4724 eina_list_append_relative(it->parent->item->items, it, _after);
4726 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4727 EINA_INLIST_GET(_after));
4728 it->item->rel = _after;
4729 it->item->rel->relcount++;
4730 it->item->before = EINA_FALSE;
4731 _item_queue(wd, it, NULL);
4732 return (Elm_Object_Item *)it;
4735 EAPI Elm_Object_Item *
4736 elm_genlist_item_insert_before(Evas_Object *obj,
4737 const Elm_Genlist_Item_Class *itc,
4739 Elm_Object_Item *parent,
4740 Elm_Object_Item *before,
4741 Elm_Genlist_Item_Type type,
4743 const void *func_data)
4745 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4746 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4747 Widget_Data *wd = elm_widget_data_get(obj);
4748 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4749 if (!wd) return NULL;
4750 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4751 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4753 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4755 if (!it) return NULL;
4758 if (it->group && _before->group)
4759 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4764 it->parent->item->items =
4765 eina_list_prepend_relative(it->parent->item->items, it, _before);
4767 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4768 EINA_INLIST_GET(_before));
4769 it->item->rel = _before;
4770 it->item->rel->relcount++;
4771 it->item->before = EINA_TRUE;
4772 _item_queue(wd, it, NULL);
4773 return (Elm_Object_Item *)it;
4776 EAPI Elm_Object_Item *
4777 elm_genlist_item_sorted_insert(Evas_Object *obj,
4778 const Elm_Genlist_Item_Class *itc,
4780 Elm_Object_Item *parent,
4781 Elm_Genlist_Item_Type type,
4782 Eina_Compare_Cb comp,
4784 const void *func_data)
4786 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4787 Widget_Data *wd = elm_widget_data_get(obj);
4788 if (!wd) return NULL;
4789 Elm_Gen_Item *rel = NULL;
4790 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4792 if (!it) return NULL;
4794 wd->item_compare_cb = comp;
4801 l = eina_list_search_sorted_near_list(it->parent->item->items,
4802 _elm_genlist_item_list_compare,
4806 rel = eina_list_data_get(l);
4810 if (cmp_result >= 0)
4812 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4813 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4814 it->item->before = EINA_FALSE;
4816 else if (cmp_result < 0)
4818 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4819 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4820 it->item->before = EINA_TRUE;
4827 wd->state = eina_inlist_sorted_state_new();
4828 eina_inlist_sorted_state_init(wd->state, wd->items);
4829 wd->requeued = EINA_FALSE;
4833 wd->group_items = eina_list_append(wd->group_items, it);
4835 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4836 _elm_genlist_item_compare, wd->state);
4838 if (EINA_INLIST_GET(it)->next)
4840 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4841 it->item->before = EINA_TRUE;
4843 else if (EINA_INLIST_GET(it)->prev)
4845 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4846 it->item->before = EINA_FALSE;
4852 it->item->rel = rel;
4853 it->item->rel->relcount++;
4856 _item_queue(wd, it, _elm_genlist_item_list_compare);
4858 return (Elm_Object_Item *)it;
4862 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4864 Eina_Inlist *next, *l;
4865 Widget_Data *wd = elm_widget_data_get(obj);
4868 if (!standby) wd->generation++;
4872 eina_inlist_sorted_state_free(wd->state);
4876 if (wd->walking > 0)
4878 wd->clear_me = EINA_TRUE;
4881 evas_event_freeze(evas_object_evas_get(wd->obj));
4882 for (l = wd->items, next = l ? l->next : NULL;
4884 l = next, next = next ? next->next : NULL)
4886 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4888 if (it->generation < wd->generation)
4890 Elm_Gen_Item *itn = NULL;
4892 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4893 if (itn) itn->walking++; /* prevent early death of subitem */
4895 elm_widget_item_free(it);
4896 if (itn) itn->walking--;
4899 wd->clear_me = EINA_FALSE;
4900 wd->pan_changed = EINA_TRUE;
4903 ecore_job_del(wd->calc_job);
4904 wd->calc_job = NULL;
4906 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4907 if (wd->clear_cb) wd->clear_cb(wd);
4913 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4914 wd->alpha_bg = NULL;
4918 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4919 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4921 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4922 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4923 evas_event_thaw(evas_object_evas_get(wd->obj));
4924 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4928 elm_genlist_clear(Evas_Object *obj)
4930 ELM_CHECK_WIDTYPE(obj, widtype);
4931 _elm_genlist_clear(obj, EINA_FALSE);
4935 elm_genlist_multi_select_set(Evas_Object *obj,
4938 ELM_CHECK_WIDTYPE(obj, widtype);
4939 Widget_Data *wd = elm_widget_data_get(obj);
4941 wd->multi = !!multi;
4945 elm_genlist_multi_select_get(const Evas_Object *obj)
4947 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4948 Widget_Data *wd = elm_widget_data_get(obj);
4949 if (!wd) return EINA_FALSE;
4953 EAPI Elm_Object_Item *
4954 elm_genlist_selected_item_get(const Evas_Object *obj)
4956 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4957 Widget_Data *wd = elm_widget_data_get(obj);
4958 if (!wd) return NULL;
4959 if (wd->selected) return wd->selected->data;
4963 EAPI const Eina_List *
4964 elm_genlist_selected_items_get(const Evas_Object *obj)
4966 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4967 Widget_Data *wd = elm_widget_data_get(obj);
4968 if (!wd) return NULL;
4969 return wd->selected;
4973 elm_genlist_realized_items_get(const Evas_Object *obj)
4975 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4976 Widget_Data *wd = elm_widget_data_get(obj);
4977 Eina_List *list = NULL;
4979 Eina_Bool done = EINA_FALSE;
4980 if (!wd) return NULL;
4981 EINA_INLIST_FOREACH(wd->blocks, itb)
4989 EINA_LIST_FOREACH(itb->items, l, it)
4991 if (it->realized) list = eina_list_append(list, it);
5002 EAPI Elm_Object_Item *
5003 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5008 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5009 Widget_Data *wd = elm_widget_data_get(obj);
5010 Evas_Coord ox, oy, ow, oh;
5013 if (!wd) return NULL;
5014 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5016 EINA_INLIST_FOREACH(wd->blocks, itb)
5021 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
5022 oy + itb->y - itb->wd->pan_y,
5023 itb->w, itb->h, x, y, 1, 1))
5025 EINA_LIST_FOREACH(itb->items, l, it)
5027 Evas_Coord itx, ity;
5029 itx = ox + itb->x + it->x - itb->wd->pan_x;
5030 ity = oy + itb->y + it->y - itb->wd->pan_y;
5031 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5035 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5036 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5040 return (Elm_Object_Item *)it;
5042 lasty = ity + it->item->h;
5047 if (y > lasty) *posret = 1;
5053 EAPI Elm_Object_Item *
5054 elm_genlist_first_item_get(const Evas_Object *obj)
5056 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5057 Widget_Data *wd = elm_widget_data_get(obj);
5058 if (!wd) return NULL;
5059 if (!wd->items) return NULL;
5060 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
5061 while ((it) && (it->generation < wd->generation))
5062 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5063 return (Elm_Object_Item *)it;
5066 EAPI Elm_Object_Item *
5067 elm_genlist_last_item_get(const Evas_Object *obj)
5069 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5070 Widget_Data *wd = elm_widget_data_get(obj);
5071 if (!wd) return NULL;
5072 if (!wd->items) return NULL;
5073 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
5074 while ((it) && (it->generation < wd->generation))
5075 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5076 return (Elm_Object_Item *)it;
5079 EAPI Elm_Object_Item *
5080 elm_genlist_item_next_get(const Elm_Object_Item *it)
5082 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5083 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5086 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
5087 if ((_it) && (_it->generation == _it->wd->generation)) break;
5089 return (Elm_Object_Item *) _it;
5092 EAPI Elm_Object_Item *
5093 elm_genlist_item_prev_get(const Elm_Object_Item *it)
5095 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5096 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5099 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
5100 if ((_it) && (_it->generation == _it->wd->generation)) break;
5102 return (Elm_Object_Item *) _it;
5105 EAPI Elm_Object_Item *
5106 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5108 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5109 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
5113 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
5115 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5116 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
5118 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5120 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
5121 _item_subitems_clear(_it);
5124 if (!wd->tree_effect_animator)
5126 wd->expanded_item = _it;
5127 _item_tree_effect_before(_it);
5128 evas_object_raise(wd->alpha_bg);
5129 evas_object_show(wd->alpha_bg);
5130 wd->start_time = ecore_time_get();
5131 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
5134 _item_subitems_clear(_it);
5139 elm_genlist_item_selected_set(Elm_Object_Item *it,
5142 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5143 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5144 Widget_Data *wd = _it->wd;
5146 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
5148 selected = !!selected;
5149 if (_it->selected == selected) return;
5155 while (wd->selected)
5157 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
5158 _it->unsel_cb(wd->selected->data);
5161 _it->highlight_cb(_it);
5165 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
5170 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5172 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5173 return ((Elm_Gen_Item *)it)->selected;
5177 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5180 if (it->item->expanded)
5182 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5186 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5189 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5190 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5197 _elm_genlist_move_items_set(Elm_Gen_Item *it)
5200 Elm_Gen_Item *it2 = NULL;
5201 Evas_Coord ox, oy, ow, oh, dh = 0;
5203 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
5205 if (it->item->expanded)
5207 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
5208 EINA_LIST_FOREACH_SAFE(it->wd->move_items, l, ll, it2)
5210 if (it2 == it->wd->expanded_next_item) break;
5211 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
5216 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
5217 it2 = it->wd->expanded_next_item;
5218 while (it2 && (dh < oy + oh))
5221 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
5222 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5228 elm_genlist_item_expanded_set(Elm_Object_Item *it,
5231 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5232 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5233 expanded = !!expanded;
5234 if (_it->item->expanded == expanded) return;
5235 _it->item->expanded = expanded;
5236 _it->wd->expanded_item = _it;
5237 _elm_genlist_move_items_set(_it);
5239 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
5240 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
5242 if (_it->item->expanded)
5244 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
5246 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
5247 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
5248 _it->wd->auto_scroll_enabled = EINA_TRUE;
5252 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
5254 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
5255 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
5256 _it->wd->auto_scroll_enabled = EINA_FALSE;
5261 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5263 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5264 return ((Elm_Gen_Item *)it)->item->expanded;
5268 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5270 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
5271 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5274 EINA_DEPRECATED EAPI void
5275 elm_genlist_item_display_only_set(Elm_Object_Item *it,
5276 Eina_Bool display_only)
5278 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5279 display_only = !!display_only;
5282 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
5285 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5286 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5287 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
5291 EINA_DEPRECATED EAPI Eina_Bool
5292 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
5294 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5295 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5296 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5297 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5298 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5304 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
5305 Elm_Genlist_Item_Scrollto_Type type,
5312 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5313 Evas_Coord gith = 0;
5314 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5315 if ((_it->item->queued) || (!_it->item->mincalcd))
5317 _it->wd->show_item = _it;
5318 _it->wd->bring_in = bring_in;
5319 _it->wd->scrollto_type = type;
5320 _it->item->showme = EINA_TRUE;
5323 if (_it->wd->show_item)
5325 _it->wd->show_item->item->showme = EINA_FALSE;
5326 _it->wd->show_item = NULL;
5329 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
5332 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5333 if ((_it->item->group_item) &&
5334 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
5335 gith = _it->item->group_item->item->h;
5337 *y = _it->y + _it->item->block->y - gith;
5339 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5340 if (_it->item->group_item) gith = _it->item->group_item->item->h;
5341 *y = _it->y + _it->item->block->y - gith;
5343 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5344 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
5350 *x = _it->x + _it->item->block->x;
5351 *w = _it->item->block->w;
5356 elm_genlist_item_promote(Elm_Object_Item *it)
5358 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5359 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5360 if (_it->generation < _it->wd->generation) return;
5361 _item_move_before(_it,
5362 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
5366 elm_genlist_item_demote(Elm_Object_Item *it)
5368 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5369 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5370 if (_it->generation < _it->wd->generation) return;
5371 _item_move_after(_it,
5372 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
5376 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5378 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5379 Evas_Coord x, y, w, h;
5380 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5382 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
5383 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
5387 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5390 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5391 Evas_Coord x, y, w, h;
5392 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5394 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
5395 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
5399 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5401 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5403 Evas_Object *content;
5404 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5406 elm_widget_sub_object_del(WIDGET(it), content);
5407 evas_object_smart_member_del(content);
5408 evas_object_hide(content);
5409 if (l) *l = eina_list_append(*l, content);
5414 elm_genlist_item_update(Elm_Object_Item *it)
5416 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5417 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5419 if (!_it->item->block) return;
5420 if (_it->generation < _it->wd->generation) return;
5421 _it->item->mincalcd = EINA_FALSE;
5422 _it->item->updateme = EINA_TRUE;
5423 _it->item->block->updateme = EINA_TRUE;
5424 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5425 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5429 elm_genlist_item_fields_update(Elm_Object_Item *it,
5431 Elm_Genlist_Item_Field_Type itf)
5433 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5434 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5436 if (!_it->item->block) return;
5437 if (_it->generation < _it->wd->generation) return;
5439 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5440 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5441 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5443 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5444 &_it->contents, parts);
5445 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5446 &_it->contents, parts);
5450 _it->item->flip_content_objs =
5451 _item_mode_content_unrealize(_it, VIEW(_it),
5452 &_it->item->flip_contents, parts,
5453 &_it->item->flip_content_objs);
5454 _it->item->flip_content_objs =
5455 _item_mode_content_realize(_it, VIEW(_it),
5456 &_it->item->flip_contents, parts,
5457 &_it->item->flip_content_objs);
5459 if (_it->item->deco_it_view)
5461 _it->item->deco_it_content_objs =
5462 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5463 &_it->item->deco_it_contents, parts,
5464 &_it->item->deco_it_content_objs);
5465 _it->item->deco_it_content_objs =
5466 _item_mode_content_realize(_it, _it->item->deco_it_view,
5467 &_it->item->deco_it_contents, parts,
5468 &_it->item->deco_it_content_objs);
5470 if (_it->wd->decorate_all_mode)
5472 _it->item->deco_all_content_objs =
5473 _item_mode_content_unrealize(_it, _it->deco_all_view,
5474 &_it->item->deco_all_contents, parts,
5475 &_it->item->deco_all_content_objs);
5476 _it->item->deco_all_content_objs =
5477 _item_mode_content_realize(_it, _it->deco_all_view,
5478 &_it->item->deco_all_contents, parts,
5479 &_it->item->deco_all_content_objs);
5482 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5483 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5487 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5488 const Elm_Genlist_Item_Class *itc)
5490 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5491 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5493 if (!_it->item->block) return;
5494 EINA_SAFETY_ON_NULL_RETURN(itc);
5495 if (_it->generation < _it->wd->generation) return;
5497 _it->item->nocache_once = EINA_TRUE;
5499 elm_widget_stringlist_free(_it->texts);
5501 elm_widget_stringlist_free(_it->contents);
5502 _it->contents = NULL;
5503 elm_widget_stringlist_free(_it->states);
5508 elm_widget_stringlist_free(_it->item->flip_contents);
5509 _it->item->flip_contents = NULL;
5511 if (_it->item->deco_it_view)
5513 elm_widget_stringlist_free(_it->item->deco_it_texts);
5514 _it->item->deco_it_texts = NULL;
5515 elm_widget_stringlist_free(_it->item->deco_it_contents);
5516 _it->item->deco_it_contents = NULL;
5518 if (_it->wd->decorate_all_mode)
5520 elm_widget_stringlist_free(_it->item->deco_all_texts);
5521 _it->item->deco_all_texts = NULL;
5522 elm_widget_stringlist_free(_it->item->deco_all_contents);
5523 _it->item->deco_all_contents = NULL;
5526 elm_genlist_item_update(it);
5529 EAPI const Elm_Genlist_Item_Class *
5530 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5532 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5533 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5534 if (_it->generation < _it->wd->generation) return NULL;
5538 static Evas_Object *
5539 _elm_genlist_item_label_create(void *data,
5540 Evas_Object *obj __UNUSED__,
5541 Evas_Object *tooltip,
5542 void *it __UNUSED__)
5544 Evas_Object *label = elm_label_add(tooltip);
5547 elm_object_style_set(label, "tooltip");
5548 elm_object_text_set(label, data);
5553 _elm_genlist_item_label_del_cb(void *data,
5554 Evas_Object *obj __UNUSED__,
5555 void *event_info __UNUSED__)
5557 eina_stringshare_del(data);
5561 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5564 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5565 text = eina_stringshare_add(text);
5566 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5568 _elm_genlist_item_label_del_cb);
5572 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5573 Elm_Tooltip_Item_Content_Cb func,
5575 Evas_Smart_Cb del_cb)
5577 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5578 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5580 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5583 if (_it->tooltip.del_cb)
5584 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5586 _it->tooltip.content_cb = func;
5587 _it->tooltip.data = data;
5588 _it->tooltip.del_cb = del_cb;
5592 elm_widget_item_tooltip_content_cb_set(_it,
5593 _it->tooltip.content_cb,
5594 _it->tooltip.data, NULL);
5595 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5596 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5602 if (del_cb) del_cb((void *)data, NULL, NULL);
5606 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5608 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5609 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5611 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5612 elm_widget_item_tooltip_unset(_it);
5614 if (_it->tooltip.del_cb)
5615 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5616 _it->tooltip.del_cb = NULL;
5617 _it->tooltip.content_cb = NULL;
5618 _it->tooltip.data = NULL;
5619 _it->tooltip.free_size = EINA_FALSE;
5620 if (_it->tooltip.style)
5621 elm_genlist_item_tooltip_style_set(it, NULL);
5625 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5628 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5629 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5631 eina_stringshare_replace(&_it->tooltip.style, style);
5632 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5636 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5638 return elm_object_item_tooltip_style_get(it);
5642 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5645 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5646 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5648 _it->tooltip.free_size = disable;
5649 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5654 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5656 return elm_object_tooltip_window_mode_get(VIEW(it));
5660 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5663 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5664 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5665 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5666 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5670 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5672 return elm_widget_item_cursor_get(it);
5676 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5678 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5679 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5681 if (!_it->mouse_cursor) return;
5683 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5685 eina_stringshare_del(_it->mouse_cursor);
5686 _it->mouse_cursor = NULL;
5690 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5693 elm_widget_item_cursor_style_set(it, style);
5697 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5699 return elm_widget_item_cursor_style_get(it);
5703 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5704 Eina_Bool engine_only)
5706 elm_widget_item_cursor_engine_only_set(it, engine_only);
5710 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5712 return elm_widget_item_cursor_engine_only_get(it);
5716 elm_genlist_item_index_get(const Elm_Object_Item *it)
5718 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5719 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5721 if (_it->item->block)
5722 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5727 elm_genlist_mode_set(Evas_Object *obj,
5730 ELM_CHECK_WIDTYPE(obj, widtype);
5731 Widget_Data *wd = elm_widget_data_get(obj);
5733 if (wd->mode == mode) return;
5735 if (wd->mode == ELM_LIST_COMPRESS)
5736 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5742 elm_genlist_mode_get(const Evas_Object *obj)
5744 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5745 Widget_Data *wd = elm_widget_data_get(obj);
5746 if (!wd) return ELM_LIST_LAST;
5751 elm_genlist_bounce_set(Evas_Object *obj,
5755 ELM_CHECK_WIDTYPE(obj, widtype);
5756 Widget_Data *wd = elm_widget_data_get(obj);
5758 wd->h_bounce = !!h_bounce;
5759 wd->v_bounce = !!v_bounce;
5760 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5764 elm_genlist_bounce_get(const Evas_Object *obj,
5765 Eina_Bool *h_bounce,
5766 Eina_Bool *v_bounce)
5768 ELM_CHECK_WIDTYPE(obj, widtype);
5769 Widget_Data *wd = elm_widget_data_get(obj);
5771 if (h_bounce) *h_bounce = wd->h_bounce;
5772 if (v_bounce) *v_bounce = wd->v_bounce;
5776 elm_genlist_homogeneous_set(Evas_Object *obj,
5777 Eina_Bool homogeneous)
5779 ELM_CHECK_WIDTYPE(obj, widtype);
5780 Widget_Data *wd = elm_widget_data_get(obj);
5782 wd->homogeneous = !!homogeneous;
5786 elm_genlist_homogeneous_get(const Evas_Object *obj)
5788 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5789 Widget_Data *wd = elm_widget_data_get(obj);
5790 if (!wd) return EINA_FALSE;
5791 return wd->homogeneous;
5795 elm_genlist_block_count_set(Evas_Object *obj,
5798 ELM_CHECK_WIDTYPE(obj, widtype);
5799 Widget_Data *wd = elm_widget_data_get(obj);
5801 wd->max_items_per_block = count;
5802 wd->item_cache_max = wd->max_items_per_block * 2;
5803 _item_cache_clean(wd);
5807 elm_genlist_block_count_get(const Evas_Object *obj)
5809 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5810 Widget_Data *wd = elm_widget_data_get(obj);
5812 return wd->max_items_per_block;
5816 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5819 ELM_CHECK_WIDTYPE(obj, widtype);
5820 Widget_Data *wd = elm_widget_data_get(obj);
5822 wd->longpress_timeout = timeout;
5826 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5828 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5829 Widget_Data *wd = elm_widget_data_get(obj);
5831 return wd->longpress_timeout;
5835 elm_genlist_scroller_policy_set(Evas_Object *obj,
5836 Elm_Scroller_Policy policy_h,
5837 Elm_Scroller_Policy policy_v)
5839 ELM_CHECK_WIDTYPE(obj, widtype);
5840 Widget_Data *wd = elm_widget_data_get(obj);
5841 if ((!wd) || (!wd->scr)) return;
5842 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5843 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5845 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5849 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5850 Elm_Scroller_Policy *policy_h,
5851 Elm_Scroller_Policy *policy_v)
5853 ELM_CHECK_WIDTYPE(obj, widtype);
5854 Widget_Data *wd = elm_widget_data_get(obj);
5855 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5856 if ((!wd) || (!wd->scr)) return;
5857 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5858 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5859 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5863 elm_genlist_realized_items_update(Evas_Object *obj)
5865 ELM_CHECK_WIDTYPE(obj, widtype);
5867 Eina_List *list, *l;
5868 Elm_Object_Item *it;
5870 list = elm_genlist_realized_items_get(obj);
5871 EINA_LIST_FOREACH(list, l, it)
5872 elm_genlist_item_update(it);
5876 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5877 const char *decorate_it_type,
5878 Eina_Bool decorate_it_set)
5880 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5881 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5883 Widget_Data *wd = _it->wd;
5885 Elm_Object_Item *it2;
5888 if (!decorate_it_type) return;
5889 if ((_it->generation < _it->wd->generation) ||
5890 elm_widget_item_disabled_get(_it)) return;
5891 if (wd->decorate_all_mode) return;
5893 if ((wd->mode_item == _it) &&
5894 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5897 if (!_it->itc->decorate_item_style) return;
5898 _it->decorate_it_set = decorate_it_set;
5902 EINA_LIST_FOREACH(wd->selected, l, it2)
5903 if (((Elm_Gen_Item *)it2)->realized)
5904 elm_genlist_item_selected_set(it2, EINA_FALSE);
5908 it2 = elm_genlist_selected_item_get(wd->obj);
5909 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5910 elm_genlist_item_selected_set(it2, EINA_FALSE);
5913 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5914 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5915 _decorate_item_unset(wd);
5917 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5918 if (decorate_it_set) _decorate_item_set(_it);
5922 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5924 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5925 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5926 return _it->wd->decorate_it_type;
5929 EAPI const Elm_Object_Item *
5930 elm_genlist_decorated_item_get(const Evas_Object *obj)
5932 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5933 Widget_Data *wd = elm_widget_data_get(obj);
5934 if (!wd) return NULL;
5935 return (Elm_Object_Item *) wd->mode_item;
5939 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5941 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5942 Widget_Data *wd = elm_widget_data_get(obj);
5943 if (!wd) return EINA_FALSE;
5945 return wd->decorate_all_mode;
5949 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5951 ELM_CHECK_WIDTYPE(obj, widtype);
5952 Eina_List *list, *l;
5955 Widget_Data *wd = elm_widget_data_get(obj);
5957 decorated = !!decorated;
5958 if (wd->decorate_all_mode == decorated) return;
5959 wd->decorate_all_mode = decorated;
5961 list = elm_genlist_realized_items_get(obj);
5962 if (!wd->decorate_all_mode)
5964 EINA_LIST_FOREACH(list, l, it)
5966 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5967 _decorate_all_item_unrealize(it);
5969 _item_cache_zero(wd);
5973 EINA_LIST_FOREACH(list, l, it)
5975 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5977 if (it->itc->decorate_all_item_style)
5978 _decorate_all_item_realize(it, EINA_TRUE);
5982 if (wd->calc_job) ecore_job_del(wd->calc_job);
5983 wd->calc_job = ecore_job_add(_calc_job, wd);
5987 elm_genlist_reorder_mode_set(Evas_Object *obj,
5988 Eina_Bool reorder_mode)
5990 ELM_CHECK_WIDTYPE(obj, widtype);
5991 Widget_Data *wd = elm_widget_data_get(obj);
5993 wd->reorder_mode = !!reorder_mode;
5997 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5999 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6000 Widget_Data *wd = elm_widget_data_get(obj);
6001 if (!wd) return EINA_FALSE;
6002 return wd->reorder_mode;
6005 EAPI Elm_Genlist_Item_Type
6006 elm_genlist_item_type_get(const Elm_Object_Item *it)
6008 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
6009 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6010 return _it->item->type;
6013 EAPI Elm_Genlist_Item_Class *
6014 elm_genlist_item_class_new(void)
6016 Elm_Genlist_Item_Class *itc;
6018 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
6021 itc->version = CLASS_ALLOCATED;
6023 itc->delete_me = EINA_FALSE;
6029 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6031 if (itc && (itc->version == CLASS_ALLOCATED))
6033 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6034 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6044 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6046 if (itc && (itc->version == CLASS_ALLOCATED))
6049 if (itc->refcount == 0) itc->refcount--;
6054 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6056 if (itc && (itc->version == CLASS_ALLOCATED))
6058 if (itc->refcount > 0) itc->refcount--;
6059 if (itc->delete_me && (!itc->refcount))
6060 elm_genlist_item_class_free(itc);
6064 void _flip_job(void *data)
6066 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
6067 _item_unhighlight(it);
6069 _elm_genlist_item_unrealize(it, EINA_FALSE);
6070 it->flipped = EINA_TRUE;
6071 it->item->nocache = EINA_TRUE;
6072 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6073 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
6077 elm_genlist_item_flip_set(Elm_Object_Item *it,
6080 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6081 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6084 if (_it->flipped == flip) return;
6088 ecore_job_add(_flip_job, _it);
6092 _it->flipped = flip;
6093 _item_cache_zero(_it->wd);
6094 elm_genlist_item_update(it);
6095 _it->item->nocache = EINA_FALSE;
6100 elm_genlist_item_flip_get(const Elm_Object_Item *it)
6102 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6103 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6104 return _it->flipped;
6108 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
6110 ELM_CHECK_WIDTYPE(obj, widtype);
6111 Widget_Data *wd = elm_widget_data_get(obj);
6113 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6115 if (wd->select_mode != mode)
6116 wd->select_mode = mode;
6119 EAPI Elm_Object_Select_Mode
6120 elm_genlist_select_mode_get(const Evas_Object *obj)
6122 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
6123 Widget_Data *wd = elm_widget_data_get(obj);
6124 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
6125 return wd->select_mode;
6129 elm_genlist_highlight_mode_set(Evas_Object *obj,
6130 Eina_Bool highlight)
6132 ELM_CHECK_WIDTYPE(obj, widtype);
6133 Widget_Data *wd = elm_widget_data_get(obj);
6135 wd->highlight = !!highlight;
6139 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6141 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6142 Widget_Data *wd = elm_widget_data_get(obj);
6143 if (!wd) return EINA_FALSE;
6144 return wd->highlight;
6148 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
6149 Elm_Object_Select_Mode mode)
6151 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6152 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6154 if (_it->generation < _it->wd->generation) return;
6155 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6157 if (_it->select_mode != mode)
6158 _it->select_mode = mode;
6160 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6162 _it->item->mincalcd = EINA_FALSE;
6163 _it->item->updateme = EINA_TRUE;
6164 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
6165 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
6166 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
6170 EAPI Elm_Object_Select_Mode
6171 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
6173 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
6174 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6175 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
6176 return _it->select_mode;
6179 /* for gengrid as of now */
6181 _elm_genlist_page_relative_set(Evas_Object *obj,
6185 Evas_Coord pagesize_h;
6186 Evas_Coord pagesize_v;
6188 ELM_CHECK_WIDTYPE(obj, widtype);
6189 Widget_Data *wd = elm_widget_data_get(obj);
6192 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
6193 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
6197 /* for gengrid as of now */
6199 _elm_genlist_page_relative_get(const Evas_Object *obj,
6203 ELM_CHECK_WIDTYPE(obj, widtype);
6204 Widget_Data *wd = elm_widget_data_get(obj);
6207 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
6210 /* for gengrid as of now */
6212 _elm_genlist_page_size_set(Evas_Object *obj,
6213 Evas_Coord h_pagesize,
6214 Evas_Coord v_pagesize)
6219 ELM_CHECK_WIDTYPE(obj, widtype);
6220 Widget_Data *wd = elm_widget_data_get(obj);
6222 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
6223 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
6227 /* for gengrid as of now */
6229 _elm_genlist_current_page_get(const Evas_Object *obj,
6233 ELM_CHECK_WIDTYPE(obj, widtype);
6234 Widget_Data *wd = elm_widget_data_get(obj);
6236 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
6239 /* for gengrid as of now */
6241 _elm_genlist_last_page_get(const Evas_Object *obj,
6245 ELM_CHECK_WIDTYPE(obj, widtype);
6246 Widget_Data *wd = elm_widget_data_get(obj);
6248 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
6251 /* for gengrid as of now */
6253 _elm_genlist_page_show(const Evas_Object *obj,
6257 ELM_CHECK_WIDTYPE(obj, widtype);
6258 Widget_Data *wd = elm_widget_data_get(obj);
6260 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
6263 /* for gengrid as of now */
6265 _elm_genlist_page_bring_in(const Evas_Object *obj,
6269 ELM_CHECK_WIDTYPE(obj, widtype);
6270 Widget_Data *wd = elm_widget_data_get(obj);
6272 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
6276 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
6279 Evas_Object *content;
6281 if (!it->realized) return;
6282 if (it->wd->reorder_it == it) return;
6283 if (it->defer_unrealize && !it->item->updateme) return;
6285 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
6287 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
6290 ecore_timer_del(it->long_timer);
6291 it->long_timer = NULL;
6294 elm_widget_stringlist_free(it->texts);
6296 elm_widget_stringlist_free(it->contents);
6297 it->contents = NULL;
6298 elm_widget_stringlist_free(it->states);
6300 EINA_LIST_FREE(it->content_objs, content)
6301 evas_object_del(content);
6303 it->unrealize_cb(it);
6305 it->realized = EINA_FALSE;
6306 it->want_unrealize = EINA_FALSE;
6307 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
6308 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
6312 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
6314 elm_widget_item_pre_notify_del(it);
6315 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
6317 if ((it->relcount > 0) || (it->walking > 0)) return;
6319 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6321 if (it->itc->func.del)
6322 it->itc->func.del((void *)it->base.data, WIDGET(it));
6326 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
6328 _elm_genlist_item_del_notserious(it);
6329 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6330 if (it->tooltip.del_cb)
6331 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6332 it->wd->walking -= it->walking;
6335 ecore_timer_del(it->long_timer);
6336 it->long_timer = NULL;
6339 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
6343 eina_inlist_sorted_state_free(it->wd->state);
6344 it->wd->state = NULL;
6346 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6347 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
6351 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
6352 it->wd->last_selected_item = NULL;
6353 it->wd->item_count--;
6357 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
6359 ELM_CHECK_WIDTYPE(obj, widtype);
6360 Widget_Data *wd = elm_widget_data_get(obj);
6362 wd->tree_effect_enabled = !!enabled;
6366 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
6368 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6369 Widget_Data *wd = elm_widget_data_get(obj);
6370 if (!wd) return EINA_FALSE;
6371 return wd->tree_effect_enabled;
6375 _create_tray_alpha_bg(const Evas_Object *obj)
6377 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6378 Widget_Data *wd = elm_widget_data_get(obj);
6379 if (!wd) return NULL;
6381 Evas_Object *bg = NULL;
6382 Evas_Coord ox, oy, ow, oh;
6384 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6385 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6386 evas_object_color_set(bg,0,0,0,0);
6387 evas_object_resize(bg , ow, oh);
6388 evas_object_move(bg , ox, oy);
6393 _item_contract_emit(Elm_Gen_Item *it)
6398 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6399 it->item->tree_effect_finished = EINA_FALSE;
6401 EINA_LIST_FOREACH(it->item->items, l, it2)
6402 if (it2) _item_contract_emit(it2);
6406 _item_tree_effect_before(Elm_Gen_Item *it)
6411 EINA_LIST_FOREACH(it->item->items, l, it2)
6413 if (it2->parent && (it == it2->parent))
6416 it2->item->tree_effect_hideme = EINA_TRUE;
6417 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6418 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6419 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6420 _item_contract_emit(it2);
6423 return ECORE_CALLBACK_CANCEL;
6427 _item_tree_effect(Widget_Data *wd, int y)
6429 Elm_Gen_Item *it = NULL, *expanded_next_it;
6431 expanded_next_it = wd->expanded_next_item;
6433 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6435 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6438 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6439 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6440 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6442 if (!it->item->tree_effect_finished)
6444 edje_object_signal_emit(VIEW(it), "flip_item", "");
6445 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6446 it->item->tree_effect_finished = EINA_TRUE;
6449 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6452 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6454 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6457 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6458 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6460 if (!it->item->tree_effect_finished)
6462 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6463 it->item->tree_effect_finished = EINA_TRUE;
6468 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6474 _item_tree_effect_finish(Widget_Data *wd)
6476 Elm_Gen_Item *it = NULL;
6479 if (wd->tree_effect_animator)
6481 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6482 _item_subitems_clear(wd->expanded_item);
6483 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6485 it->item->tree_effect_finished = EINA_TRUE;
6486 it->item->old_scrl_y = it->item->scrl_y;
6487 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6488 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6491 _item_auto_scroll(wd);
6492 evas_object_lower(wd->alpha_bg);
6493 evas_object_hide(wd->alpha_bg);
6494 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6495 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6497 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6498 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6499 evas_object_smart_changed(wd->pan_smart);
6501 wd->tree_effect_animator = NULL;
6505 _tree_effect_animator_cb(void *data)
6507 Widget_Data *wd = data;
6508 if (!wd) return ECORE_CALLBACK_CANCEL;
6509 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6510 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6512 double effect_duration = 0.3, t;
6513 int y = 0, dy = 0, dh = 0;
6514 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6517 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6518 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6519 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6520 if (t > effect_duration) end = EINA_TRUE;
6522 // Below while statement is needed, when the genlist is resized.
6523 it2 = wd->expanded_item;
6526 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6527 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6528 cvx, cvy, cvw, cvh));
6529 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6532 if (wd->expanded_next_item)
6534 expanded_next_it = wd->expanded_next_item;
6537 EINA_LIST_FOREACH(wd->move_items, l, it)
6539 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6541 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6542 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6543 expanded_next_it->item->scrl_y = cvy + cvh;
6545 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6546 cvy + cvh : expanded_next_it->item->scrl_y) -
6547 expanded_next_it->item->old_scrl_y;
6549 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6551 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6552 expanded_next_it->item->old_scrl_y = cvy + cvh;
6554 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6556 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6558 expanded_next_it->item->old_scrl_y = cvy + cvh;
6562 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6563 expanded_next_it->item->old_scrl_y;
6567 if (t <= effect_duration)
6569 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6579 _item_realize(it, in, 0);
6583 if (it != expanded_next_it)
6585 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6589 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6590 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6593 _item_tree_effect(wd, y);
6597 int expanded_item_num = 0;
6600 if (wd->expanded_item)
6601 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6606 expanded_item_num++;
6607 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6613 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6614 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6616 if (!it->item->tree_effect_finished)
6618 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6620 edje_object_signal_emit(VIEW(it), "flip_item", "");
6621 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6622 it->item->tree_effect_finished = EINA_TRUE;
6626 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6632 _item_tree_effect_finish(wd);
6633 return ECORE_CALLBACK_CANCEL;
6635 return ECORE_CALLBACK_RENEW;