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)
686 minw = vmw + wd->realminw;
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 if ((itb->wd->homogeneous) &&
2482 (itb->wd->mode == ELM_LIST_COMPRESS))
2486 it->item->w = it->item->minw = it->wd->group_item_width;
2487 it->item->h = it->item->minh = it->wd->group_item_height;
2491 it->item->w = it->item->minw = it->wd->item_width;
2492 it->item->h = it->item->minh = it->wd->item_height;
2497 _item_realize(it, in, EINA_TRUE);
2498 _elm_genlist_item_unrealize(it, EINA_TRUE);
2504 if (!it->item->mincalcd) changed = EINA_TRUE;
2505 _item_realize(it, in, EINA_FALSE);
2507 minh += it->item->minh;
2508 if (minw < it->item->minw) minw = it->item->minw;
2514 if (changed) itb->wd->pan_changed = changed;
2517 itb->changed = EINA_FALSE;
2518 itb->position_update = EINA_FALSE;
2519 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2520 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2525 _item_block_realize(Item_Block *itb)
2527 if (itb->realized) return;
2528 itb->realized = EINA_TRUE;
2529 itb->want_unrealize = EINA_FALSE;
2533 _item_block_unrealize(Item_Block *itb)
2537 Eina_Bool dragging = EINA_FALSE;
2539 if (!itb->realized) return;
2540 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2541 EINA_LIST_FOREACH(itb->items, l, it)
2543 if (itb->must_recalc || !it->group)
2547 dragging = EINA_TRUE;
2548 it->want_unrealize = EINA_TRUE;
2551 _elm_genlist_item_unrealize(it, EINA_FALSE);
2556 itb->realized = EINA_FALSE;
2557 itb->want_unrealize = EINA_TRUE;
2560 itb->want_unrealize = EINA_FALSE;
2561 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2562 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2566 _get_space_for_reorder_item(Elm_Gen_Item *it)
2568 Evas_Coord rox, roy, row, roh, oy, oh;
2569 Eina_Bool top = EINA_FALSE;
2570 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2571 if (!reorder_it) return 0;
2573 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2574 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2576 if ((it->wd->reorder_start_y < it->item->block->y) &&
2577 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2579 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2580 if (it->item->block->count == 1)
2581 it->wd->reorder_rel = it;
2583 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2584 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2586 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2589 it->item->block->reorder_offset = 0;
2591 it->item->scrl_y += it->item->block->reorder_offset;
2593 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2594 rox, roy + (roh / 2), row, 1));
2597 it->wd->reorder_rel = it;
2598 it->item->scrl_y += it->wd->reorder_it->item->h;
2599 return it->wd->reorder_it->item->h;
2606 _reorder_move_animator_cb(void *data)
2608 Elm_Gen_Item *it = data;
2609 Eina_Bool down = EINA_FALSE;
2611 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2613 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2615 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2618 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2619 if (diff > it->item->h) y = diff / 2;
2621 if (it->item->old_scrl_y < it->item->scrl_y)
2623 it->item->old_scrl_y += y;
2626 else if (it->item->old_scrl_y > it->item->scrl_y)
2628 it->item->old_scrl_y -= y;
2632 if (it->deco_all_view)
2633 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2635 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2636 //FIXME : group raise
2638 _group_items_recalc(it->wd);
2641 if ((it->wd->reorder_pan_move) ||
2642 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2643 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2645 it->item->old_scrl_y = it->item->scrl_y;
2646 it->item->move_effect_enabled = EINA_FALSE;
2647 it->wd->reorder_move_animator = NULL;
2648 return ECORE_CALLBACK_CANCEL;
2650 return ECORE_CALLBACK_RENEW;
2654 _item_position(Elm_Gen_Item *it,
2662 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2663 evas_object_resize(view, it->item->w, it->item->h);
2664 evas_object_move(view, it_x, it_y);
2665 evas_object_show(view);
2666 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2667 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2671 _item_block_position(Item_Block *itb,
2676 //FIXME : group raise
2680 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2681 Eina_Bool vis = EINA_FALSE;
2682 Evas_Coord minh = 0;
2684 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2685 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2686 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2688 EINA_LIST_FOREACH(itb->items, l, it)
2690 if (it->generation < it->wd->generation) continue;
2691 else if (it->wd->reorder_it == it) continue;
2694 it->item->w = itb->w;
2695 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2696 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2698 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2699 cvx, cvy, cvw, cvh));
2700 //FIXME : group raise
2705 if ((itb->realized) && (!it->realized))
2707 if (vis) _item_realize(it, in, EINA_FALSE);
2711 if (vis || it->dragging)
2713 if (it->wd->reorder_mode)
2714 y += _get_space_for_reorder_item(it);
2715 //FIXME : group raise
2717 git = it->item->group_item;
2720 if (git->item->scrl_y < oy)
2721 git->item->scrl_y = oy;
2722 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2723 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2724 git->item->want_realize = EINA_TRUE;
2727 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2729 if (!it->item->move_effect_enabled)
2731 it->item->move_effect_enabled = EINA_TRUE;
2732 it->wd->reorder_move_animator =
2734 _reorder_move_animator_cb, it);
2737 if (!it->item->move_effect_enabled)
2739 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2740 _decorate_all_item_position(it, it->item->scrl_x,
2744 if (!it->wd->tree_effect_enabled ||
2745 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2746 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2747 (it->item->old_scrl_y == it->item->scrl_y)))
2749 if (it->item->deco_it_view)
2750 _item_position(it, it->item->deco_it_view,
2754 _item_position(it, VIEW(it), it->item->scrl_x,
2758 it->item->old_scrl_y = it->item->scrl_y;
2763 if (!it->wd->tree_effect_animator)
2765 it->want_unrealize = EINA_TRUE;
2766 _elm_genlist_item_unrealize(it, EINA_FALSE);
2772 //FIXME : group raise
2776 if (vis) it->item->want_realize = EINA_TRUE;
2780 minh += it->item->minh;
2782 if (!itb->wd->reorder_it) itb->minh = minh;
2783 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2784 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2787 //FIXME: group raise
2790 _group_items_recalc(void *data)
2792 Widget_Data *wd = data;
2796 evas_event_freeze(evas_object_evas_get(wd->obj));
2797 EINA_LIST_FOREACH(wd->group_items, l, git)
2799 if (git->item->want_realize)
2802 _item_realize(git, 0, EINA_FALSE);
2803 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2804 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2805 evas_object_show(VIEW(git));
2806 evas_object_raise(VIEW(git));
2808 else if (!git->item->want_realize && git->realized)
2811 _elm_genlist_item_unrealize(git, EINA_FALSE);
2814 evas_event_thaw(evas_object_evas_get(wd->obj));
2815 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2820 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2822 Elm_Gen_Item *it = data;
2824 if (it->want_unrealize) return;
2825 it->item->mincalcd = EINA_FALSE;
2826 it->item->block->changeme = EINA_TRUE;
2827 if (it->wd->changed_job) ecore_job_del(it->wd->changed_job);
2828 it->wd->changed_job = ecore_job_add(_changed_job, it->wd);
2832 _must_recalc_idler(void *data)
2834 Widget_Data *wd = data;
2835 if (wd->calc_job) ecore_job_del(wd->calc_job);
2836 wd->calc_job = ecore_job_add(_calc_job, wd);
2837 wd->must_recalc_idler = NULL;
2838 return ECORE_CALLBACK_CANCEL;
2842 _scroll_item(Widget_Data *wd)
2844 Elm_Gen_Item *it = NULL;
2845 //FIXME: group raise
2847 Evas_Coord gith = 0;
2849 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2850 if (!wd->show_item) return;
2852 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2854 dx = it->x + it->item->block->x;
2855 dy = it->y + it->item->block->y;
2856 dw = it->item->block->w;
2858 switch (wd->scrollto_type)
2860 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2861 //FIXME: group raise
2863 if (it->item->group_item) gith = it->item->group_item->item->h;
2867 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2868 dy += ((it->item->h / 2) - (oh / 2));
2870 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2872 if ((wd->expanded_item) &&
2873 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2874 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2876 it = wd->expanded_item;
2877 dx = it->x + it->item->block->x;
2878 dy = it->y + it->item->block->y;
2879 //FIXME: group raise
2881 if (it->item->group_item) gith = it->item->group_item->item->h;
2882 dx = it->x + it->item->block->x;
2883 dy = it->y + it->item->block->y - gith;
2885 dw = it->item->block->w;
2889 //FIXME: group raise
2891 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2892 gith = it->item->group_item->item->h;
2900 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2902 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2904 it->item->showme = EINA_FALSE;
2905 wd->show_item = NULL;
2906 wd->auto_scroll_enabled = EINA_FALSE;
2907 wd->check_scroll = EINA_FALSE;
2911 _calc_job(void *data)
2913 Widget_Data *wd = data;
2914 Item_Block *itb, *chb = NULL;
2915 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2916 Evas_Coord pan_w = 0, pan_h = 0;
2918 Eina_Bool minw_change = EINA_FALSE;
2919 Eina_Bool did_must_recalc = EINA_FALSE;
2922 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2923 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2928 evas_event_freeze(evas_object_evas_get(wd->obj));
2929 EINA_INLIST_FOREACH(wd->blocks, itb)
2931 Eina_Bool showme = EINA_FALSE;
2934 showme = itb->showme;
2935 itb->showme = EINA_FALSE;
2938 if (itb->realized) _item_block_unrealize(itb);
2940 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2942 if (itb->must_recalc)
2946 EINA_LIST_FOREACH(itb->items, l, it)
2947 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2948 itb->changed = EINA_TRUE;
2949 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2950 if (itb->realized) _item_block_unrealize(itb);
2951 itb->must_recalc = EINA_FALSE;
2953 showme = _item_block_recalc(itb, in, EINA_FALSE);
2959 if (minw == -1) minw = itb->minw;
2960 else if ((!itb->must_recalc) && (minw < itb->minw))
2963 minw_change = EINA_TRUE;
2968 minw_change = EINA_TRUE;
2974 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2975 wd->check_scroll = EINA_TRUE;
2979 EINA_INLIST_FOREACH(wd->blocks, itb)
2985 if ((chb) && (EINA_INLIST_GET(chb)->next))
2987 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2989 if (itb->realized) _item_block_unrealize(itb);
2992 wd->realminw = minw;
2993 if (minw < wd->w) minw = wd->w;
2994 if ((minw != wd->minw) || (minh != wd->minh))
2998 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2999 _sizing_eval(wd->obj);
3000 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
3005 it = wd->anchor_item;
3006 it_y = wd->anchor_y;
3007 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
3008 it->item->block->y + it->y + it_y);
3009 wd->anchor_item = it;
3010 wd->anchor_y = it_y;
3013 if (did_must_recalc)
3015 if (!wd->must_recalc_idler)
3016 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
3018 if (wd->check_scroll)
3020 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
3021 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
3022 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3023 switch (wd->scrollto_type)
3025 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
3028 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
3031 case ELM_GENLIST_ITEM_SCROLLTO_IN:
3036 if ((wd->show_item) && (wd->show_item->item->block))
3038 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
3039 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
3045 wd->calc_job = NULL;
3046 evas_object_smart_changed(wd->pan_smart);
3047 evas_event_thaw(evas_object_evas_get(wd->obj));
3048 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3052 _update_job(void *data)
3054 Widget_Data *wd = data;
3058 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
3060 wd->update_job = NULL;
3063 evas_event_freeze(evas_object_evas_get(wd->obj));
3064 EINA_INLIST_FOREACH(wd->blocks, itb)
3066 Evas_Coord itminw, itminh;
3073 _item_block_position(itb, num);
3077 recalc = EINA_FALSE;
3078 EINA_LIST_FOREACH(itb->items, l2, it)
3080 if (it->item->updateme)
3082 itminw = it->item->minw;
3083 itminh = it->item->minh;
3087 _elm_genlist_item_unrealize(it, EINA_FALSE);
3088 _item_realize(it, num, EINA_FALSE);
3089 position = EINA_TRUE;
3093 _item_realize(it, num, EINA_TRUE);
3094 _elm_genlist_item_unrealize(it, EINA_TRUE);
3096 if ((it->item->minw != itminw) || (it->item->minh != itminh))
3098 it->item->updateme = EINA_FALSE;
3102 itb->updateme = EINA_FALSE;
3105 position = EINA_TRUE;
3106 itb->changed = EINA_TRUE;
3107 _item_block_recalc(itb, num0, EINA_FALSE);
3108 _item_block_position(itb, num0);
3113 if (wd->calc_job) ecore_job_del(wd->calc_job);
3114 wd->calc_job = ecore_job_add(_calc_job, wd);
3116 evas_event_thaw(evas_object_evas_get(wd->obj));
3117 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3121 _changed_job(void *data)
3123 Widget_Data *wd = data; Eina_List *l2;
3125 int num, num0, position = 0;
3126 Eina_Bool width_changed = EINA_FALSE, height_changed = EINA_FALSE;
3128 wd->changed_job = NULL;
3130 EINA_INLIST_FOREACH(wd->blocks, itb)
3132 Evas_Coord itminw, itminh;
3139 _item_block_position(itb, num);
3143 width_changed = height_changed = EINA_FALSE;
3144 EINA_LIST_FOREACH(itb->items, l2, it)
3146 if ((!it->item->mincalcd) && (it->realized))
3148 Evas_Coord mw = -1, mh = -1;
3149 itminw = it->item->minw;
3150 itminh = it->item->minh;
3152 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->w;
3153 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3154 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3155 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
3156 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
3157 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3158 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3160 width_changed = EINA_TRUE;
3163 it->item->w = it->item->minw = mw;
3164 it->item->h = it->item->minh = mh;
3165 it->item->mincalcd = EINA_TRUE;
3167 //if ((it->item->minw != itminw) || (it->item->minh != itminh))
3168 //if ((it->item->minh != itminh))
3170 if ((it->item->minw != itminw))
3171 width_changed = EINA_TRUE;
3172 if ((it->item->minh != itminh))
3173 height_changed = EINA_TRUE;
3175 if ((!it->wd->group_item_width) && (it->group))
3177 it->wd->group_item_width = mw;
3178 it->wd->group_item_height = mh;
3180 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
3182 it->wd->item_width = mw;
3183 it->wd->item_height = mh;
3188 itb->changeme = EINA_FALSE;
3189 // TODO: why this is separated.
3193 itb->changed = EINA_TRUE;
3194 _item_block_recalc(itb, num0, 0);
3195 _item_block_position(itb, num0);
3197 else if (width_changed)
3199 _item_block_position(itb, num0);
3204 if (wd->calc_job) ecore_job_del(wd->calc_job);
3205 wd->calc_job = ecore_job_add(_calc_job, wd);
3210 _pan_set(Evas_Object *obj,
3214 Pan *sd = evas_object_smart_data_get(obj);
3218 // Evas_Coord ow, oh;
3219 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3220 // ow = sd->wd->minw - ow;
3221 // if (ow < 0) ow = 0;
3222 // oh = sd->wd->minh - oh;
3223 // if (oh < 0) oh = 0;
3224 // if (x < 0) x = 0;
3225 // if (y < 0) y = 0;
3226 // if (x > ow) x = ow;
3227 // if (y > oh) y = oh;
3228 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
3232 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3234 if ((itb->y + itb->h) > y)
3239 EINA_LIST_FOREACH(itb->items, l2, it)
3241 if ((itb->y + it->y) >= y)
3243 sd->wd->anchor_item = it;
3244 sd->wd->anchor_y = -(itb->y + it->y - y);
3251 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
3255 _pan_get(Evas_Object *obj,
3259 Pan *sd = evas_object_smart_data_get(obj);
3262 if (x) *x = sd->wd->pan_x;
3263 if (y) *y = sd->wd->pan_y;
3267 _pan_max_get(Evas_Object *obj,
3271 Pan *sd = evas_object_smart_data_get(obj);
3275 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3276 ow = sd->wd->minw - ow;
3278 oh = sd->wd->minh - oh;
3285 _pan_min_get(Evas_Object *obj __UNUSED__,
3294 _pan_child_size_get(Evas_Object *obj,
3298 Pan *sd = evas_object_smart_data_get(obj);
3301 if (w) *w = sd->wd->minw;
3302 if (h) *h = sd->wd->minh;
3306 _pan_add(Evas_Object *obj)
3309 Evas_Object_Smart_Clipped_Data *cd;
3312 cd = evas_object_smart_data_get(obj);
3315 sd->__clipped_data = *cd;
3317 evas_object_smart_data_set(obj, sd);
3321 _pan_del(Evas_Object *obj)
3323 Pan *sd = evas_object_smart_data_get(obj);
3328 ecore_job_del(sd->resize_job);
3329 sd->resize_job = NULL;
3335 _pan_resize_job(void *data)
3339 _sizing_eval(sd->wd->obj);
3340 sd->resize_job = NULL;
3344 _pan_resize(Evas_Object *obj,
3348 Pan *sd = evas_object_smart_data_get(obj);
3352 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3353 if ((ow == w) && (oh == h)) return;
3354 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3357 if (sd->resize_job) ecore_job_del(sd->resize_job);
3358 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3360 sd->wd->pan_changed = EINA_TRUE;
3361 evas_object_smart_changed(obj);
3362 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3363 sd->wd->calc_job = NULL;
3367 _pan_calculate(Evas_Object *obj)
3369 Pan *sd = evas_object_smart_data_get(obj);
3371 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3373 //FIXME: group raise
3380 evas_event_freeze(evas_object_evas_get(obj));
3382 if (sd->wd->pan_changed)
3385 sd->wd->pan_changed = EINA_FALSE;
3388 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3389 sd->wd->prev_viewport_w = ow;
3390 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3391 //FIXME: group raise
3393 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3395 git->item->want_realize = EINA_FALSE;
3399 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3401 if (!sd->wd->tree_effect_animator)
3403 _item_tree_effect_before(sd->wd->expanded_item);
3404 evas_object_raise(sd->wd->alpha_bg);
3405 evas_object_show(sd->wd->alpha_bg);
3406 sd->wd->start_time = ecore_time_get();
3407 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3411 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3413 itb->w = sd->wd->minw;
3414 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3415 itb->y - sd->wd->pan_y + oy,
3417 cvx, cvy, cvw, cvh))
3419 if ((!itb->realized) || (itb->changed))
3421 _item_block_realize(itb);
3423 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3424 sd->wd->calc_job = NULL;
3427 _item_block_position(itb, in);
3431 if (itb->realized) _item_block_unrealize(itb);
3435 //FIXME: group raise
3437 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3438 _group_items_recalc(sd->wd);
3440 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3442 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3443 sd->wd->reorder_pan_move = EINA_TRUE;
3444 else sd->wd->reorder_pan_move = EINA_FALSE;
3445 evas_object_raise(sd->wd->VIEW(reorder_it));
3446 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3447 sd->wd->start_time = ecore_loop_time_get();
3450 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3451 _item_auto_scroll(sd->wd);
3453 evas_event_thaw(evas_object_evas_get(obj));
3454 evas_event_thaw_eval(evas_object_evas_get(obj));
3458 _pan_move(Evas_Object *obj,
3459 Evas_Coord x __UNUSED__,
3460 Evas_Coord y __UNUSED__)
3462 Pan *sd = evas_object_smart_data_get(obj);
3466 sd->wd->pan_changed = EINA_TRUE;
3467 evas_object_smart_changed(obj);
3468 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3469 sd->wd->calc_job = NULL;
3473 _hold_on(void *data __UNUSED__,
3475 void *event_info __UNUSED__)
3477 Widget_Data *wd = elm_widget_data_get(obj);
3479 elm_smart_scroller_hold_set(wd->scr, 1);
3483 _hold_off(void *data __UNUSED__,
3485 void *event_info __UNUSED__)
3487 Widget_Data *wd = elm_widget_data_get(obj);
3489 elm_smart_scroller_hold_set(wd->scr, 0);
3493 _freeze_on(void *data __UNUSED__,
3495 void *event_info __UNUSED__)
3497 Widget_Data *wd = elm_widget_data_get(obj);
3499 elm_smart_scroller_freeze_set(wd->scr, 1);
3503 _freeze_off(void *data __UNUSED__,
3505 void *event_info __UNUSED__)
3507 Widget_Data *wd = elm_widget_data_get(obj);
3509 elm_smart_scroller_freeze_set(wd->scr, 0);
3513 _scr_anim_start(void *data,
3514 Evas_Object *obj __UNUSED__,
3515 void *event_info __UNUSED__)
3517 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3521 _scr_anim_stop(void *data,
3522 Evas_Object *obj __UNUSED__,
3523 void *event_info __UNUSED__)
3525 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3529 _scr_drag_start(void *data,
3530 Evas_Object *obj __UNUSED__,
3531 void *event_info __UNUSED__)
3533 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3537 _scr_drag_stop(void *data,
3538 Evas_Object *obj __UNUSED__,
3539 void *event_info __UNUSED__)
3541 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3545 _edge_left(void *data,
3546 Evas_Object *scr __UNUSED__,
3547 void *event_info __UNUSED__)
3549 Evas_Object *obj = data;
3550 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3554 _edge_right(void *data,
3555 Evas_Object *scr __UNUSED__,
3556 void *event_info __UNUSED__)
3558 Evas_Object *obj = data;
3559 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3563 _edge_top(void *data,
3564 Evas_Object *scr __UNUSED__,
3565 void *event_info __UNUSED__)
3567 Evas_Object *obj = data;
3568 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3572 _edge_bottom(void *data,
3573 Evas_Object *scr __UNUSED__,
3574 void *event_info __UNUSED__)
3576 Evas_Object *obj = data;
3577 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3581 _decorate_item_realize(Elm_Gen_Item *it)
3585 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3587 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3588 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3589 edje_object_scale_set(it->item->deco_it_view,
3590 elm_widget_scale_get(WIDGET(it)) *
3591 _elm_config->scale);
3592 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3593 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3595 strncpy(buf, "item", sizeof(buf));
3596 if (it->wd->mode == ELM_LIST_COMPRESS)
3597 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3599 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3600 strncat(buf, "/", sizeof(buf) - strlen(buf));
3601 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3603 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3604 elm_widget_style_get(WIDGET(it)));
3605 edje_object_mirrored_set(it->item->deco_it_view,
3606 elm_widget_mirrored_get(WIDGET(it)));
3608 /* signal callback add */
3609 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3611 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3613 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3616 /* text_get, content_get, state_get */
3617 /* FIXME: If you see that assert, please notify us and we
3618 will clean our mess */
3619 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3621 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3622 if (!it->item->deco_it_contents)
3623 it->item->deco_it_contents =
3624 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3625 it->item->deco_it_content_objs =
3626 _item_mode_content_realize(it, it->item->deco_it_view,
3627 &it->item->deco_it_contents, NULL,
3628 &it->item->deco_it_content_objs);
3629 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3630 edje_object_part_swallow(it->item->deco_it_view,
3631 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3634 it->want_unrealize = EINA_FALSE;
3635 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3636 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3640 _decorate_item_unrealize(Elm_Gen_Item *it)
3642 Widget_Data *wd = it->wd;
3643 Evas_Object *content;
3644 if (!it->item->deco_it_view) return;
3646 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3647 elm_widget_stringlist_free(it->item->deco_it_texts);
3648 it->item->deco_it_texts = NULL;
3649 elm_widget_stringlist_free(it->item->deco_it_contents);
3650 it->item->deco_it_contents = NULL;
3651 elm_widget_stringlist_free(it->item->deco_it_states);
3653 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3654 evas_object_del(content);
3656 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3657 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3658 evas_object_del(it->item->deco_it_view);
3659 it->item->deco_it_view = NULL;
3661 if (wd->mode_item == it)
3662 wd->mode_item = NULL;
3663 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3664 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3668 _decorate_item_set(Elm_Gen_Item *it)
3671 Widget_Data *wd = it->wd;
3676 it->item->nocache_once = EINA_TRUE;
3678 if (wd->scr_hold_timer)
3680 ecore_timer_del(wd->scr_hold_timer);
3681 wd->scr_hold_timer = NULL;
3683 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3684 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3686 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3687 _decorate_item_realize(it);
3688 if (it->item->group_item)
3689 evas_object_raise(it->item->VIEW(group_item));
3690 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3691 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3692 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3694 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3695 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3699 _decorate_item_unset(Widget_Data *wd)
3702 if (!wd->mode_item) return;
3703 char buf[1024], buf2[1024];
3707 it->item->nocache_once = EINA_TRUE;
3709 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3710 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3712 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3713 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3715 wd->mode_item = NULL;
3719 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3721 if ((!it) || (!it->wd->decorate_all_mode)) return;
3722 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3723 evas_object_move(it->deco_all_view, itx, ity);
3727 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3730 const char *stacking_even;
3731 const char *stacking;
3733 if ((!it) || (it->item->decorate_all_item_realized) ||
3734 (it->generation < it->wd->generation))
3737 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3738 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3739 _elm_config->scale);
3740 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3741 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3743 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3744 strncpy(buf, "tree", sizeof(buf));
3745 else strncpy(buf, "item", sizeof(buf));
3746 if (it->wd->mode == ELM_LIST_COMPRESS)
3747 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3749 strncat(buf, "/", sizeof(buf) - strlen(buf));
3750 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3752 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3753 elm_widget_style_get(WIDGET(it)));
3755 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3756 if (!stacking_even) stacking_even = "above";
3757 it->item->stacking_even = !!strcmp("above", stacking_even);
3759 stacking = edje_object_data_get(VIEW(it), "stacking");
3760 if (!stacking) stacking = "yes";
3761 it->item->nostacking = !!strcmp("yes", stacking);
3763 edje_object_mirrored_set(it->deco_all_view,
3764 elm_widget_mirrored_get(WIDGET(it)));
3766 _elm_genlist_item_odd_even_update(it);
3767 _elm_genlist_item_state_update(it, NULL);
3769 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3770 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3772 _item_mouse_callbacks_del(it, VIEW(it));
3773 _item_mouse_callbacks_add(it, it->deco_all_view);
3775 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3776 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3777 if (!it->item->deco_all_contents)
3778 it->item->deco_all_contents =
3779 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "decorate_contents"));
3780 it->item->deco_all_content_objs =
3781 _item_mode_content_realize(it, it->deco_all_view,
3782 &it->item->deco_all_contents, NULL,
3783 &it->item->deco_all_content_objs);
3784 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3785 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3787 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3788 evas_object_show(it->deco_all_view);
3790 if (it->selected) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
3792 it->item->decorate_all_item_realized = EINA_TRUE;
3793 it->want_unrealize = EINA_FALSE;
3797 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3800 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3802 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3803 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3804 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3805 _elm_genlist_item_odd_even_update(it);
3806 _elm_genlist_item_state_update(it, NULL);
3808 evas_object_del(it->deco_all_view);
3809 it->deco_all_view = NULL;
3810 elm_widget_stringlist_free(it->item->deco_all_texts);
3811 it->item->deco_all_texts = NULL;
3812 elm_widget_stringlist_free(it->item->deco_all_contents);
3813 it->item->deco_all_contents = NULL;
3814 elm_widget_stringlist_free(it->item->deco_all_states);
3815 it->item->deco_all_states = NULL;
3816 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3817 evas_object_del(icon);
3818 edje_object_message_signal_process(it->deco_all_view);
3819 _item_mouse_callbacks_del(it, it->deco_all_view);
3820 _item_mouse_callbacks_add(it, VIEW(it));
3822 it->item->decorate_all_item_realized = EINA_FALSE;
3826 _item_auto_scroll(Widget_Data *wd)
3829 Elm_Gen_Item *tmp_item = NULL;
3831 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3833 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3834 if (!tmp_item) return;
3835 wd->show_item = tmp_item;
3836 wd->bring_in = EINA_TRUE;
3837 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3838 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3840 wd->show_item->item->showme = EINA_TRUE;
3841 wd->auto_scroll_enabled = EINA_FALSE;
3849 elm_genlist_add(Evas_Object *parent)
3854 Evas_Coord minw, minh;
3855 static Evas_Smart *smart = NULL;
3859 static Evas_Smart_Class sc;
3861 evas_object_smart_clipped_smart_set(&_pan_sc);
3863 sc.name = "elm_genlist_pan";
3864 sc.version = EVAS_SMART_CLASS_VERSION;
3867 sc.resize = _pan_resize;
3868 sc.move = _pan_move;
3869 sc.calculate = _pan_calculate;
3870 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3873 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3875 ELM_SET_WIDTYPE(widtype, "genlist");
3877 elm_widget_type_set(obj, "genlist");
3878 elm_widget_sub_object_add(parent, obj);
3879 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3880 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3881 elm_widget_data_set(obj, wd);
3882 elm_widget_del_hook_set(obj, _del_hook);
3883 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3884 elm_widget_theme_hook_set(obj, _theme_hook);
3885 elm_widget_can_focus_set(obj, EINA_TRUE);
3886 elm_widget_event_hook_set(obj, _event_hook);
3887 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3888 elm_widget_translate_hook_set(obj, _translate_hook);
3891 wd->scr = elm_smart_scroller_add(e);
3892 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_DOWN,
3893 _mouse_down_scroller, obj);
3894 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_UP,
3895 _mouse_up_scroller, obj);
3896 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_MOVE,
3897 _mouse_move_scroller, obj);
3898 elm_smart_scroller_widget_set(wd->scr, obj);
3899 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3900 elm_widget_style_get(obj));
3901 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3902 _elm_config->thumbscroll_bounce_enable);
3903 elm_widget_resize_object_set(obj, wd->scr);
3905 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3906 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3907 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3908 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3909 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3910 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3911 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3912 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3915 wd->mode = ELM_LIST_SCROLL;
3916 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3917 wd->item_cache_max = wd->max_items_per_block * 2;
3918 wd->longpress_timeout = _elm_config->longpress_timeout;
3919 wd->highlight = EINA_TRUE;
3920 wd->tree_effect_enabled = _elm_config->effect_enable;
3922 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3923 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3924 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3925 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3927 wd->pan_smart = evas_object_smart_add(e, smart);
3928 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3931 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3932 _pan_set, _pan_get, _pan_max_get,
3933 _pan_min_get, _pan_child_size_get);
3935 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3937 evas_object_size_hint_min_set(obj, minw, minh);
3939 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3941 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3947 _item_select(Elm_Gen_Item *it)
3950 Evas_Object *obj = WIDGET(it);
3951 Evas_Object *item_obj;
3953 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3954 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3955 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3959 it->selected = EINA_TRUE;
3960 it->wd->selected = eina_list_append(it->wd->selected, it);
3962 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3964 evas_object_ref(obj);
3967 if (it->wd->last_selected_item &&
3968 (it != (Elm_Gen_Item *) it->wd->last_selected_item))
3970 Elm_Gen_Item *_lsit = (Elm_Gen_Item *)it->wd->last_selected_item;
3972 EINA_LIST_FOREACH(_lsit->content_objs, l, item_obj)
3974 elm_widget_focused_object_clear(item_obj);
3975 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3977 if (elm_widget_type_get(obj) == _genlist)
3979 EINA_LIST_FOREACH(_lsit->item->flip_content_objs, l, item_obj)
3981 elm_widget_focused_object_clear(item_obj);
3982 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3984 EINA_LIST_FOREACH(_lsit->item->deco_all_content_objs, l, item_obj)
3986 elm_widget_focused_object_clear(item_obj);
3987 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3990 _lsit->can_focus = EINA_FALSE;
3992 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3993 if (it->generation == it->wd->generation)
3994 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3997 if ((it->wd->clear_me) && (!it->wd->walking))
3998 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
4001 if ((!it->walking) && (it->generation < it->wd->generation))
4006 elm_widget_item_free(it);
4010 it->wd->last_selected_item = (Elm_Object_Item *)it;
4012 evas_object_unref(obj);
4015 static Evas_Object *
4016 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
4018 return edje_object_part_swallow_get(VIEW(it), part);
4022 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
4024 if (content && part)
4026 it->content_objs = eina_list_append(it->content_objs, content);
4027 edje_object_part_swallow(VIEW(it), part, content);
4031 static Evas_Object *
4032 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
4035 obj = edje_object_part_swallow_get(VIEW(it), part);
4036 if (!obj) return NULL;
4037 it->content_objs = eina_list_remove(it->content_objs, obj);
4038 edje_object_part_unswallow(VIEW(it), obj);
4043 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
4045 if (!it->itc->func.text_get) return NULL;
4046 return edje_object_part_text_get(VIEW(it), part);
4050 _item_disable_hook(Elm_Object_Item *it)
4054 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4056 if (_it->generation < _it->wd->generation) return;
4059 elm_genlist_item_selected_set(it, EINA_FALSE);
4063 if (elm_widget_item_disabled_get(it))
4065 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
4066 if (_it->deco_all_view)
4067 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
4071 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
4072 if (_it->deco_all_view)
4073 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
4075 EINA_LIST_FOREACH(_it->content_objs, l, obj)
4076 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
4081 _item_del_pre_hook(Elm_Object_Item *it)
4083 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4085 if ((_it->relcount > 0) || (_it->walking > 0))
4087 elm_genlist_item_subitems_clear(it);
4088 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
4089 _elm_genlist_item_del_notserious(_it);
4090 if (_it->item->block)
4092 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
4093 _it->item->block->changed = EINA_TRUE;
4094 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
4095 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
4099 _it->parent->item->items =
4100 eina_list_remove(_it->parent->item->items, it);
4110 _item_signal_emit_hook(Elm_Object_Item *it,
4111 const char *emission,
4114 edje_object_signal_emit(VIEW(it), emission, source);
4118 _elm_genlist_item_new(Widget_Data *wd,
4119 const Elm_Gen_Item_Class *itc,
4121 Elm_Gen_Item *parent,
4123 const void *func_data)
4127 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
4128 if (!it) return NULL;
4130 it->generation = wd->generation;
4132 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
4133 it->base.data = data;
4134 it->parent = parent;
4135 it->func.func = func;
4136 it->func.data = func_data;
4137 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
4138 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
4139 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
4140 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
4141 elm_widget_item_disable_hook_set(it, _item_disable_hook);
4142 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
4143 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
4146 it->sel_cb = (Ecore_Cb)_item_select;
4151 static Elm_Gen_Item *
4152 _item_new(Widget_Data *wd,
4153 const Elm_Genlist_Item_Class *itc,
4155 Elm_Gen_Item *parent,
4156 Elm_Genlist_Item_Type type,
4158 const void *func_data)
4160 Elm_Gen_Item *it, *it2;
4163 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
4164 if (!it) return NULL;
4165 it->item = ELM_NEW(Elm_Gen_Item_Type);
4166 it->item->type = type;
4167 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
4168 it->item->expanded_depth = 0;
4169 ELM_GEN_ITEM_SETUP(it);
4170 it->mouse_cursor = NULL;
4171 it->can_focus = EINA_TRUE;
4174 if (it->parent->group)
4175 it->item->group_item = parent;
4176 else if (it->parent->item->group_item)
4177 it->item->group_item = it->parent->item->group_item;
4179 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
4181 if (!it2->parent->group) depth += 1;
4183 it->item->expanded_depth = depth;
4189 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
4193 itb = calloc(1, sizeof(Item_Block));
4194 if (!itb) return NULL;
4198 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
4199 _item_block_position_update(wd->blocks, 0);
4203 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4204 itb->position_update = EINA_TRUE;
4205 if (wd->blocks != EINA_INLIST_GET(itb))
4207 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4218 _item_block_add(Widget_Data *wd,
4221 Item_Block *itb = NULL;
4228 itb = calloc(1, sizeof(Item_Block));
4229 if (!itb) return EINA_FALSE;
4231 if (!it->item->rel->item->block)
4234 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4235 itb->items = eina_list_append(itb->items, it);
4236 itb->position_update = EINA_TRUE;
4237 it->position = eina_list_count(itb->items);
4238 it->position_update = EINA_TRUE;
4240 if (wd->blocks != EINA_INLIST_GET(itb))
4242 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4253 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4254 if (it->item->before)
4256 wd->blocks = eina_inlist_prepend_relative
4257 (wd->blocks, EINA_INLIST_GET(itb),
4258 EINA_INLIST_GET(it->item->rel->item->block));
4260 eina_list_prepend_relative_list(itb->items, it, tmp);
4262 /* Update index from where we prepended */
4263 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4264 _item_block_position_update(EINA_INLIST_GET(itb),
4265 it->item->rel->item->block->position);
4269 wd->blocks = eina_inlist_append_relative
4270 (wd->blocks, EINA_INLIST_GET(itb),
4271 EINA_INLIST_GET(it->item->rel->item->block));
4273 eina_list_append_relative_list(itb->items, it, tmp);
4275 /* Update block index from where we appended */
4276 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4277 _item_block_position_update(EINA_INLIST_GET(itb),
4278 it->item->rel->item->block->position + 1);
4284 if (it->item->before)
4288 itb = (Item_Block *)(wd->blocks);
4289 if (itb->count >= wd->max_items_per_block)
4291 itb = _item_block_new(wd, EINA_TRUE);
4292 if (!itb) return EINA_FALSE;
4297 itb = _item_block_new(wd, EINA_TRUE);
4298 if (!itb) return EINA_FALSE;
4300 itb->items = eina_list_prepend(itb->items, it);
4302 _item_position_update(itb->items, 0);
4308 itb = (Item_Block *)(wd->blocks->last);
4309 if (itb->count >= wd->max_items_per_block)
4311 itb = _item_block_new(wd, EINA_FALSE);
4312 if (!itb) return EINA_FALSE;
4317 itb = _item_block_new(wd, EINA_FALSE);
4318 if (!itb) return EINA_FALSE;
4320 itb->items = eina_list_append(itb->items, it);
4321 it->position = eina_list_count(itb->items);
4329 if (it->item->rel->item->queued)
4331 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
4332 on sorted insertion order, so the queue is not always ordered like the item list.
4333 This lead to issue where we depend on an item that is not yet created. As a quick
4334 work around, we reschedule the calc of the item and stop reordering the list to
4335 prevent any nasty issue to show up here.
4337 wd->queue = eina_list_append(wd->queue, it);
4338 wd->requeued = EINA_TRUE;
4339 it->item->queued = EINA_TRUE;
4342 itb = it->item->rel->item->block;
4343 if (!itb) goto newblock;
4344 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4345 if (it->item->before)
4347 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4348 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4352 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4353 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4357 itb->changed = EINA_TRUE;
4358 it->item->block = itb;
4359 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
4360 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
4363 it->item->rel->relcount--;
4364 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
4366 _item_del(it->item->rel);
4367 elm_widget_item_free(it->item->rel);
4369 it->item->rel = NULL;
4371 if (itb->count > itb->wd->max_items_per_block)
4376 Eina_Bool done = EINA_FALSE;
4378 newc = itb->count / 2;
4380 if (EINA_INLIST_GET(itb)->prev)
4382 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4384 if (itbp->count + newc < wd->max_items_per_block / 2)
4386 /* moving items to previous block */
4387 while ((itb->count > newc) && (itb->items))
4389 it2 = eina_list_data_get(itb->items);
4390 itb->items = eina_list_remove_list(itb->items, itb->items);
4393 itbp->items = eina_list_append(itbp->items, it2);
4394 it2->item->block = itbp;
4402 if (!done && EINA_INLIST_GET(itb)->next)
4404 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4406 if (itbn->count + newc < wd->max_items_per_block / 2)
4408 /* moving items to next block */
4409 while ((itb->count > newc) && (itb->items))
4413 l = eina_list_last(itb->items);
4414 it2 = eina_list_data_get(l);
4415 itb->items = eina_list_remove_list(itb->items, l);
4418 itbn->items = eina_list_prepend(itbn->items, it2);
4419 it2->item->block = itbn;
4429 /* moving items to new block */
4430 itb2 = calloc(1, sizeof(Item_Block));
4431 if (!itb2) return EINA_FALSE;
4434 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4435 EINA_INLIST_GET(itb));
4436 itb2->changed = EINA_TRUE;
4437 while ((itb->count > newc) && (itb->items))
4441 l = eina_list_last(itb->items);
4443 itb->items = eina_list_remove_list(itb->items, l);
4446 itb2->items = eina_list_prepend(itb2->items, it2);
4447 it2->item->block = itb2;
4457 _item_process(Widget_Data *wd, Elm_Gen_Item *it)
4459 if (!_item_block_add(wd, it)) return 1;
4461 _item_block_realize(it->item->block);
4466 _item_process_post(Widget_Data *wd, Elm_Gen_Item *it, Eina_Bool qadd)
4468 Eina_Bool showme = EINA_FALSE;
4470 if (it->item->block->changed)
4472 showme = _item_block_recalc(it->item->block, it->item->block->num, qadd);
4473 it->item->block->changed = 0;
4474 if (wd->pan_changed)
4476 if (wd->calc_job) ecore_job_del(wd->calc_job);
4477 wd->calc_job = NULL;
4479 wd->pan_changed = EINA_FALSE;
4482 if (showme) it->item->block->showme = EINA_TRUE;
4486 _queue_process(Widget_Data *wd)
4491 t0 = ecore_loop_time_get();
4492 //evas_event_freeze(evas_object_evas_get(wd->obj));
4493 for (n = 0; (wd->queue) && (n < 128); n++)
4497 it = eina_list_data_get(wd->queue);
4498 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4499 it->item->queued = EINA_FALSE;
4500 if (_item_process(wd, it)) continue;
4501 t = ecore_time_get();
4502 _item_process_post(wd, it, EINA_TRUE);
4503 /* same as eina_inlist_count > 1 */
4504 if (wd->blocks && wd->blocks->next)
4506 if ((t - t0) > (ecore_animator_frametime_get())) break;
4509 //evas_event_thaw(evas_object_evas_get(wd->obj));
4510 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4515 _idle_process(void *data, Eina_Bool *wakeup)
4517 Widget_Data *wd = data;
4520 //static double q_start = 0.0;
4521 //if (q_start == 0.0) q_start = ecore_time_get();
4523 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4527 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4529 return ECORE_CALLBACK_CANCEL;
4531 return ECORE_CALLBACK_RENEW;
4535 _item_idle_enterer(void *data)
4537 Widget_Data *wd = data;
4538 Eina_Bool wakeup = EINA_FALSE;
4539 Eina_Bool ok = _idle_process(data, &wakeup);
4544 if (wd->calc_job) ecore_job_del(wd->calc_job);
4545 wd->calc_job = ecore_job_add(_calc_job, wd);
4547 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4552 _item_queue(Widget_Data *wd,
4556 if (it->item->queued) return;
4557 if ((wd->blocks) && (wd->homogeneous) && (wd->mode == ELM_LIST_COMPRESS))
4559 if (!_item_process(wd, it))
4560 _item_process_post(wd, it, EINA_FALSE);
4563 it->item->queued = EINA_TRUE;
4564 if (cb && !wd->requeued)
4565 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4567 wd->queue = eina_list_append(wd->queue, it);
4568 // FIXME: why does a freeze then thaw here cause some genlist
4569 // elm_genlist_item_append() to be much much slower?
4570 // evas_event_freeze(evas_object_evas_get(wd->obj));
4571 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4573 if (wd->queue_idle_enterer)
4575 ecore_idle_enterer_del(wd->queue_idle_enterer);
4576 wd->queue_idle_enterer = NULL;
4580 // evas_event_thaw(evas_object_evas_get(wd->obj));
4581 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4582 if (!wd->queue_idle_enterer)
4583 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4587 _elm_genlist_item_compare(const void *data, const void *data1)
4589 const Elm_Gen_Item *it, *item1;
4590 it = ELM_GEN_ITEM_FROM_INLIST(data);
4591 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4592 return it->wd->item_compare_cb(it, item1);
4596 _elm_genlist_item_list_compare(const void *data, const void *data1)
4598 const Elm_Gen_Item *it = data;
4599 const Elm_Gen_Item *item1 = data1;
4600 return it->wd->item_compare_cb(it, item1);
4603 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4605 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4610 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4611 _item_block_del(it);
4613 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4614 it->item->rel = after;
4615 it->item->rel->relcount++;
4616 it->item->before = EINA_FALSE;
4617 if (after->item->group_item) it->item->group_item = after->item->group_item;
4618 _item_queue(it->wd, it, NULL);
4620 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4623 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4625 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4628 if (!before) return;
4630 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4631 _item_block_del(it);
4632 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4633 it->item->rel = before;
4634 it->item->rel->relcount++;
4635 it->item->before = EINA_TRUE;
4636 if (before->item->group_item) it->item->group_item = before->item->group_item;
4637 _item_queue(it->wd, it, NULL);
4639 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4643 elm_genlist_items_count(const Evas_Object *obj)
4645 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4646 Widget_Data *wd = elm_widget_data_get(obj);
4648 return wd->item_count;
4651 EAPI Elm_Object_Item *
4652 elm_genlist_item_append(Evas_Object *obj,
4653 const Elm_Genlist_Item_Class *itc,
4655 Elm_Object_Item *parent,
4656 Elm_Genlist_Item_Type type,
4658 const void *func_data)
4660 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4661 Widget_Data *wd = elm_widget_data_get(obj);
4662 if (!wd) return NULL;
4663 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4665 if (!it) return NULL;
4669 wd->group_items = eina_list_append(wd->group_items, it);
4670 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4671 it->item->rel = NULL;
4675 Elm_Gen_Item *it2 = NULL;
4676 Eina_List *ll = eina_list_last(it->parent->item->items);
4677 if (ll) it2 = ll->data;
4678 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4679 if (!it2) it2 = it->parent;
4681 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4682 EINA_INLIST_GET(it2));
4683 it->item->rel = it2;
4684 it->item->rel->relcount++;
4686 it->item->before = EINA_FALSE;
4687 _item_queue(wd, it, NULL);
4688 return (Elm_Object_Item *)it;
4691 EAPI Elm_Object_Item *
4692 elm_genlist_item_prepend(Evas_Object *obj,
4693 const Elm_Genlist_Item_Class *itc,
4695 Elm_Object_Item *parent,
4696 Elm_Genlist_Item_Type type,
4698 const void *func_data)
4700 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4701 Widget_Data *wd = elm_widget_data_get(obj);
4702 if (!wd) return NULL;
4703 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4705 if (!it) return NULL;
4709 wd->group_items = eina_list_prepend(wd->group_items, it);
4710 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4711 it->item->rel = NULL;
4715 Elm_Gen_Item *it2 = NULL;
4716 Eina_List *ll = it->parent->item->items;
4717 if (ll) it2 = ll->data;
4718 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4719 if (!it2) it2 = it->parent;
4721 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4722 EINA_INLIST_GET(it2));
4723 it->item->rel = it2;
4724 it->item->rel->relcount++;
4726 it->item->before = EINA_TRUE;
4727 _item_queue(wd, it, NULL);
4728 return (Elm_Object_Item *)it;
4731 EAPI Elm_Object_Item *
4732 elm_genlist_item_insert_after(Evas_Object *obj,
4733 const Elm_Genlist_Item_Class *itc,
4735 Elm_Object_Item *parent,
4736 Elm_Object_Item *after,
4737 Elm_Genlist_Item_Type type,
4739 const void *func_data)
4741 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4742 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4743 Widget_Data *wd = elm_widget_data_get(obj);
4744 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4745 if (!wd) return NULL;
4746 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4747 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4749 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4751 if (!it) return NULL;
4754 if ((it->group) && (_after->group))
4755 wd->group_items = eina_list_append_relative(wd->group_items, it,
4760 it->parent->item->items =
4761 eina_list_append_relative(it->parent->item->items, it, _after);
4763 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4764 EINA_INLIST_GET(_after));
4765 it->item->rel = _after;
4766 it->item->rel->relcount++;
4767 it->item->before = EINA_FALSE;
4768 _item_queue(wd, it, NULL);
4769 return (Elm_Object_Item *)it;
4772 EAPI Elm_Object_Item *
4773 elm_genlist_item_insert_before(Evas_Object *obj,
4774 const Elm_Genlist_Item_Class *itc,
4776 Elm_Object_Item *parent,
4777 Elm_Object_Item *before,
4778 Elm_Genlist_Item_Type type,
4780 const void *func_data)
4782 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4783 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4784 Widget_Data *wd = elm_widget_data_get(obj);
4785 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4786 if (!wd) return NULL;
4787 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4788 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4790 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4792 if (!it) return NULL;
4795 if (it->group && _before->group)
4796 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4801 it->parent->item->items =
4802 eina_list_prepend_relative(it->parent->item->items, it, _before);
4804 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4805 EINA_INLIST_GET(_before));
4806 it->item->rel = _before;
4807 it->item->rel->relcount++;
4808 it->item->before = EINA_TRUE;
4809 _item_queue(wd, it, NULL);
4810 return (Elm_Object_Item *)it;
4813 EAPI Elm_Object_Item *
4814 elm_genlist_item_sorted_insert(Evas_Object *obj,
4815 const Elm_Genlist_Item_Class *itc,
4817 Elm_Object_Item *parent,
4818 Elm_Genlist_Item_Type type,
4819 Eina_Compare_Cb comp,
4821 const void *func_data)
4823 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4824 Widget_Data *wd = elm_widget_data_get(obj);
4825 if (!wd) return NULL;
4826 Elm_Gen_Item *rel = NULL;
4827 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4829 if (!it) return NULL;
4831 wd->item_compare_cb = comp;
4838 l = eina_list_search_sorted_near_list(it->parent->item->items,
4839 _elm_genlist_item_list_compare,
4843 rel = eina_list_data_get(l);
4847 if (cmp_result >= 0)
4849 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4850 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4851 it->item->before = EINA_FALSE;
4853 else if (cmp_result < 0)
4855 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4856 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4857 it->item->before = EINA_TRUE;
4864 wd->state = eina_inlist_sorted_state_new();
4865 eina_inlist_sorted_state_init(wd->state, wd->items);
4866 wd->requeued = EINA_FALSE;
4870 wd->group_items = eina_list_append(wd->group_items, it);
4872 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4873 _elm_genlist_item_compare, wd->state);
4875 if (EINA_INLIST_GET(it)->next)
4877 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4878 it->item->before = EINA_TRUE;
4880 else if (EINA_INLIST_GET(it)->prev)
4882 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4883 it->item->before = EINA_FALSE;
4889 it->item->rel = rel;
4890 it->item->rel->relcount++;
4893 _item_queue(wd, it, _elm_genlist_item_list_compare);
4895 return (Elm_Object_Item *)it;
4899 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4901 Eina_Inlist *next, *l;
4902 Widget_Data *wd = elm_widget_data_get(obj);
4905 if (!standby) wd->generation++;
4909 eina_inlist_sorted_state_free(wd->state);
4913 if (wd->walking > 0)
4915 wd->clear_me = EINA_TRUE;
4918 evas_event_freeze(evas_object_evas_get(wd->obj));
4919 for (l = wd->items, next = l ? l->next : NULL;
4921 l = next, next = next ? next->next : NULL)
4923 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4925 if (it->generation < wd->generation)
4927 Elm_Gen_Item *itn = NULL;
4929 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4930 if (itn) itn->walking++; /* prevent early death of subitem */
4932 elm_widget_item_free(it);
4933 if (itn) itn->walking--;
4936 wd->clear_me = EINA_FALSE;
4937 wd->pan_changed = EINA_TRUE;
4940 ecore_job_del(wd->calc_job);
4941 wd->calc_job = NULL;
4943 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4944 if (wd->clear_cb) wd->clear_cb(wd);
4950 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4951 wd->alpha_bg = NULL;
4955 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4956 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4958 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4959 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4960 evas_event_thaw(evas_object_evas_get(wd->obj));
4961 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4965 elm_genlist_clear(Evas_Object *obj)
4967 ELM_CHECK_WIDTYPE(obj, widtype);
4968 _elm_genlist_clear(obj, EINA_FALSE);
4972 elm_genlist_multi_select_set(Evas_Object *obj,
4975 ELM_CHECK_WIDTYPE(obj, widtype);
4976 Widget_Data *wd = elm_widget_data_get(obj);
4978 wd->multi = !!multi;
4982 elm_genlist_multi_select_get(const Evas_Object *obj)
4984 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4985 Widget_Data *wd = elm_widget_data_get(obj);
4986 if (!wd) return EINA_FALSE;
4990 EAPI Elm_Object_Item *
4991 elm_genlist_selected_item_get(const Evas_Object *obj)
4993 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4994 Widget_Data *wd = elm_widget_data_get(obj);
4995 if (!wd) return NULL;
4996 if (wd->selected) return wd->selected->data;
5000 EAPI const Eina_List *
5001 elm_genlist_selected_items_get(const Evas_Object *obj)
5003 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5004 Widget_Data *wd = elm_widget_data_get(obj);
5005 if (!wd) return NULL;
5006 return wd->selected;
5010 elm_genlist_realized_items_get(const Evas_Object *obj)
5012 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5013 Widget_Data *wd = elm_widget_data_get(obj);
5014 Eina_List *list = NULL;
5016 Eina_Bool done = EINA_FALSE;
5017 if (!wd) return NULL;
5018 EINA_INLIST_FOREACH(wd->blocks, itb)
5026 EINA_LIST_FOREACH(itb->items, l, it)
5028 if (it->realized) list = eina_list_append(list, it);
5039 EAPI Elm_Object_Item *
5040 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5045 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5046 Widget_Data *wd = elm_widget_data_get(obj);
5047 Evas_Coord ox, oy, ow, oh;
5050 if (!wd) return NULL;
5051 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5053 EINA_INLIST_FOREACH(wd->blocks, itb)
5058 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
5059 oy + itb->y - itb->wd->pan_y,
5060 itb->w, itb->h, x, y, 1, 1))
5062 EINA_LIST_FOREACH(itb->items, l, it)
5064 Evas_Coord itx, ity;
5066 itx = ox + itb->x + it->x - itb->wd->pan_x;
5067 ity = oy + itb->y + it->y - itb->wd->pan_y;
5068 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5072 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5073 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5077 return (Elm_Object_Item *)it;
5079 lasty = ity + it->item->h;
5084 if (y > lasty) *posret = 1;
5090 EAPI Elm_Object_Item *
5091 elm_genlist_first_item_get(const Evas_Object *obj)
5093 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5094 Widget_Data *wd = elm_widget_data_get(obj);
5095 if (!wd) return NULL;
5096 if (!wd->items) return NULL;
5097 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
5098 while ((it) && (it->generation < wd->generation))
5099 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5100 return (Elm_Object_Item *)it;
5103 EAPI Elm_Object_Item *
5104 elm_genlist_last_item_get(const Evas_Object *obj)
5106 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5107 Widget_Data *wd = elm_widget_data_get(obj);
5108 if (!wd) return NULL;
5109 if (!wd->items) return NULL;
5110 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
5111 while ((it) && (it->generation < wd->generation))
5112 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5113 return (Elm_Object_Item *)it;
5116 EAPI Elm_Object_Item *
5117 elm_genlist_item_next_get(const Elm_Object_Item *it)
5119 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5120 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5123 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
5124 if ((_it) && (_it->generation == _it->wd->generation)) break;
5126 return (Elm_Object_Item *) _it;
5129 EAPI Elm_Object_Item *
5130 elm_genlist_item_prev_get(const Elm_Object_Item *it)
5132 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5133 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5136 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
5137 if ((_it) && (_it->generation == _it->wd->generation)) break;
5139 return (Elm_Object_Item *) _it;
5142 EAPI Elm_Object_Item *
5143 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5145 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5146 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
5150 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
5152 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5153 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
5155 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5157 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
5158 _item_subitems_clear(_it);
5161 if (!wd->tree_effect_animator)
5163 wd->expanded_item = _it;
5164 _item_tree_effect_before(_it);
5165 evas_object_raise(wd->alpha_bg);
5166 evas_object_show(wd->alpha_bg);
5167 wd->start_time = ecore_time_get();
5168 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
5171 _item_subitems_clear(_it);
5176 elm_genlist_item_selected_set(Elm_Object_Item *it,
5179 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5180 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5181 Widget_Data *wd = _it->wd;
5183 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
5185 selected = !!selected;
5186 if (_it->selected == selected) return;
5192 while (wd->selected)
5194 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
5195 _it->unsel_cb(wd->selected->data);
5198 _it->highlight_cb(_it);
5202 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
5207 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5209 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5210 return ((Elm_Gen_Item *)it)->selected;
5214 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5217 if (it->item->expanded)
5219 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5223 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5226 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5227 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5234 _elm_genlist_move_items_set(Elm_Gen_Item *it)
5237 Elm_Gen_Item *it2 = NULL;
5238 Evas_Coord ox, oy, ow, oh, dh = 0;
5240 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
5242 if (it->item->expanded)
5244 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
5245 EINA_LIST_FOREACH_SAFE(it->wd->move_items, l, ll, it2)
5247 if (it2 == it->wd->expanded_next_item) break;
5248 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
5253 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
5254 it2 = it->wd->expanded_next_item;
5255 while (it2 && (dh < oy + oh))
5258 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
5259 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5265 elm_genlist_item_expanded_set(Elm_Object_Item *it,
5268 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5269 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5270 expanded = !!expanded;
5271 if (_it->item->expanded == expanded) return;
5272 if (_it->item->type != ELM_GENLIST_ITEM_TREE) return;
5273 _it->item->expanded = expanded;
5274 _it->wd->expanded_item = _it;
5275 _elm_genlist_move_items_set(_it);
5277 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
5278 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
5280 if (_it->item->expanded)
5282 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
5284 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
5285 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
5286 _it->wd->auto_scroll_enabled = EINA_TRUE;
5290 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
5292 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
5293 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
5294 _it->wd->auto_scroll_enabled = EINA_FALSE;
5299 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5301 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5302 return ((Elm_Gen_Item *)it)->item->expanded;
5306 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5308 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
5309 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5312 EINA_DEPRECATED EAPI void
5313 elm_genlist_item_display_only_set(Elm_Object_Item *it,
5314 Eina_Bool display_only)
5316 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5317 display_only = !!display_only;
5320 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
5323 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5324 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5325 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
5329 EINA_DEPRECATED EAPI Eina_Bool
5330 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
5332 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5333 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5334 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5335 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5336 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5342 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
5343 Elm_Genlist_Item_Scrollto_Type type,
5350 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5351 Evas_Coord gith = 0;
5352 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5353 if ((_it->wd->homogeneous) &&
5354 (_it->wd->mode == ELM_LIST_COMPRESS))
5355 goto hm_shortcut; /* homogenous genlist shortcut */
5356 if ((_it->item->queued) || (!_it->item->mincalcd))
5358 _it->wd->show_item = _it;
5359 _it->wd->bring_in = bring_in;
5360 _it->wd->scrollto_type = type;
5361 _it->item->showme = EINA_TRUE;
5365 if (_it->wd->show_item)
5367 _it->wd->show_item->item->showme = EINA_FALSE;
5368 _it->wd->show_item = NULL;
5371 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
5374 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5375 if ((_it->item->group_item) &&
5376 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
5377 gith = _it->item->group_item->item->h;
5379 *y = _it->y + _it->item->block->y - gith;
5381 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5382 if (_it->item->group_item) gith = _it->item->group_item->item->h;
5383 *y = _it->y + _it->item->block->y - gith;
5385 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5386 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
5392 *x = _it->x + _it->item->block->x;
5393 *w = _it->item->block->w;
5398 elm_genlist_item_promote(Elm_Object_Item *it)
5400 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5401 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5402 if (_it->generation < _it->wd->generation) return;
5403 _item_move_before(_it,
5404 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
5408 elm_genlist_item_demote(Elm_Object_Item *it)
5410 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5411 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5412 if (_it->generation < _it->wd->generation) return;
5413 _item_move_after(_it,
5414 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
5418 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5420 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5421 Evas_Coord x, y, w, h;
5422 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5424 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
5425 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
5429 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5432 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5433 Evas_Coord x, y, w, h;
5434 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5436 elm_smart_scroller_child_viewport_size_get(_it->wd->scr, &x, &y);
5438 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
5439 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
5443 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5445 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5447 Evas_Object *content;
5448 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5450 elm_widget_sub_object_del(WIDGET(it), content);
5451 evas_object_smart_member_del(content);
5452 evas_object_hide(content);
5453 if (l) *l = eina_list_append(*l, content);
5458 elm_genlist_item_update(Elm_Object_Item *it)
5460 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5461 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5463 if (!_it->item->block) return;
5464 if (_it->generation < _it->wd->generation) return;
5465 _it->item->mincalcd = EINA_FALSE;
5466 _it->item->updateme = EINA_TRUE;
5467 _it->item->block->updateme = EINA_TRUE;
5468 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5469 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5473 elm_genlist_item_fields_update(Elm_Object_Item *it,
5475 Elm_Genlist_Item_Field_Type itf)
5477 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5478 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5480 if (!_it->item->block) return;
5481 if (_it->generation < _it->wd->generation) return;
5483 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5484 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5485 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5487 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5488 &_it->contents, parts);
5489 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5490 &_it->contents, parts);
5494 _it->item->flip_content_objs =
5495 _item_mode_content_unrealize(_it, VIEW(_it),
5496 &_it->item->flip_contents, parts,
5497 &_it->item->flip_content_objs);
5498 _it->item->flip_content_objs =
5499 _item_mode_content_realize(_it, VIEW(_it),
5500 &_it->item->flip_contents, parts,
5501 &_it->item->flip_content_objs);
5503 if (_it->item->deco_it_view)
5505 _it->item->deco_it_content_objs =
5506 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5507 &_it->item->deco_it_contents, parts,
5508 &_it->item->deco_it_content_objs);
5509 _it->item->deco_it_content_objs =
5510 _item_mode_content_realize(_it, _it->item->deco_it_view,
5511 &_it->item->deco_it_contents, parts,
5512 &_it->item->deco_it_content_objs);
5514 if (_it->wd->decorate_all_mode)
5516 _it->item->deco_all_content_objs =
5517 _item_mode_content_unrealize(_it, _it->deco_all_view,
5518 &_it->item->deco_all_contents, parts,
5519 &_it->item->deco_all_content_objs);
5520 _it->item->deco_all_content_objs =
5521 _item_mode_content_realize(_it, _it->deco_all_view,
5522 &_it->item->deco_all_contents, parts,
5523 &_it->item->deco_all_content_objs);
5526 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5527 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5531 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5532 const Elm_Genlist_Item_Class *itc)
5534 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5535 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5537 if (!_it->item->block) return;
5538 EINA_SAFETY_ON_NULL_RETURN(itc);
5539 if (_it->generation < _it->wd->generation) return;
5541 _it->item->nocache_once = EINA_TRUE;
5543 elm_widget_stringlist_free(_it->texts);
5545 elm_widget_stringlist_free(_it->contents);
5546 _it->contents = NULL;
5547 elm_widget_stringlist_free(_it->states);
5552 elm_widget_stringlist_free(_it->item->flip_contents);
5553 _it->item->flip_contents = NULL;
5555 if (_it->item->deco_it_view)
5557 elm_widget_stringlist_free(_it->item->deco_it_texts);
5558 _it->item->deco_it_texts = NULL;
5559 elm_widget_stringlist_free(_it->item->deco_it_contents);
5560 _it->item->deco_it_contents = NULL;
5562 if (_it->wd->decorate_all_mode)
5564 elm_widget_stringlist_free(_it->item->deco_all_texts);
5565 _it->item->deco_all_texts = NULL;
5566 elm_widget_stringlist_free(_it->item->deco_all_contents);
5567 _it->item->deco_all_contents = NULL;
5570 elm_genlist_item_update(it);
5573 EAPI const Elm_Genlist_Item_Class *
5574 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5576 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5577 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5578 if (_it->generation < _it->wd->generation) return NULL;
5582 static Evas_Object *
5583 _elm_genlist_item_label_create(void *data,
5584 Evas_Object *obj __UNUSED__,
5585 Evas_Object *tooltip,
5586 void *it __UNUSED__)
5588 Evas_Object *label = elm_label_add(tooltip);
5591 elm_object_style_set(label, "tooltip");
5592 elm_object_text_set(label, data);
5597 _elm_genlist_item_label_del_cb(void *data,
5598 Evas_Object *obj __UNUSED__,
5599 void *event_info __UNUSED__)
5601 eina_stringshare_del(data);
5605 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5608 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5609 text = eina_stringshare_add(text);
5610 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5612 _elm_genlist_item_label_del_cb);
5616 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5617 Elm_Tooltip_Item_Content_Cb func,
5619 Evas_Smart_Cb del_cb)
5621 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5622 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5624 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5627 if (_it->tooltip.del_cb)
5628 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5630 _it->tooltip.content_cb = func;
5631 _it->tooltip.data = data;
5632 _it->tooltip.del_cb = del_cb;
5636 elm_widget_item_tooltip_content_cb_set(_it,
5637 _it->tooltip.content_cb,
5638 _it->tooltip.data, NULL);
5639 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5640 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5646 if (del_cb) del_cb((void *)data, NULL, NULL);
5650 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5652 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5653 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5655 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5656 elm_widget_item_tooltip_unset(_it);
5658 if (_it->tooltip.del_cb)
5659 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5660 _it->tooltip.del_cb = NULL;
5661 _it->tooltip.content_cb = NULL;
5662 _it->tooltip.data = NULL;
5663 _it->tooltip.free_size = EINA_FALSE;
5664 if (_it->tooltip.style)
5665 elm_genlist_item_tooltip_style_set(it, NULL);
5669 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5672 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5673 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5675 eina_stringshare_replace(&_it->tooltip.style, style);
5676 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5680 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5682 return elm_object_item_tooltip_style_get(it);
5686 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5689 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5690 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5692 _it->tooltip.free_size = disable;
5693 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5698 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5700 return elm_object_tooltip_window_mode_get(VIEW(it));
5704 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5707 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5708 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5709 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5710 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5714 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5716 return elm_widget_item_cursor_get(it);
5720 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5722 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5723 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5725 if (!_it->mouse_cursor) return;
5727 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5729 eina_stringshare_del(_it->mouse_cursor);
5730 _it->mouse_cursor = NULL;
5734 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5737 elm_widget_item_cursor_style_set(it, style);
5741 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5743 return elm_widget_item_cursor_style_get(it);
5747 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5748 Eina_Bool engine_only)
5750 elm_widget_item_cursor_engine_only_set(it, engine_only);
5754 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5756 return elm_widget_item_cursor_engine_only_get(it);
5760 elm_genlist_item_index_get(const Elm_Object_Item *it)
5762 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5763 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5765 if (_it->item->block)
5766 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5771 elm_genlist_mode_set(Evas_Object *obj,
5774 ELM_CHECK_WIDTYPE(obj, widtype);
5775 Widget_Data *wd = elm_widget_data_get(obj);
5777 if (wd->mode == mode) return;
5784 elm_genlist_mode_get(const Evas_Object *obj)
5786 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5787 Widget_Data *wd = elm_widget_data_get(obj);
5788 if (!wd) return ELM_LIST_LAST;
5793 elm_genlist_bounce_set(Evas_Object *obj,
5797 ELM_CHECK_WIDTYPE(obj, widtype);
5798 Widget_Data *wd = elm_widget_data_get(obj);
5800 wd->h_bounce = !!h_bounce;
5801 wd->v_bounce = !!v_bounce;
5802 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5806 elm_genlist_bounce_get(const Evas_Object *obj,
5807 Eina_Bool *h_bounce,
5808 Eina_Bool *v_bounce)
5810 ELM_CHECK_WIDTYPE(obj, widtype);
5811 Widget_Data *wd = elm_widget_data_get(obj);
5813 if (h_bounce) *h_bounce = wd->h_bounce;
5814 if (v_bounce) *v_bounce = wd->v_bounce;
5818 elm_genlist_homogeneous_set(Evas_Object *obj,
5819 Eina_Bool homogeneous)
5821 ELM_CHECK_WIDTYPE(obj, widtype);
5822 Widget_Data *wd = elm_widget_data_get(obj);
5824 wd->homogeneous = !!homogeneous;
5828 elm_genlist_homogeneous_get(const Evas_Object *obj)
5830 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5831 Widget_Data *wd = elm_widget_data_get(obj);
5832 if (!wd) return EINA_FALSE;
5833 return wd->homogeneous;
5837 elm_genlist_block_count_set(Evas_Object *obj,
5840 ELM_CHECK_WIDTYPE(obj, widtype);
5841 Widget_Data *wd = elm_widget_data_get(obj);
5843 wd->max_items_per_block = count;
5844 wd->item_cache_max = wd->max_items_per_block * 2;
5845 _item_cache_clean(wd);
5849 elm_genlist_block_count_get(const Evas_Object *obj)
5851 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5852 Widget_Data *wd = elm_widget_data_get(obj);
5854 return wd->max_items_per_block;
5858 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5861 ELM_CHECK_WIDTYPE(obj, widtype);
5862 Widget_Data *wd = elm_widget_data_get(obj);
5864 wd->longpress_timeout = timeout;
5868 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5870 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5871 Widget_Data *wd = elm_widget_data_get(obj);
5873 return wd->longpress_timeout;
5877 elm_genlist_scroller_policy_set(Evas_Object *obj,
5878 Elm_Scroller_Policy policy_h,
5879 Elm_Scroller_Policy policy_v)
5881 ELM_CHECK_WIDTYPE(obj, widtype);
5882 Widget_Data *wd = elm_widget_data_get(obj);
5883 if ((!wd) || (!wd->scr)) return;
5884 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5885 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5887 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5891 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5892 Elm_Scroller_Policy *policy_h,
5893 Elm_Scroller_Policy *policy_v)
5895 ELM_CHECK_WIDTYPE(obj, widtype);
5896 Widget_Data *wd = elm_widget_data_get(obj);
5897 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5898 if ((!wd) || (!wd->scr)) return;
5899 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5900 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5901 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5905 elm_genlist_realized_items_update(Evas_Object *obj)
5907 ELM_CHECK_WIDTYPE(obj, widtype);
5909 Eina_List *list, *l;
5910 Elm_Object_Item *it;
5912 list = elm_genlist_realized_items_get(obj);
5913 EINA_LIST_FOREACH(list, l, it)
5914 elm_genlist_item_update(it);
5918 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5919 const char *decorate_it_type,
5920 Eina_Bool decorate_it_set)
5922 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5923 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5925 Widget_Data *wd = _it->wd;
5927 Elm_Object_Item *it2;
5930 if (!decorate_it_type) return;
5931 if ((_it->generation < _it->wd->generation) ||
5932 elm_widget_item_disabled_get(_it)) return;
5933 if (wd->decorate_all_mode) return;
5935 if ((wd->mode_item == _it) &&
5936 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5939 if (!_it->itc->decorate_item_style) return;
5940 _it->decorate_it_set = decorate_it_set;
5944 EINA_LIST_FOREACH(wd->selected, l, it2)
5945 if (((Elm_Gen_Item *)it2)->realized)
5946 elm_genlist_item_selected_set(it2, EINA_FALSE);
5950 it2 = elm_genlist_selected_item_get(wd->obj);
5951 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5952 elm_genlist_item_selected_set(it2, EINA_FALSE);
5955 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5956 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5957 _decorate_item_unset(wd);
5959 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5960 if (decorate_it_set) _decorate_item_set(_it);
5964 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5966 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5967 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5968 return _it->wd->decorate_it_type;
5971 EAPI const Elm_Object_Item *
5972 elm_genlist_decorated_item_get(const Evas_Object *obj)
5974 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5975 Widget_Data *wd = elm_widget_data_get(obj);
5976 if (!wd) return NULL;
5977 return (Elm_Object_Item *) wd->mode_item;
5981 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5983 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5984 Widget_Data *wd = elm_widget_data_get(obj);
5985 if (!wd) return EINA_FALSE;
5987 return wd->decorate_all_mode;
5991 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5993 ELM_CHECK_WIDTYPE(obj, widtype);
5994 Eina_List *list, *l;
5997 Widget_Data *wd = elm_widget_data_get(obj);
5999 decorated = !!decorated;
6000 if (wd->decorate_all_mode == decorated) return;
6001 wd->decorate_all_mode = decorated;
6003 if (wd->tree_effect_animator)
6005 ecore_animator_del(wd->tree_effect_animator);
6006 wd->tree_effect_animator = NULL;
6008 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6010 list = elm_genlist_realized_items_get(obj);
6011 if (!wd->decorate_all_mode)
6013 EINA_LIST_FOREACH(list, l, it)
6015 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6016 _decorate_all_item_unrealize(it);
6018 _item_cache_zero(wd);
6022 EINA_LIST_FOREACH(list, l, it)
6024 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6026 if (it->itc->decorate_all_item_style)
6027 _decorate_all_item_realize(it, EINA_TRUE);
6031 if (wd->calc_job) ecore_job_del(wd->calc_job);
6032 wd->calc_job = ecore_job_add(_calc_job, wd);
6036 elm_genlist_reorder_mode_set(Evas_Object *obj,
6037 Eina_Bool reorder_mode)
6039 ELM_CHECK_WIDTYPE(obj, widtype);
6040 Widget_Data *wd = elm_widget_data_get(obj);
6042 wd->reorder_mode = !!reorder_mode;
6046 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6048 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6049 Widget_Data *wd = elm_widget_data_get(obj);
6050 if (!wd) return EINA_FALSE;
6051 return wd->reorder_mode;
6054 EAPI Elm_Genlist_Item_Type
6055 elm_genlist_item_type_get(const Elm_Object_Item *it)
6057 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
6058 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6059 return _it->item->type;
6062 EAPI Elm_Genlist_Item_Class *
6063 elm_genlist_item_class_new(void)
6065 Elm_Genlist_Item_Class *itc;
6067 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
6070 itc->version = CLASS_ALLOCATED;
6072 itc->delete_me = EINA_FALSE;
6078 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6080 if (itc && (itc->version == CLASS_ALLOCATED))
6082 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6083 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6093 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6095 if (itc && (itc->version == CLASS_ALLOCATED))
6098 if (itc->refcount == 0) itc->refcount--;
6103 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6105 if (itc && (itc->version == CLASS_ALLOCATED))
6107 if (itc->refcount > 0) itc->refcount--;
6108 if (itc->delete_me && (!itc->refcount))
6109 elm_genlist_item_class_free(itc);
6113 void _flip_job(void *data)
6115 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
6116 _item_unhighlight(it);
6118 _elm_genlist_item_unrealize(it, EINA_FALSE);
6119 it->flipped = EINA_TRUE;
6120 it->item->nocache = EINA_TRUE;
6121 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6122 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
6126 elm_genlist_item_flip_set(Elm_Object_Item *it,
6129 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6130 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6133 if (_it->flipped == flip) return;
6137 ecore_job_add(_flip_job, _it);
6141 _it->flipped = flip;
6142 _item_cache_zero(_it->wd);
6143 elm_genlist_item_update(it);
6144 _it->item->nocache = EINA_FALSE;
6149 elm_genlist_item_flip_get(const Elm_Object_Item *it)
6151 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6152 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6153 return _it->flipped;
6157 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
6159 ELM_CHECK_WIDTYPE(obj, widtype);
6160 Widget_Data *wd = elm_widget_data_get(obj);
6162 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6164 if (wd->select_mode != mode)
6165 wd->select_mode = mode;
6168 EAPI Elm_Object_Select_Mode
6169 elm_genlist_select_mode_get(const Evas_Object *obj)
6171 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
6172 Widget_Data *wd = elm_widget_data_get(obj);
6173 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
6174 return wd->select_mode;
6178 elm_genlist_highlight_mode_set(Evas_Object *obj,
6179 Eina_Bool highlight)
6181 ELM_CHECK_WIDTYPE(obj, widtype);
6182 Widget_Data *wd = elm_widget_data_get(obj);
6184 wd->highlight = !!highlight;
6188 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6190 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6191 Widget_Data *wd = elm_widget_data_get(obj);
6192 if (!wd) return EINA_FALSE;
6193 return wd->highlight;
6197 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
6198 Elm_Object_Select_Mode mode)
6200 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6201 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6203 if (_it->generation < _it->wd->generation) return;
6204 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6206 if (_it->select_mode != mode)
6207 _it->select_mode = mode;
6209 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6211 _it->item->mincalcd = EINA_FALSE;
6212 _it->item->updateme = EINA_TRUE;
6213 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
6214 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
6215 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
6219 EAPI Elm_Object_Select_Mode
6220 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
6222 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
6223 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6224 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
6225 return _it->select_mode;
6228 /* for gengrid as of now */
6230 _elm_genlist_page_relative_set(Evas_Object *obj,
6234 Evas_Coord pagesize_h;
6235 Evas_Coord pagesize_v;
6237 ELM_CHECK_WIDTYPE(obj, widtype);
6238 Widget_Data *wd = elm_widget_data_get(obj);
6241 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
6242 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
6246 /* for gengrid as of now */
6248 _elm_genlist_page_relative_get(const Evas_Object *obj,
6252 ELM_CHECK_WIDTYPE(obj, widtype);
6253 Widget_Data *wd = elm_widget_data_get(obj);
6256 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
6259 /* for gengrid as of now */
6261 _elm_genlist_page_size_set(Evas_Object *obj,
6262 Evas_Coord h_pagesize,
6263 Evas_Coord v_pagesize)
6268 ELM_CHECK_WIDTYPE(obj, widtype);
6269 Widget_Data *wd = elm_widget_data_get(obj);
6271 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
6272 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
6276 /* for gengrid as of now */
6278 _elm_genlist_current_page_get(const Evas_Object *obj,
6282 ELM_CHECK_WIDTYPE(obj, widtype);
6283 Widget_Data *wd = elm_widget_data_get(obj);
6285 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
6288 /* for gengrid as of now */
6290 _elm_genlist_last_page_get(const Evas_Object *obj,
6294 ELM_CHECK_WIDTYPE(obj, widtype);
6295 Widget_Data *wd = elm_widget_data_get(obj);
6297 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
6300 /* for gengrid as of now */
6302 _elm_genlist_page_show(const Evas_Object *obj,
6306 ELM_CHECK_WIDTYPE(obj, widtype);
6307 Widget_Data *wd = elm_widget_data_get(obj);
6309 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
6312 /* for gengrid as of now */
6314 _elm_genlist_page_bring_in(const Evas_Object *obj,
6318 ELM_CHECK_WIDTYPE(obj, widtype);
6319 Widget_Data *wd = elm_widget_data_get(obj);
6321 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
6325 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
6328 Evas_Object *content;
6330 if (!it->realized) return;
6331 if (it->wd->reorder_it == it) return;
6332 if (it->defer_unrealize && !it->item->updateme) return;
6334 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
6336 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
6339 ecore_timer_del(it->long_timer);
6340 it->long_timer = NULL;
6343 elm_widget_stringlist_free(it->texts);
6345 elm_widget_stringlist_free(it->contents);
6346 it->contents = NULL;
6347 elm_widget_stringlist_free(it->states);
6349 EINA_LIST_FREE(it->content_objs, content)
6350 evas_object_del(content);
6352 it->unrealize_cb(it);
6354 it->realized = EINA_FALSE;
6355 it->want_unrealize = EINA_FALSE;
6356 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
6357 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
6361 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
6363 elm_widget_item_pre_notify_del(it);
6364 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
6366 if ((it->relcount > 0) || (it->walking > 0)) return;
6368 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6370 if (it->itc->func.del)
6371 it->itc->func.del((void *)it->base.data, WIDGET(it));
6375 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
6377 _elm_genlist_item_del_notserious(it);
6378 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6379 if (it->tooltip.del_cb)
6380 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6381 it->wd->walking -= it->walking;
6384 ecore_timer_del(it->long_timer);
6385 it->long_timer = NULL;
6388 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
6392 eina_inlist_sorted_state_free(it->wd->state);
6393 it->wd->state = NULL;
6395 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6396 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
6400 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
6401 it->wd->last_selected_item = NULL;
6402 it->wd->item_count--;
6406 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
6408 ELM_CHECK_WIDTYPE(obj, widtype);
6409 Widget_Data *wd = elm_widget_data_get(obj);
6411 wd->tree_effect_enabled = !!enabled;
6415 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
6417 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6418 Widget_Data *wd = elm_widget_data_get(obj);
6419 if (!wd) return EINA_FALSE;
6420 return wd->tree_effect_enabled;
6424 _create_tray_alpha_bg(const Evas_Object *obj)
6426 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6427 Widget_Data *wd = elm_widget_data_get(obj);
6428 if (!wd) return NULL;
6430 Evas_Object *bg = NULL;
6431 Evas_Coord ox, oy, ow, oh;
6433 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6434 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6435 evas_object_color_set(bg,0,0,0,0);
6436 evas_object_resize(bg , ow, oh);
6437 evas_object_move(bg , ox, oy);
6442 _item_contract_emit(Elm_Gen_Item *it)
6447 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6448 it->item->tree_effect_finished = EINA_FALSE;
6450 EINA_LIST_FOREACH(it->item->items, l, it2)
6451 if (it2) _item_contract_emit(it2);
6455 _item_tree_effect_before(Elm_Gen_Item *it)
6460 EINA_LIST_FOREACH(it->item->items, l, it2)
6462 if (it2->parent && (it == it2->parent))
6465 it2->item->tree_effect_hideme = EINA_TRUE;
6466 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6467 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6468 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6469 _item_contract_emit(it2);
6472 return ECORE_CALLBACK_CANCEL;
6476 _item_tree_effect(Widget_Data *wd, int y)
6478 Elm_Gen_Item *it = NULL, *expanded_next_it;
6480 expanded_next_it = wd->expanded_next_item;
6482 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6484 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6487 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6488 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6489 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6491 if (!it->item->tree_effect_finished)
6493 edje_object_signal_emit(VIEW(it), "flip_item", "");
6494 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6495 it->item->tree_effect_finished = EINA_TRUE;
6498 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6501 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6503 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6506 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6507 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6509 if (!it->item->tree_effect_finished)
6511 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6512 it->item->tree_effect_finished = EINA_TRUE;
6517 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6523 _item_tree_effect_finish(Widget_Data *wd)
6525 Elm_Gen_Item *it = NULL;
6528 if (wd->tree_effect_animator)
6530 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6531 _item_subitems_clear(wd->expanded_item);
6532 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6534 it->item->tree_effect_finished = EINA_TRUE;
6535 it->item->old_scrl_y = it->item->scrl_y;
6536 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6537 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6540 _item_auto_scroll(wd);
6541 evas_object_lower(wd->alpha_bg);
6542 evas_object_hide(wd->alpha_bg);
6543 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6544 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6546 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6547 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6548 evas_object_smart_changed(wd->pan_smart);
6550 wd->tree_effect_animator = NULL;
6554 _tree_effect_animator_cb(void *data)
6556 Widget_Data *wd = data;
6557 if (!wd) return ECORE_CALLBACK_CANCEL;
6558 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6559 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6561 double effect_duration = 0.3, t;
6562 int y = 0, dy = 0, dh = 0;
6563 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6566 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6567 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6568 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6569 if (t > effect_duration) end = EINA_TRUE;
6571 // Below while statement is needed, when the genlist is resized.
6572 it2 = wd->expanded_item;
6575 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6576 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6577 cvx, cvy, cvw, cvh));
6578 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6581 if (wd->expanded_next_item)
6583 expanded_next_it = wd->expanded_next_item;
6586 EINA_LIST_FOREACH(wd->move_items, l, it)
6588 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6590 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6591 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6592 expanded_next_it->item->scrl_y = cvy + cvh;
6594 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6595 cvy + cvh : expanded_next_it->item->scrl_y) -
6596 expanded_next_it->item->old_scrl_y;
6598 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6600 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6601 expanded_next_it->item->old_scrl_y = cvy + cvh;
6603 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6605 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6607 expanded_next_it->item->old_scrl_y = cvy + cvh;
6611 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6612 expanded_next_it->item->old_scrl_y;
6616 if (t <= effect_duration)
6618 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6626 if (!it->realized && !it->item->queued)
6627 _item_realize(it, in, 0);
6630 if (it != expanded_next_it)
6632 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6636 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6637 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6640 _item_tree_effect(wd, y);
6644 int expanded_item_num = 0;
6647 if (wd->expanded_item)
6648 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6653 expanded_item_num++;
6654 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6660 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6661 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6663 if (!it->item->tree_effect_finished)
6665 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6667 edje_object_signal_emit(VIEW(it), "flip_item", "");
6668 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6669 it->item->tree_effect_finished = EINA_TRUE;
6673 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6679 _item_tree_effect_finish(wd);
6680 return ECORE_CALLBACK_CANCEL;
6682 return ECORE_CALLBACK_RENEW;