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 EINA_SAFETY_ON_NULL_RETURN(it);
966 Evas_Event_Mouse_Move *ev = event_info;
967 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
968 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
970 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
972 if (!it->wd->on_hold)
974 it->wd->on_hold = EINA_TRUE;
975 if ((!it->wd->wasselected) && (!it->flipped))
977 _item_unhighlight(it);
982 if (it->wd->multitouched)
984 it->wd->cur_x = ev->cur.canvas.x;
985 it->wd->cur_y = ev->cur.canvas.y;
988 if ((it->dragging) && (it->down))
990 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
993 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
994 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
995 if (abs((it->wd->history[it->wd->movements].x -
996 it->wd->history[0].x)) > 40)
997 it->wd->swipe = EINA_TRUE;
1003 ecore_timer_del(it->long_timer);
1004 it->long_timer = NULL;
1006 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
1009 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
1013 ecore_timer_del(it->long_timer);
1014 it->long_timer = NULL;
1016 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1018 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
1020 if (ev->cur.canvas.y < (oy + (it->wd->reorder_it->item->h / 2)))
1021 it->wd->reorder_fast = 1;
1022 else if (ev->cur.canvas.y > (oy + oh - (it->wd->reorder_it->item->h / 2)))
1023 it->wd->reorder_fast = -1;
1024 else it->wd->reorder_fast = 0;
1026 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
1028 if (!it->wd->reorder_start_y)
1029 it->wd->reorder_start_y = it->item->block->y + it->y;
1033 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
1034 y_pos = oy + oh - it->wd->reorder_it->item->h;
1038 if (it->deco_all_view)
1039 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
1041 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1043 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1044 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1048 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1049 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1050 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1051 x = ev->cur.canvas.x - x;
1052 y = ev->cur.canvas.y - y;
1055 if (adx < 0) adx = -dx;
1058 if (ady < 0) ady = -dy;
1061 if ((adx > minw) || (ady > minh))
1063 it->dragging = EINA_TRUE;
1066 ecore_timer_del(it->long_timer);
1067 it->long_timer = NULL;
1069 if ((!it->wd->wasselected) && (!it->flipped))
1071 _item_unhighlight(it);
1076 if ((ady > adx) && (!it->wd->drag_started))
1077 evas_object_smart_callback_call(WIDGET(it),
1078 SIG_DRAG_START_UP, it);
1082 evas_object_smart_callback_call(WIDGET(it),
1083 SIG_DRAG_START_LEFT, it);
1085 evas_object_smart_callback_call(WIDGET(it),
1086 SIG_DRAG_START_RIGHT, it);
1091 if ((ady > adx) && (!it->wd->drag_started))
1092 evas_object_smart_callback_call(WIDGET(it),
1093 SIG_DRAG_START_DOWN, it);
1097 evas_object_smart_callback_call(WIDGET(it),
1098 SIG_DRAG_START_LEFT, it);
1100 evas_object_smart_callback_call(WIDGET(it),
1101 SIG_DRAG_START_RIGHT, it);
1108 _long_press(void *data)
1110 Elm_Gen_Item *it = data, *it_tmp;
1111 Eina_List *list, *l;
1113 it->long_timer = NULL;
1114 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1115 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1116 return ECORE_CALLBACK_CANCEL;
1117 it->wd->longpressed = EINA_TRUE;
1118 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1119 if ((it->wd->reorder_mode) && (!it->group))
1121 it->wd->reorder_it = it;
1122 it->wd->reorder_start_y = 0;
1123 if (it->deco_all_view)
1124 evas_object_raise(it->deco_all_view);
1126 evas_object_raise(VIEW(it));
1128 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1129 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1131 list = elm_genlist_realized_items_get(it->wd->obj);
1132 EINA_LIST_FOREACH(list, l, it_tmp)
1134 if (it != it_tmp) _item_unselect(it_tmp);
1136 if (it->item->items)
1138 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
1140 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
1142 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
1144 return ECORE_CALLBACK_RENEW;
1148 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1150 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1151 return ECORE_CALLBACK_RENEW;
1154 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1156 return ECORE_CALLBACK_CANCEL;
1160 _swipe(Elm_Gen_Item *it)
1165 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1166 elm_widget_item_disabled_get(it)) return;
1167 it->wd->swipe = EINA_FALSE;
1168 for (i = 0; i < it->wd->movements; i++)
1170 sum += it->wd->history[i].x;
1171 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1174 sum /= it->wd->movements;
1175 if (abs(sum - it->wd->history[0].x) <= 10) return;
1176 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1180 _swipe_cancel(void *data)
1182 Elm_Gen_Item *it = data;
1184 if (!it) return ECORE_CALLBACK_CANCEL;
1185 it->wd->swipe = EINA_FALSE;
1186 it->wd->movements = 0;
1187 return ECORE_CALLBACK_RENEW;
1191 _multi_cancel(void *data)
1193 Widget_Data *wd = data;
1195 if (!wd) return ECORE_CALLBACK_CANCEL;
1196 wd->multi_timeout = EINA_TRUE;
1197 return ECORE_CALLBACK_RENEW;
1201 _multi_touch_gesture_eval(void *data)
1203 Elm_Gen_Item *it = data;
1205 it->wd->multitouched = EINA_FALSE;
1206 if (it->wd->multi_timer)
1208 ecore_timer_del(it->wd->multi_timer);
1209 it->wd->multi_timer = NULL;
1211 if (it->wd->multi_timeout)
1213 it->wd->multi_timeout = EINA_FALSE;
1217 Evas_Coord minw = 0, minh = 0;
1218 Evas_Coord off_x, off_y, off_mx, off_my;
1220 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1221 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1222 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1223 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1224 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1226 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1228 if ((off_x + off_mx) > (off_y + off_my))
1230 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1231 evas_object_smart_callback_call(WIDGET(it),
1232 SIG_MULTI_SWIPE_RIGHT, it);
1233 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1234 evas_object_smart_callback_call(WIDGET(it),
1235 SIG_MULTI_SWIPE_LEFT, it);
1236 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1237 evas_object_smart_callback_call(WIDGET(it),
1238 SIG_MULTI_PINCH_OUT, it);
1240 evas_object_smart_callback_call(WIDGET(it),
1241 SIG_MULTI_PINCH_IN, it);
1245 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1246 evas_object_smart_callback_call(WIDGET(it),
1247 SIG_MULTI_SWIPE_DOWN, it);
1248 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1249 evas_object_smart_callback_call(WIDGET(it),
1250 SIG_MULTI_SWIPE_UP, it);
1251 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1252 evas_object_smart_callback_call(WIDGET(it),
1253 SIG_MULTI_PINCH_OUT, it);
1255 evas_object_smart_callback_call(WIDGET(it),
1256 SIG_MULTI_PINCH_IN, it);
1259 it->wd->multi_timeout = EINA_FALSE;
1263 _multi_down(void *data,
1264 Evas *evas __UNUSED__,
1265 Evas_Object *obj __UNUSED__,
1268 Elm_Gen_Item *it = data;
1269 Evas_Event_Multi_Down *ev = event_info;
1271 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1272 it->wd->multi_device = ev->device;
1273 it->wd->multi_down = EINA_TRUE;
1274 it->wd->multitouched = EINA_TRUE;
1275 it->wd->prev_mx = ev->canvas.x;
1276 it->wd->prev_my = ev->canvas.y;
1277 if (!it->wd->wasselected)
1279 _item_unhighlight(it);
1282 it->wd->wasselected = EINA_FALSE;
1283 it->wd->longpressed = EINA_FALSE;
1286 ecore_timer_del(it->long_timer);
1287 it->long_timer = NULL;
1291 it->dragging = EINA_FALSE;
1292 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1294 if (it->item->swipe_timer)
1296 ecore_timer_del(it->item->swipe_timer);
1297 it->item->swipe_timer = NULL;
1299 if (it->wd->on_hold)
1301 it->wd->swipe = EINA_FALSE;
1302 it->wd->movements = 0;
1303 it->wd->on_hold = EINA_FALSE;
1308 _multi_up(void *data,
1309 Evas *evas __UNUSED__,
1310 Evas_Object *obj __UNUSED__,
1313 Elm_Gen_Item *it = data;
1314 Evas_Event_Multi_Up *ev = event_info;
1316 if (it->wd->multi_device != ev->device) return;
1317 it->wd->multi_device = 0;
1318 it->wd->multi_down = EINA_FALSE;
1319 if (it->wd->mouse_down) return;
1320 _multi_touch_gesture_eval(data);
1324 _multi_move(void *data,
1325 Evas *evas __UNUSED__,
1326 Evas_Object *obj __UNUSED__,
1329 Elm_Gen_Item *it = data;
1330 Evas_Event_Multi_Move *ev = event_info;
1332 if (it->wd->multi_device != ev->device) return;
1333 it->wd->cur_mx = ev->cur.canvas.x;
1334 it->wd->cur_my = ev->cur.canvas.y;
1338 _item_unfocusable_set(Elm_Gen_Item *it, Eina_Bool unfocus)
1341 Evas_Object *item_obj;
1342 Evas_Object *obj = WIDGET(it);
1345 EINA_LIST_FOREACH(it->content_objs, l, item_obj)
1347 if (unfocus) elm_widget_focused_object_clear(item_obj);
1348 elm_widget_tree_unfocusable_set(item_obj, unfocus);
1350 if (elm_widget_type_get(obj) == _genlist)
1352 EINA_LIST_FOREACH(it->item->flip_content_objs, l, item_obj)
1354 if (unfocus) elm_widget_focused_object_clear(item_obj);
1355 elm_widget_tree_unfocusable_set(item_obj, unfocus);
1357 EINA_LIST_FOREACH(it->item->deco_all_content_objs, l, item_obj)
1359 if (unfocus) elm_widget_focused_object_clear(item_obj);
1360 elm_widget_tree_unfocusable_set(item_obj, unfocus);
1363 it->can_focus = !unfocus;
1368 _mouse_down(void *data,
1369 Evas *evas __UNUSED__,
1373 Elm_Gen_Item *it = data;
1374 Evas_Event_Mouse_Down *ev = event_info;
1377 if (ev->button != 1) return;
1379 _item_unfocusable_set(it, EINA_FALSE);
1380 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1382 it->wd->on_hold = EINA_TRUE;
1385 it->down = EINA_TRUE;
1386 it->dragging = EINA_FALSE;
1387 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1388 it->dx = ev->canvas.x - x;
1389 it->dy = ev->canvas.y - y;
1390 it->wd->mouse_down = EINA_TRUE;
1391 if (!it->wd->multitouched)
1393 it->wd->prev_x = ev->canvas.x;
1394 it->wd->prev_y = ev->canvas.y;
1395 it->wd->multi_timeout = EINA_FALSE;
1396 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1397 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1399 it->wd->longpressed = EINA_FALSE;
1400 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1401 else it->wd->on_hold = EINA_FALSE;
1402 if (it->wd->on_hold) return;
1403 it->wd->wasselected = it->selected;
1404 _item_highlight(it);
1405 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1406 if ((!elm_widget_item_disabled_get(it)) &&
1407 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1409 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1410 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1412 if (it->long_timer) ecore_timer_del(it->long_timer);
1413 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1414 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1416 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1419 it->long_timer = NULL;
1420 it->wd->swipe = EINA_FALSE;
1421 it->wd->movements = 0;
1425 _mouse_up(void *data,
1426 Evas *evas __UNUSED__,
1427 Evas_Object *obj __UNUSED__,
1430 Elm_Gen_Item *it = data;
1431 Evas_Event_Mouse_Up *ev = event_info;
1432 Eina_Bool dragged = EINA_FALSE;
1434 if (ev->button != 1) return;
1435 it->down = EINA_FALSE;
1436 it->wd->mouse_down = EINA_FALSE;
1437 if (it->wd->multitouched)
1439 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1440 if (it->wd->multi_down) return;
1441 _multi_touch_gesture_eval(data);
1444 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1445 else it->wd->on_hold = EINA_FALSE;
1448 ecore_timer_del(it->long_timer);
1449 it->long_timer = NULL;
1453 it->dragging = EINA_FALSE;
1454 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1457 if (it->item->swipe_timer)
1459 ecore_timer_del(it->item->swipe_timer);
1460 it->item->swipe_timer = NULL;
1462 if (it->wd->multi_timer)
1464 ecore_timer_del(it->wd->multi_timer);
1465 it->wd->multi_timer = NULL;
1466 it->wd->multi_timeout = EINA_FALSE;
1468 if (it->wd->on_hold)
1470 if (it->wd->swipe) _swipe(data);
1471 it->wd->longpressed = EINA_FALSE;
1472 it->wd->on_hold = EINA_FALSE;
1475 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1477 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1478 it->wd->reorder_fast = 0;
1480 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1482 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1483 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1485 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1486 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1490 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1491 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1493 it->wd->reorder_deleted = EINA_FALSE;
1494 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1495 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1496 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1497 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1499 if (it->wd->longpressed)
1501 it->wd->longpressed = EINA_FALSE;
1502 if ((!it->wd->wasselected) && (!it->flipped))
1504 _item_unhighlight(it);
1507 it->wd->wasselected = EINA_FALSE;
1512 if (it->want_unrealize)
1514 _elm_genlist_item_unrealize(it, EINA_FALSE);
1515 if (it->item->block->want_unrealize)
1516 _item_block_unrealize(it->item->block);
1519 if (elm_widget_item_disabled_get(it) || (dragged) ||
1520 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1522 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1527 _item_highlight(it);
1532 _item_unhighlight(it);
1540 Widget_Data *wd = it->wd;
1543 while (wd->selected)
1545 _item_unhighlight(wd->selected->data);
1546 _item_unselect(wd->selected->data);
1552 const Eina_List *l, *l_next;
1555 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1558 _item_unhighlight(it2);
1559 _item_unselect(it2);
1561 //_item_highlight(it);
1564 _item_highlight(it);
1570 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1572 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1574 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1576 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1578 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1580 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1582 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1587 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1589 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1591 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1593 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1595 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1597 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1599 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1605 _mouse_down_scroller(void *data,
1606 Evas *evas __UNUSED__,
1607 Evas_Object *obj __UNUSED__,
1608 void *event_info __UNUSED__)
1610 Widget_Data *wd = elm_widget_data_get(data);
1613 wd->drag_started = EINA_FALSE;
1617 _mouse_up_scroller(void *data,
1618 Evas *evas __UNUSED__,
1619 Evas_Object *obj __UNUSED__,
1620 void *event_info __UNUSED__)
1622 Widget_Data *wd = elm_widget_data_get(data);
1625 wd->drag_started = EINA_FALSE;
1629 _mouse_move_scroller(void *data,
1630 Evas *evas __UNUSED__,
1631 Evas_Object *obj __UNUSED__,
1634 Widget_Data *wd = elm_widget_data_get(data);
1635 Evas_Event_Mouse_Move *ev = event_info;
1636 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
1639 if (wd->drag_started) return;
1641 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1642 dx = ev->cur.canvas.x - ev->prev.canvas.x;
1643 dy = ev->cur.canvas.y - ev->prev.canvas.y;
1646 if (adx < 0) adx = -dx;
1647 if (ady < 0) ady = -dy;
1648 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
1652 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
1653 wd->drag_started = EINA_TRUE;
1657 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
1658 wd->drag_started = EINA_TRUE;
1664 _signal_expand_toggle(void *data,
1665 Evas_Object *obj __UNUSED__,
1666 const char *emission __UNUSED__,
1667 const char *source __UNUSED__)
1669 Elm_Gen_Item *it = data;
1671 if (it->item->expanded)
1672 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1674 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1678 _signal_expand(void *data,
1679 Evas_Object *obj __UNUSED__,
1680 const char *emission __UNUSED__,
1681 const char *source __UNUSED__)
1683 Elm_Gen_Item *it = data;
1685 if (!it->item->expanded)
1686 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1690 _signal_contract(void *data,
1691 Evas_Object *obj __UNUSED__,
1692 const char *emission __UNUSED__,
1693 const char *source __UNUSED__)
1695 Elm_Gen_Item *it = data;
1697 if (it->item->expanded)
1698 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1702 _scr_hold_timer_cb(void *data)
1704 if (!data) return ECORE_CALLBACK_CANCEL;
1705 Widget_Data *wd = data;
1706 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1707 wd->scr_hold_timer = NULL;
1708 return ECORE_CALLBACK_CANCEL;
1712 _decorate_item_finished_signal_cb(void *data,
1714 const char *emission __UNUSED__,
1715 const char *source __UNUSED__)
1719 Elm_Gen_Item *it = data;
1720 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1722 Evas *te = evas_object_evas_get(obj);
1724 evas_event_freeze(te);
1725 it->item->nocache_once = EINA_FALSE;
1726 _decorate_item_unrealize(it);
1727 //FIXME: group raise
1729 if (it->item->group_item)
1730 evas_object_raise(it->item->VIEW(group_item));
1732 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1733 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1734 evas_event_thaw(te);
1735 evas_event_thaw_eval(te);
1739 _item_cache_clean(Widget_Data *wd)
1741 evas_event_freeze(evas_object_evas_get(wd->obj));
1742 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1746 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1747 wd->item_cache = eina_inlist_remove(wd->item_cache,
1748 wd->item_cache->last);
1749 wd->item_cache_count--;
1750 if (itc->spacer) evas_object_del(itc->spacer);
1751 if (itc->base_view) evas_object_del(itc->base_view);
1752 eina_stringshare_del(itc->item_style);
1755 evas_event_thaw(evas_object_evas_get(wd->obj));
1756 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1760 _item_cache_zero(Widget_Data *wd)
1762 int pmax = wd->item_cache_max;
1763 wd->item_cache_max = 0;
1764 _item_cache_clean(wd);
1765 wd->item_cache_max = pmax;
1769 _item_cache_add(Elm_Gen_Item *it)
1773 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1774 if (it->wd->item_cache_max <= 0)
1776 evas_object_del(VIEW(it));
1780 evas_object_del(it->spacer);
1783 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1784 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1788 it->wd->item_cache_count++;
1789 itc = calloc(1, sizeof(Item_Cache));
1792 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1793 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1796 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1797 EINA_INLIST_GET(itc));
1798 itc->spacer = it->spacer;
1800 itc->base_view = VIEW(it);
1802 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1803 evas_object_hide(itc->base_view);
1804 evas_object_move(itc->base_view, -9999, -9999);
1805 itc->item_style = eina_stringshare_add(it->itc->item_style);
1806 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1807 itc->selected = it->selected;
1808 itc->disabled = elm_widget_item_disabled_get(it);
1809 itc->expanded = it->item->expanded;
1812 ecore_timer_del(it->long_timer);
1813 it->long_timer = NULL;
1815 if (it->item->swipe_timer)
1817 ecore_timer_del(it->item->swipe_timer);
1818 it->item->swipe_timer = NULL;
1820 // FIXME: other callbacks?
1821 edje_object_signal_callback_del_full(itc->base_view,
1822 "elm,action,expand,toggle",
1823 "elm", _signal_expand_toggle, it);
1824 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1826 _signal_expand, it);
1827 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1828 "elm", _signal_contract, it);
1829 _item_mouse_callbacks_del(it, itc->base_view);
1830 _item_cache_clean(it->wd);
1831 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1832 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1836 _item_cache_find(Elm_Gen_Item *it)
1841 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1842 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1844 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1846 if ((itc->tree == tree) &&
1847 (((!it->itc->item_style) && (!itc->item_style)) ||
1848 (it->itc->item_style && itc->item_style &&
1849 (!strcmp(it->itc->item_style, itc->item_style)))))
1851 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1852 EINA_INLIST_GET(itc));
1853 it->wd->item_cache_count--;
1861 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1863 if (it->position_update || it->item->block->position_update)
1865 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1866 it->position_update = EINA_FALSE;
1871 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1873 if (!it->item->nostacking)
1875 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1877 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1878 else evas_object_lower(VIEW(it));
1882 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1883 else evas_object_raise(VIEW(it));
1887 if (it->item->order_num_in & 0x1)
1889 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1890 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1894 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1895 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1900 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1904 if (it->selected != itc->selected)
1908 edje_object_signal_emit(VIEW(it),
1909 "elm,state,selected", "elm");
1910 if (it->deco_all_view)
1911 edje_object_signal_emit(it->deco_all_view,
1912 "elm,state,selected", "elm");
1915 if (elm_widget_item_disabled_get(it) != itc->disabled)
1917 if (elm_widget_item_disabled_get(it))
1918 edje_object_signal_emit(VIEW(it),
1919 "elm,state,disabled", "elm");
1920 if (it->deco_all_view)
1921 edje_object_signal_emit(it->deco_all_view,
1922 "elm,state,disabled", "elm");
1924 if (it->item->expanded != itc->expanded)
1926 if (it->item->expanded)
1927 edje_object_signal_emit(VIEW(it),
1928 "elm,state,expanded", "elm");
1929 if (it->deco_all_view)
1930 edje_object_signal_emit(it->deco_all_view,
1931 "elm,state,expanded", "elm");
1938 edje_object_signal_emit(VIEW(it),
1939 "elm,state,selected", "elm");
1940 if (it->deco_all_view)
1941 edje_object_signal_emit(it->deco_all_view,
1942 "elm,state,selected", "elm");
1944 if (elm_widget_item_disabled_get(it))
1946 edje_object_signal_emit(VIEW(it),
1947 "elm,state,disabled", "elm");
1948 if (it->deco_all_view)
1949 edje_object_signal_emit(it->deco_all_view,
1950 "elm,state,disabled", "elm");
1952 if (it->item->expanded)
1954 edje_object_signal_emit(VIEW(it),
1955 "elm,state,expanded", "elm");
1956 if (it->deco_all_view)
1957 edje_object_signal_emit(it->deco_all_view,
1958 "elm,state,expanded", "elm");
1964 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1966 Elm_Gen_Item *it = data;
1967 if (it) it->defer_unrealize = EINA_TRUE;
1971 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1973 Elm_Gen_Item *it = data;
1974 if (it) it->defer_unrealize = EINA_FALSE;
1979 _item_mode_content_realize(Elm_Gen_Item *it,
1980 Evas_Object *target,
1983 Eina_List **contents_list)
1985 Eina_List *res = *contents_list;
1987 if (it->itc->func.content_get)
1993 EINA_LIST_FOREACH(*source, l, key)
1995 if (parts && fnmatch(parts, key, FNM_PERIOD))
1998 ic = it->itc->func.content_get
1999 ((void *)it->base.data, WIDGET(it), key);
2003 res = eina_list_append(res, ic);
2004 edje_object_part_swallow(target, key, ic);
2005 evas_object_show(ic);
2006 elm_widget_sub_object_add(WIDGET(it), ic);
2009 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2010 // genlist does not need to handle this focus thing.
2011 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2012 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2014 if (elm_widget_item_disabled_get(it))
2015 elm_widget_disabled_set(ic, EINA_TRUE);
2024 _item_mode_content_unrealize(Elm_Gen_Item *it,
2025 Evas_Object *target,
2028 Eina_List **contents_list)
2030 Eina_List *res = *contents_list;
2032 if (it->itc->func.content_get)
2036 Evas_Object *ic = NULL;
2038 EINA_LIST_FOREACH(*source, l, key)
2040 if (parts && fnmatch(parts, key, FNM_PERIOD))
2043 ic = edje_object_part_swallow_get(target, key);
2046 res = eina_list_remove(res, ic);
2047 edje_object_part_unswallow(target, ic);
2048 evas_object_del(ic);
2057 _item_cache_free(Item_Cache *itc)
2059 if (itc->spacer) evas_object_del(itc->spacer);
2060 if (itc->base_view) evas_object_del(itc->base_view);
2061 eina_stringshare_del(itc->item_style);
2066 _item_text_realize(Elm_Gen_Item *it,
2067 Evas_Object *target,
2071 if (it->itc->func.text_get)
2077 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
2078 EINA_LIST_FOREACH(*source, l, key)
2080 if (parts && fnmatch(parts, key, FNM_PERIOD))
2083 char *s = it->itc->func.text_get
2084 ((void *)it->base.data, WIDGET(it), key);
2088 edje_object_part_text_escaped_set(target, key, s);
2093 edje_object_part_text_set(target, key, "");
2100 _item_content_unrealize(Elm_Gen_Item *it,
2101 Evas_Object *target,
2105 Eina_List *res = it->content_objs;
2107 if (it->itc->func.content_get)
2111 Evas_Object *ic = NULL;
2113 EINA_LIST_FOREACH(*source, l, key)
2115 if (parts && fnmatch(parts, key, FNM_PERIOD))
2118 ic = edje_object_part_swallow_get(target, key);
2121 res = eina_list_remove(res, ic);
2122 edje_object_part_unswallow(target, ic);
2123 evas_object_del(ic);
2132 _item_content_realize(Elm_Gen_Item *it,
2133 Evas_Object *target,
2137 Eina_List *res = it->content_objs;
2139 if (it->itc->func.content_get)
2143 Evas_Object *ic = NULL;
2146 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
2148 EINA_LIST_FOREACH(*source, l, key)
2150 if (parts && fnmatch(parts, key, FNM_PERIOD))
2153 if (it->itc->func.content_get)
2154 ic = it->itc->func.content_get
2155 ((void *)it->base.data, WIDGET(it), key);
2158 res = eina_list_append(res, ic);
2159 edje_object_part_swallow(target, key, ic);
2160 evas_object_show(ic);
2161 elm_widget_sub_object_add(WIDGET(it), ic);
2162 evas_object_event_callback_add(ic,
2163 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2164 _changed_size_hints, it);
2167 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2168 // genlist does not need to handle this focus thing.
2169 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2170 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2173 if (elm_widget_item_disabled_get(it))
2174 elm_widget_disabled_set(ic, EINA_TRUE);
2183 _item_state_realize(Elm_Gen_Item *it,
2184 Evas_Object *target,
2188 if (it->itc->func.state_get)
2195 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2196 EINA_LIST_FOREACH(*source, l, key)
2198 if (parts && fnmatch(parts, key, FNM_PERIOD))
2201 Eina_Bool on = it->itc->func.state_get
2202 ((void *)it->base.data, WIDGET(it), key);
2206 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2207 edje_object_signal_emit(target, buf, "elm");
2211 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2212 edje_object_signal_emit(target, buf, "elm");
2219 _item_order_update(const Eina_Inlist *l, int start)
2221 Elm_Gen_Item *it, *it2;
2223 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next, it = ELM_GEN_ITEM_FROM_INLIST(l))
2225 it->item->order_num_in = start++;
2226 _elm_genlist_item_odd_even_update(it);
2227 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
2228 if (it2 && (it->item->order_num_in != it2->item->order_num_in)) return;
2233 _item_realize(Elm_Gen_Item *it,
2237 const char *treesize;
2240 Item_Cache *itc = NULL;
2242 if (it->generation < it->wd->generation) return;
2243 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2246 if (it->item->order_num_in != in)
2248 _item_order_update(EINA_INLIST_GET(it), in);
2249 _elm_genlist_item_state_update(it, NULL);
2250 _elm_genlist_item_index_update(it);
2252 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2253 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2256 it->item->order_num_in = in;
2258 if ((it->item->nocache_once) && (!it->flipped))
2259 it->item->nocache_once = EINA_FALSE;
2260 else if (!it->item->nocache)
2261 itc = _item_cache_find(it);
2262 if (itc && (!it->wd->tree_effect_enabled))
2264 VIEW(it) = itc->base_view;
2265 itc->base_view = NULL;
2266 it->spacer = itc->spacer;
2271 const char *stacking_even;
2272 const char *stacking;
2274 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2275 edje_object_scale_set(VIEW(it),
2276 elm_widget_scale_get(WIDGET(it)) *
2277 _elm_config->scale);
2278 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2279 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2281 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2282 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2284 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2286 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2287 elm_widget_style_get(WIDGET(it)));
2289 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2290 if (!stacking_even) stacking_even = "above";
2291 it->item->stacking_even = !!strcmp("above", stacking_even);
2293 stacking = edje_object_data_get(VIEW(it), "stacking");
2294 if (!stacking) stacking = "yes";
2295 it->item->nostacking = !!strcmp("yes", stacking);
2297 edje_object_mirrored_set(VIEW(it),
2298 elm_widget_mirrored_get(WIDGET(it)));
2301 _item_order_update(EINA_INLIST_GET(it), in);
2303 if (!(it->deco_all_view) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2305 if (it->wd->reorder_mode)
2306 edje_object_signal_emit(VIEW(it), "elm,state,reorder,mode_set", "elm");
2308 edje_object_signal_emit(VIEW(it), "elm,state,reorder,mode_unset", "elm");
2311 treesize = edje_object_data_get(VIEW(it), "treesize");
2312 if (treesize) tsize = atoi(treesize);
2313 if (!it->spacer && treesize)
2316 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2317 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2318 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2322 evas_object_size_hint_min_set(it->spacer,
2323 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2324 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2328 edje_object_signal_callback_add(VIEW(it),
2329 "elm,action,expand,toggle",
2330 "elm", _signal_expand_toggle, it);
2331 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2332 "elm", _signal_expand, it);
2333 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2334 "elm", _signal_contract, it);
2335 _item_mouse_callbacks_add(it, VIEW(it));
2337 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2338 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2339 _decorate_all_item_realize(it, EINA_FALSE);
2341 _elm_genlist_item_state_update(it, itc);
2342 _elm_genlist_item_index_update(it);
2345 if ((calc) && (it->wd->homogeneous) &&
2346 ((it->wd->item_width) ||
2347 ((it->wd->item_width) && (it->wd->group_item_width))))
2349 /* homogenous genlist shortcut */
2350 if (!it->item->mincalcd)
2354 it->item->w = it->item->minw = it->wd->group_item_width;
2355 it->item->h = it->item->minh = it->wd->group_item_height;
2359 it->item->w = it->item->minw = it->wd->item_width;
2360 it->item->h = it->item->minh = it->wd->item_height;
2362 it->item->mincalcd = EINA_TRUE;
2367 /* FIXME: If you see that assert, please notify us and we
2368 will clean our mess */
2369 assert(eina_list_count(it->content_objs) == 0);
2371 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2372 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2373 _item_state_realize(it, VIEW(it), &it->states, NULL);
2376 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2377 if (!(it->item->flip_contents))
2378 it->item->flip_contents =
2379 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2380 it->item->flip_content_objs =
2381 _item_mode_content_realize(it, VIEW(it),
2382 &it->item->flip_contents, NULL,
2383 &it->item->flip_content_objs);
2386 if (!it->item->mincalcd || ((it->wd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
2388 Evas_Coord mw = -1, mh = -1;
2390 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2391 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2392 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2393 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2395 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2396 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2397 it->item->w = it->item->minw = mw;
2398 it->item->h = it->item->minh = mh;
2399 it->item->mincalcd = EINA_TRUE;
2401 if ((!it->wd->group_item_width) && (it->group))
2403 it->wd->group_item_width = mw;
2404 it->wd->group_item_height = mh;
2406 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2408 it->wd->item_width = mw;
2409 it->wd->item_height = mh;
2412 if (!calc) evas_object_show(VIEW(it));
2415 if (it->tooltip.content_cb)
2417 elm_widget_item_tooltip_content_cb_set(it,
2418 it->tooltip.content_cb,
2419 it->tooltip.data, NULL);
2420 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2421 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2424 if (it->mouse_cursor)
2425 elm_widget_item_cursor_set(it, it->mouse_cursor);
2427 it->realized = EINA_TRUE;
2428 it->want_unrealize = EINA_FALSE;
2430 if (itc) _item_cache_free(itc);
2431 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2432 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2435 if (it->item->tree_effect_hideme)
2437 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2438 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2439 it->item->tree_effect_hideme = EINA_FALSE;
2441 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2444 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2446 if (it->itc->decorate_all_item_style)
2448 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2449 edje_object_message_signal_process(it->deco_all_view);
2452 edje_object_message_signal_process(VIEW(it));
2456 _item_unrealize_cb(Elm_Gen_Item *it)
2458 Evas_Object *content;
2459 elm_widget_stringlist_free(it->item->flip_contents);
2460 it->item->flip_contents = NULL;
2461 EINA_LIST_FREE(it->item->flip_content_objs, content)
2462 evas_object_del(content);
2464 // unswallow VIEW(it) first then manipulate VIEW(it)
2465 _decorate_item_unrealize(it);
2466 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2468 if (it->item->nocache_once || it->item->nocache)
2470 evas_object_del(VIEW(it));
2474 evas_object_del(it->spacer);
2480 edje_object_mirrored_set(VIEW(it),
2481 elm_widget_mirrored_get(WIDGET(it)));
2482 edje_object_scale_set(VIEW(it),
2483 elm_widget_scale_get(WIDGET(it))
2484 * _elm_config->scale);
2485 _item_cache_add(it);
2489 it->realized = EINA_FALSE;
2490 it->want_unrealize = EINA_FALSE;
2494 _item_block_recalc(Item_Block *itb,
2500 Evas_Coord minw = 0, minh = 0;
2501 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2504 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2506 EINA_LIST_FOREACH(itb->items, l, it)
2508 if (it->generation < it->wd->generation) continue;
2509 showme |= it->item->showme;
2514 if (!it->item->mincalcd) changed = EINA_TRUE;
2517 _item_realize(it, in, EINA_TRUE);
2518 _elm_genlist_item_unrealize(it, EINA_TRUE);
2523 if ((itb->wd->homogeneous) &&
2524 (itb->wd->mode == ELM_LIST_COMPRESS))
2528 it->item->w = it->item->minw = it->wd->group_item_width;
2529 it->item->h = it->item->minh = it->wd->group_item_height;
2533 it->item->w = it->item->minw = it->wd->item_width;
2534 it->item->h = it->item->minh = it->wd->item_height;
2539 _item_realize(it, in, EINA_TRUE);
2540 _elm_genlist_item_unrealize(it, EINA_TRUE);
2546 if (!it->item->mincalcd) changed = EINA_TRUE;
2547 _item_realize(it, in, EINA_FALSE);
2549 minh += it->item->minh;
2550 if (minw < it->item->minw) minw = it->item->minw;
2556 if (changed) itb->wd->pan_changed = changed;
2559 itb->changed = EINA_FALSE;
2560 itb->position_update = 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));
2567 _item_block_realize(Item_Block *itb)
2569 if (itb->realized) return;
2570 itb->realized = EINA_TRUE;
2571 itb->want_unrealize = EINA_FALSE;
2575 _item_block_unrealize(Item_Block *itb)
2579 Eina_Bool dragging = EINA_FALSE;
2581 if (!itb->realized) return;
2582 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2583 EINA_LIST_FOREACH(itb->items, l, it)
2585 if (itb->must_recalc || !it->group)
2589 dragging = EINA_TRUE;
2590 it->want_unrealize = EINA_TRUE;
2593 _elm_genlist_item_unrealize(it, EINA_FALSE);
2598 itb->realized = EINA_FALSE;
2599 itb->want_unrealize = EINA_TRUE;
2602 itb->want_unrealize = EINA_FALSE;
2603 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2604 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2608 _get_space_for_reorder_item(Elm_Gen_Item *it)
2610 Evas_Coord rox, roy, row, roh, oy, oh;
2611 Eina_Bool top = EINA_FALSE;
2612 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2613 if (!reorder_it) return 0;
2615 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2616 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2618 if ((it->wd->reorder_start_y < it->item->block->y) &&
2619 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2621 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2622 if (it->item->block->count == 1)
2623 it->wd->reorder_rel = it;
2625 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2626 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2628 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2631 it->item->block->reorder_offset = 0;
2633 it->item->scrl_y += it->item->block->reorder_offset;
2635 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2636 rox, roy + (roh / 2), row, 1));
2639 it->wd->reorder_rel = it;
2640 it->item->scrl_y += it->wd->reorder_it->item->h;
2641 return it->wd->reorder_it->item->h;
2648 _reorder_move_animator_cb(void *data)
2650 Elm_Gen_Item *it = data;
2651 Eina_Bool down = EINA_FALSE;
2653 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2655 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2657 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2660 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2661 if (diff < dy) y = diff;
2662 else if (diff > it->item->h) y = diff / 2;
2664 if (it->item->old_scrl_y < it->item->scrl_y)
2666 it->item->old_scrl_y += y;
2669 else if (it->item->old_scrl_y > it->item->scrl_y)
2671 it->item->old_scrl_y -= y;
2675 if (it->deco_all_view)
2676 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2678 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2679 //FIXME : group raise
2681 _group_items_recalc(it->wd);
2684 if ((it->wd->reorder_pan_move) ||
2685 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2686 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2688 it->item->old_scrl_y = it->item->scrl_y;
2689 it->item->move_effect_enabled = EINA_FALSE;
2690 it->wd->reorder_move_animator = NULL;
2691 return ECORE_CALLBACK_CANCEL;
2693 return ECORE_CALLBACK_RENEW;
2697 _item_position(Elm_Gen_Item *it,
2705 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2706 evas_object_resize(view, it->item->w, it->item->h);
2707 evas_object_move(view, it_x, it_y);
2708 evas_object_show(view);
2709 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2710 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2714 _item_block_position(Item_Block *itb,
2719 //FIXME : group raise
2723 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2724 Eina_Bool vis = EINA_FALSE;
2725 Evas_Coord minh = 0;
2727 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2728 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2729 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2731 EINA_LIST_FOREACH(itb->items, l, it)
2733 if (it->generation < it->wd->generation) continue;
2734 else if (it->wd->reorder_it == it) continue;
2737 it->item->w = itb->w;
2738 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2739 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2741 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2742 cvx, cvy, cvw, cvh));
2743 //FIXME : group raise
2748 if ((itb->realized) && (!it->realized))
2750 if (vis) _item_realize(it, in, EINA_FALSE);
2754 if (vis || it->dragging)
2756 if (it->wd->reorder_mode)
2757 y += _get_space_for_reorder_item(it);
2758 //FIXME : group raise
2760 git = it->item->group_item;
2763 if (git->item->scrl_y < oy)
2764 git->item->scrl_y = oy;
2765 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2766 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2767 git->item->want_realize = EINA_TRUE;
2770 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2772 if (!it->item->move_effect_enabled)
2774 it->item->move_effect_enabled = EINA_TRUE;
2775 it->wd->reorder_move_animator =
2777 _reorder_move_animator_cb, it);
2780 if (!it->item->move_effect_enabled)
2782 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2783 _decorate_all_item_position(it, it->item->scrl_x,
2787 if (!it->wd->tree_effect_enabled ||
2788 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2789 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2790 (it->item->old_scrl_y == it->item->scrl_y)))
2792 if (it->item->deco_it_view)
2793 _item_position(it, it->item->deco_it_view,
2797 _item_position(it, VIEW(it), it->item->scrl_x,
2801 it->item->old_scrl_y = it->item->scrl_y;
2806 if (!it->wd->tree_effect_animator)
2808 it->want_unrealize = EINA_TRUE;
2809 _elm_genlist_item_unrealize(it, EINA_FALSE);
2815 //FIXME : group raise
2819 if (vis) it->item->want_realize = EINA_TRUE;
2823 minh += it->item->minh;
2825 if (!itb->wd->reorder_it) itb->minh = minh;
2826 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2827 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2830 //FIXME: group raise
2833 _group_items_recalc(void *data)
2835 Widget_Data *wd = data;
2839 evas_event_freeze(evas_object_evas_get(wd->obj));
2840 EINA_LIST_FOREACH(wd->group_items, l, git)
2842 if (git->item->want_realize)
2845 _item_realize(git, 0, EINA_FALSE);
2846 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2847 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2848 evas_object_show(VIEW(git));
2849 evas_object_raise(VIEW(git));
2851 else if (!git->item->want_realize && git->realized)
2854 _elm_genlist_item_unrealize(git, EINA_FALSE);
2857 evas_event_thaw(evas_object_evas_get(wd->obj));
2858 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2863 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2865 Elm_Gen_Item *it = data;
2867 if (it->want_unrealize) return;
2868 it->item->mincalcd = EINA_FALSE;
2869 it->item->block->changeme = EINA_TRUE;
2870 if (it->wd->changed_job) ecore_job_del(it->wd->changed_job);
2871 it->wd->changed_job = ecore_job_add(_changed_job, it->wd);
2875 _must_recalc_idler(void *data)
2877 Widget_Data *wd = data;
2878 if (wd->calc_job) ecore_job_del(wd->calc_job);
2879 wd->calc_job = ecore_job_add(_calc_job, wd);
2880 wd->must_recalc_idler = NULL;
2881 return ECORE_CALLBACK_CANCEL;
2885 _scroll_item(Widget_Data *wd)
2887 Elm_Gen_Item *it = NULL;
2888 //FIXME: group raise
2890 Evas_Coord gith = 0;
2892 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2893 if (!wd->show_item) return;
2895 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2897 dx = it->x + it->item->block->x;
2898 dy = it->y + it->item->block->y;
2899 dw = it->item->block->w;
2901 switch (wd->scrollto_type)
2903 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2904 //FIXME: group raise
2906 if (it->item->group_item) gith = it->item->group_item->item->h;
2910 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2911 dy += ((it->item->h / 2) - (oh / 2));
2913 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2915 if ((wd->expanded_item) &&
2916 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2917 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2919 it = wd->expanded_item;
2920 dx = it->x + it->item->block->x;
2921 dy = it->y + it->item->block->y;
2922 //FIXME: group raise
2924 if (it->item->group_item) gith = it->item->group_item->item->h;
2925 dx = it->x + it->item->block->x;
2926 dy = it->y + it->item->block->y - gith;
2928 dw = it->item->block->w;
2932 //FIXME: group raise
2934 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2935 gith = it->item->group_item->item->h;
2943 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2945 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2947 it->item->showme = EINA_FALSE;
2948 wd->show_item = NULL;
2949 wd->auto_scroll_enabled = EINA_FALSE;
2950 wd->check_scroll = EINA_FALSE;
2954 _calc_job(void *data)
2956 Widget_Data *wd = data;
2957 Item_Block *itb, *chb = NULL;
2958 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2959 Evas_Coord pan_w = 0, pan_h = 0;
2961 Eina_Bool minw_change = EINA_FALSE;
2962 Eina_Bool did_must_recalc = EINA_FALSE;
2965 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2966 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2971 evas_event_freeze(evas_object_evas_get(wd->obj));
2972 EINA_INLIST_FOREACH(wd->blocks, itb)
2974 Eina_Bool showme = EINA_FALSE;
2977 showme = itb->showme;
2978 itb->showme = EINA_FALSE;
2981 if (itb->realized) _item_block_unrealize(itb);
2983 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2985 if (itb->must_recalc)
2989 EINA_LIST_FOREACH(itb->items, l, it)
2990 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2991 itb->changed = EINA_TRUE;
2992 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2993 if (itb->realized) _item_block_unrealize(itb);
2994 itb->must_recalc = EINA_FALSE;
2996 showme = _item_block_recalc(itb, in, EINA_FALSE);
3002 if (minw == -1) minw = itb->minw;
3003 else if ((!itb->must_recalc) && (minw < itb->minw))
3006 minw_change = EINA_TRUE;
3011 minw_change = EINA_TRUE;
3017 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
3018 wd->check_scroll = EINA_TRUE;
3022 EINA_INLIST_FOREACH(wd->blocks, itb)
3028 if ((chb) && (EINA_INLIST_GET(chb)->next))
3030 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
3032 if (itb->realized) _item_block_unrealize(itb);
3035 wd->realminw = minw;
3036 if (minw < wd->w) minw = wd->w;
3037 if ((minw != wd->minw) || (minh != wd->minh))
3041 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3042 _sizing_eval(wd->obj);
3043 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
3048 it = wd->anchor_item;
3049 it_y = wd->anchor_y;
3050 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
3051 it->item->block->y + it->y + it_y);
3052 wd->anchor_item = it;
3053 wd->anchor_y = it_y;
3056 if (did_must_recalc)
3058 if (!wd->must_recalc_idler)
3059 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
3061 if (wd->check_scroll)
3063 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
3064 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
3065 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3066 switch (wd->scrollto_type)
3068 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
3071 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
3074 case ELM_GENLIST_ITEM_SCROLLTO_IN:
3079 if ((wd->show_item) && (wd->show_item->item->block))
3081 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
3082 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
3088 wd->calc_job = NULL;
3089 evas_object_smart_changed(wd->pan_smart);
3090 evas_event_thaw(evas_object_evas_get(wd->obj));
3091 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3095 _update_job(void *data)
3097 Widget_Data *wd = data;
3101 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
3103 wd->update_job = NULL;
3106 evas_event_freeze(evas_object_evas_get(wd->obj));
3107 EINA_INLIST_FOREACH(wd->blocks, itb)
3109 Evas_Coord itminw, itminh;
3116 _item_block_position(itb, num);
3120 recalc = EINA_FALSE;
3121 EINA_LIST_FOREACH(itb->items, l2, it)
3123 if (it->item->updateme)
3125 itminw = it->item->minw;
3126 itminh = it->item->minh;
3130 _elm_genlist_item_unrealize(it, EINA_FALSE);
3131 _item_realize(it, num, EINA_FALSE);
3132 position = EINA_TRUE;
3136 _item_realize(it, num, EINA_TRUE);
3137 _elm_genlist_item_unrealize(it, EINA_TRUE);
3139 if ((it->item->minw != itminw) || (it->item->minh != itminh))
3141 it->item->updateme = EINA_FALSE;
3145 itb->updateme = EINA_FALSE;
3148 position = EINA_TRUE;
3149 itb->changed = EINA_TRUE;
3150 _item_block_recalc(itb, num0, EINA_FALSE);
3151 _item_block_position(itb, num0);
3156 if (wd->calc_job) ecore_job_del(wd->calc_job);
3157 wd->calc_job = ecore_job_add(_calc_job, wd);
3159 evas_event_thaw(evas_object_evas_get(wd->obj));
3160 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3164 _changed_job(void *data)
3166 Widget_Data *wd = data; Eina_List *l2;
3168 int num, num0, position = 0;
3169 Eina_Bool width_changed = EINA_FALSE, height_changed = EINA_FALSE;
3171 wd->changed_job = NULL;
3173 EINA_INLIST_FOREACH(wd->blocks, itb)
3175 Evas_Coord itminw, itminh;
3182 _item_block_position(itb, num);
3186 width_changed = height_changed = EINA_FALSE;
3187 EINA_LIST_FOREACH(itb->items, l2, it)
3189 if ((!it->item->mincalcd) && (it->realized))
3191 Evas_Coord mw = -1, mh = -1;
3192 itminw = it->item->minw;
3193 itminh = it->item->minh;
3195 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->w;
3196 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3197 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3198 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
3199 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
3200 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3201 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3203 width_changed = EINA_TRUE;
3206 it->item->w = it->item->minw = mw;
3207 it->item->h = it->item->minh = mh;
3208 it->item->mincalcd = EINA_TRUE;
3210 //if ((it->item->minw != itminw) || (it->item->minh != itminh))
3211 //if ((it->item->minh != itminh))
3213 if ((it->item->minw != itminw))
3214 width_changed = EINA_TRUE;
3215 if ((it->item->minh != itminh))
3216 height_changed = EINA_TRUE;
3218 if ((!it->wd->group_item_width) && (it->group))
3220 it->wd->group_item_width = mw;
3221 it->wd->group_item_height = mh;
3223 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
3225 it->wd->item_width = mw;
3226 it->wd->item_height = mh;
3231 itb->changeme = EINA_FALSE;
3232 // TODO: why this is separated.
3236 itb->changed = EINA_TRUE;
3237 _item_block_recalc(itb, num0, 0);
3238 _item_block_position(itb, num0);
3240 else if (width_changed)
3242 _item_block_position(itb, num0);
3247 if (wd->calc_job) ecore_job_del(wd->calc_job);
3248 wd->calc_job = ecore_job_add(_calc_job, wd);
3253 _viewport_coord_get(Widget_Data *wd,
3259 Evas_Coord x, y, w, h;
3260 EINA_SAFETY_ON_NULL_RETURN(wd);
3262 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
3263 elm_smart_scroller_child_viewport_size_get(wd->scr, &w, &h);
3265 if (w > wd->minw) x -= ((w - wd->minw) / 2);
3266 if (h > wd->minh) y -= ((h - wd->minh) / 2);
3275 _pan_set(Evas_Object *obj,
3279 Pan *sd = evas_object_smart_data_get(obj);
3283 // Evas_Coord ow, oh;
3284 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3285 // ow = sd->wd->minw - ow;
3286 // if (ow < 0) ow = 0;
3287 // oh = sd->wd->minh - oh;
3288 // if (oh < 0) oh = 0;
3289 // if (x < 0) x = 0;
3290 // if (y < 0) y = 0;
3291 // if (x > ow) x = ow;
3292 // if (y > oh) y = oh;
3293 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
3297 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3299 if ((itb->y + itb->h) > y)
3304 EINA_LIST_FOREACH(itb->items, l2, it)
3306 if ((itb->y + it->y) >= y)
3308 sd->wd->anchor_item = it;
3309 sd->wd->anchor_y = -(itb->y + it->y - y);
3316 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
3320 _pan_get(Evas_Object *obj,
3324 Pan *sd = evas_object_smart_data_get(obj);
3327 if (x) *x = sd->wd->pan_x;
3328 if (y) *y = sd->wd->pan_y;
3332 _pan_max_get(Evas_Object *obj,
3336 Pan *sd = evas_object_smart_data_get(obj);
3340 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3341 ow = sd->wd->minw - ow;
3343 oh = sd->wd->minh - oh;
3350 _pan_min_get(Evas_Object *obj __UNUSED__,
3359 _pan_child_size_get(Evas_Object *obj,
3363 Pan *sd = evas_object_smart_data_get(obj);
3366 if (w) *w = sd->wd->minw;
3367 if (h) *h = sd->wd->minh;
3371 _pan_add(Evas_Object *obj)
3374 Evas_Object_Smart_Clipped_Data *cd;
3377 cd = evas_object_smart_data_get(obj);
3380 sd->__clipped_data = *cd;
3382 evas_object_smart_data_set(obj, sd);
3386 _pan_del(Evas_Object *obj)
3388 Pan *sd = evas_object_smart_data_get(obj);
3393 ecore_job_del(sd->resize_job);
3394 sd->resize_job = NULL;
3400 _pan_resize_job(void *data)
3404 _sizing_eval(sd->wd->obj);
3405 sd->resize_job = NULL;
3409 _pan_resize(Evas_Object *obj,
3413 Pan *sd = evas_object_smart_data_get(obj);
3417 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3418 if ((ow == w) && (oh == h)) return;
3419 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3422 if (sd->resize_job) ecore_job_del(sd->resize_job);
3423 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3425 sd->wd->pan_changed = EINA_TRUE;
3426 evas_object_smart_changed(obj);
3427 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3428 sd->wd->calc_job = NULL;
3432 _pan_calculate(Evas_Object *obj)
3434 Pan *sd = evas_object_smart_data_get(obj);
3436 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3438 //FIXME: group raise
3445 evas_event_freeze(evas_object_evas_get(obj));
3447 if (sd->wd->pan_changed)
3450 sd->wd->pan_changed = EINA_FALSE;
3453 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3454 sd->wd->prev_viewport_w = ow;
3455 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3456 //FIXME: group raise
3458 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3460 git->item->want_realize = EINA_FALSE;
3464 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3466 if (!sd->wd->tree_effect_animator)
3468 _item_tree_effect_before(sd->wd->expanded_item);
3469 evas_object_raise(sd->wd->alpha_bg);
3470 evas_object_show(sd->wd->alpha_bg);
3471 sd->wd->start_time = ecore_time_get();
3472 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3476 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3478 itb->w = sd->wd->minw;
3479 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3480 itb->y - sd->wd->pan_y + oy,
3482 cvx, cvy, cvw, cvh))
3484 if ((!itb->realized) || (itb->changed))
3486 _item_block_realize(itb);
3488 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3489 sd->wd->calc_job = NULL;
3492 _item_block_position(itb, in);
3496 if (itb->realized) _item_block_unrealize(itb);
3500 //FIXME: group raise
3502 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3503 _group_items_recalc(sd->wd);
3505 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3507 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3508 sd->wd->reorder_pan_move = EINA_TRUE;
3509 else sd->wd->reorder_pan_move = EINA_FALSE;
3510 evas_object_raise(sd->wd->VIEW(reorder_it));
3511 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3512 sd->wd->start_time = ecore_loop_time_get();
3515 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3516 _item_auto_scroll(sd->wd);
3518 Evas_Coord vx, vy, vw, vh;
3519 _viewport_coord_get(sd->wd, &vx, &vy, &vw, &vh);
3521 if (sd->wd->reorder_fast == 1)
3522 elm_smart_scroller_child_region_show(sd->wd->scr, vx, vy - 10, vw, vh);
3523 else if (sd->wd->reorder_fast == -1)
3524 elm_smart_scroller_child_region_show(sd->wd->scr, vx, vy + 10, vw, vh);
3526 evas_event_thaw(evas_object_evas_get(obj));
3527 evas_event_thaw_eval(evas_object_evas_get(obj));
3531 _pan_move(Evas_Object *obj,
3532 Evas_Coord x __UNUSED__,
3533 Evas_Coord y __UNUSED__)
3535 Pan *sd = evas_object_smart_data_get(obj);
3539 sd->wd->pan_changed = EINA_TRUE;
3540 evas_object_smart_changed(obj);
3541 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3542 sd->wd->calc_job = NULL;
3546 _hold_on(void *data __UNUSED__,
3548 void *event_info __UNUSED__)
3550 Widget_Data *wd = elm_widget_data_get(obj);
3552 elm_smart_scroller_hold_set(wd->scr, 1);
3556 _hold_off(void *data __UNUSED__,
3558 void *event_info __UNUSED__)
3560 Widget_Data *wd = elm_widget_data_get(obj);
3562 elm_smart_scroller_hold_set(wd->scr, 0);
3566 _freeze_on(void *data __UNUSED__,
3568 void *event_info __UNUSED__)
3570 Widget_Data *wd = elm_widget_data_get(obj);
3572 elm_smart_scroller_freeze_set(wd->scr, 1);
3576 _freeze_off(void *data __UNUSED__,
3578 void *event_info __UNUSED__)
3580 Widget_Data *wd = elm_widget_data_get(obj);
3582 elm_smart_scroller_freeze_set(wd->scr, 0);
3586 _scr_anim_start(void *data,
3587 Evas_Object *obj __UNUSED__,
3588 void *event_info __UNUSED__)
3590 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3594 _scr_anim_stop(void *data,
3595 Evas_Object *obj __UNUSED__,
3596 void *event_info __UNUSED__)
3598 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3602 _scr_drag_start(void *data,
3603 Evas_Object *obj __UNUSED__,
3604 void *event_info __UNUSED__)
3606 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3610 _scr_drag_stop(void *data,
3611 Evas_Object *obj __UNUSED__,
3612 void *event_info __UNUSED__)
3614 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3618 _edge_left(void *data,
3619 Evas_Object *scr __UNUSED__,
3620 void *event_info __UNUSED__)
3622 Evas_Object *obj = data;
3623 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3627 _edge_right(void *data,
3628 Evas_Object *scr __UNUSED__,
3629 void *event_info __UNUSED__)
3631 Evas_Object *obj = data;
3632 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3636 _edge_top(void *data,
3637 Evas_Object *scr __UNUSED__,
3638 void *event_info __UNUSED__)
3640 Evas_Object *obj = data;
3641 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3645 _edge_bottom(void *data,
3646 Evas_Object *scr __UNUSED__,
3647 void *event_info __UNUSED__)
3649 Evas_Object *obj = data;
3650 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3654 _decorate_item_realize(Elm_Gen_Item *it)
3658 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3660 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3661 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3662 edje_object_scale_set(it->item->deco_it_view,
3663 elm_widget_scale_get(WIDGET(it)) *
3664 _elm_config->scale);
3665 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3666 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3668 strncpy(buf, "item", sizeof(buf));
3669 if (it->wd->mode == ELM_LIST_COMPRESS)
3670 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3672 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3673 strncat(buf, "/", sizeof(buf) - strlen(buf));
3674 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3676 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3677 elm_widget_style_get(WIDGET(it)));
3678 edje_object_mirrored_set(it->item->deco_it_view,
3679 elm_widget_mirrored_get(WIDGET(it)));
3681 /* signal callback add */
3682 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3684 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3686 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3689 /* text_get, content_get, state_get */
3690 /* FIXME: If you see that assert, please notify us and we
3691 will clean our mess */
3692 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3694 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3695 if (!it->item->deco_it_contents)
3696 it->item->deco_it_contents =
3697 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3698 it->item->deco_it_content_objs =
3699 _item_mode_content_realize(it, it->item->deco_it_view,
3700 &it->item->deco_it_contents, NULL,
3701 &it->item->deco_it_content_objs);
3702 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3703 edje_object_part_swallow(it->item->deco_it_view,
3704 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3707 it->want_unrealize = EINA_FALSE;
3708 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3709 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3713 _decorate_item_unrealize(Elm_Gen_Item *it)
3715 Widget_Data *wd = it->wd;
3716 Evas_Object *content;
3717 if (!it->item->deco_it_view) return;
3719 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3720 elm_widget_stringlist_free(it->item->deco_it_texts);
3721 it->item->deco_it_texts = NULL;
3722 elm_widget_stringlist_free(it->item->deco_it_contents);
3723 it->item->deco_it_contents = NULL;
3724 elm_widget_stringlist_free(it->item->deco_it_states);
3726 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3727 evas_object_del(content);
3729 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3730 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3731 evas_object_del(it->item->deco_it_view);
3732 it->item->deco_it_view = NULL;
3734 if (wd->mode_item == it)
3735 wd->mode_item = NULL;
3736 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3737 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3741 _decorate_item_set(Elm_Gen_Item *it)
3744 Widget_Data *wd = it->wd;
3749 it->item->nocache_once = EINA_TRUE;
3751 if (wd->scr_hold_timer)
3753 ecore_timer_del(wd->scr_hold_timer);
3754 wd->scr_hold_timer = NULL;
3756 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3757 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3759 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3760 _decorate_item_realize(it);
3761 if (it->item->group_item)
3762 evas_object_raise(it->item->VIEW(group_item));
3763 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3764 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3765 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3767 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3768 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3772 _decorate_item_unset(Widget_Data *wd)
3775 if (!wd->mode_item) return;
3776 char buf[1024], buf2[1024];
3780 it->item->nocache_once = EINA_TRUE;
3782 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3783 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3785 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3786 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3788 wd->mode_item = NULL;
3792 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3794 if ((!it) || (!it->wd->decorate_all_mode)) return;
3795 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3796 evas_object_move(it->deco_all_view, itx, ity);
3800 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3803 const char *stacking_even;
3804 const char *stacking;
3806 if ((!it) || (it->item->decorate_all_item_realized) ||
3807 (it->generation < it->wd->generation))
3810 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3811 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3812 _elm_config->scale);
3813 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3814 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3816 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3817 strncpy(buf, "tree", sizeof(buf));
3818 else strncpy(buf, "item", sizeof(buf));
3819 if (it->wd->mode == ELM_LIST_COMPRESS)
3820 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3822 strncat(buf, "/", sizeof(buf) - strlen(buf));
3823 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3825 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3826 elm_widget_style_get(WIDGET(it)));
3828 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3829 if (!stacking_even) stacking_even = "above";
3830 it->item->stacking_even = !!strcmp("above", stacking_even);
3832 stacking = edje_object_data_get(VIEW(it), "stacking");
3833 if (!stacking) stacking = "yes";
3834 it->item->nostacking = !!strcmp("yes", stacking);
3836 edje_object_mirrored_set(it->deco_all_view,
3837 elm_widget_mirrored_get(WIDGET(it)));
3839 _elm_genlist_item_odd_even_update(it);
3840 _elm_genlist_item_state_update(it, NULL);
3842 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3843 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3845 if (it->wd->reorder_mode)
3847 edje_object_signal_emit(VIEW(it), "elm,state,reorder,mode_unset", "elm");
3848 edje_object_signal_emit(it->deco_all_view, "elm,state,reorder,mode_set", "elm");
3851 edje_object_signal_emit(it->deco_all_view, "elm,state,reorder,mode_unset", "elm");
3853 _item_mouse_callbacks_del(it, VIEW(it));
3854 _item_mouse_callbacks_add(it, it->deco_all_view);
3856 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3857 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3858 if (!it->item->deco_all_contents)
3859 it->item->deco_all_contents =
3860 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "decorate_contents"));
3861 it->item->deco_all_content_objs =
3862 _item_mode_content_realize(it, it->deco_all_view,
3863 &it->item->deco_all_contents, NULL,
3864 &it->item->deco_all_content_objs);
3865 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3866 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3868 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3869 evas_object_show(it->deco_all_view);
3871 if (it->selected) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
3873 it->item->decorate_all_item_realized = EINA_TRUE;
3874 it->want_unrealize = EINA_FALSE;
3878 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3881 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3883 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3884 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3885 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3886 _elm_genlist_item_odd_even_update(it);
3887 _elm_genlist_item_state_update(it, NULL);
3889 evas_object_del(it->deco_all_view);
3890 it->deco_all_view = NULL;
3891 elm_widget_stringlist_free(it->item->deco_all_texts);
3892 it->item->deco_all_texts = NULL;
3893 elm_widget_stringlist_free(it->item->deco_all_contents);
3894 it->item->deco_all_contents = NULL;
3895 elm_widget_stringlist_free(it->item->deco_all_states);
3896 it->item->deco_all_states = NULL;
3897 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3898 evas_object_del(icon);
3899 edje_object_message_signal_process(it->deco_all_view);
3900 _item_mouse_callbacks_del(it, it->deco_all_view);
3901 _item_mouse_callbacks_add(it, VIEW(it));
3903 it->item->decorate_all_item_realized = EINA_FALSE;
3907 _item_auto_scroll(Widget_Data *wd)
3910 Elm_Gen_Item *tmp_item = NULL;
3912 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3914 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3915 if (!tmp_item) return;
3916 wd->show_item = tmp_item;
3917 wd->bring_in = EINA_TRUE;
3918 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3919 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3921 wd->show_item->item->showme = EINA_TRUE;
3922 wd->auto_scroll_enabled = EINA_FALSE;
3930 elm_genlist_add(Evas_Object *parent)
3935 Evas_Coord minw, minh;
3936 static Evas_Smart *smart = NULL;
3940 static Evas_Smart_Class sc;
3942 evas_object_smart_clipped_smart_set(&_pan_sc);
3944 sc.name = "elm_genlist_pan";
3945 sc.version = EVAS_SMART_CLASS_VERSION;
3948 sc.resize = _pan_resize;
3949 sc.move = _pan_move;
3950 sc.calculate = _pan_calculate;
3951 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3954 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3956 ELM_SET_WIDTYPE(widtype, "genlist");
3958 elm_widget_type_set(obj, "genlist");
3959 elm_widget_sub_object_add(parent, obj);
3960 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3961 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3962 elm_widget_data_set(obj, wd);
3963 elm_widget_del_hook_set(obj, _del_hook);
3964 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3965 elm_widget_theme_hook_set(obj, _theme_hook);
3966 elm_widget_can_focus_set(obj, EINA_TRUE);
3967 elm_widget_event_hook_set(obj, _event_hook);
3968 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3969 elm_widget_translate_hook_set(obj, _translate_hook);
3972 wd->scr = elm_smart_scroller_add(e);
3973 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_DOWN,
3974 _mouse_down_scroller, obj);
3975 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_UP,
3976 _mouse_up_scroller, obj);
3977 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_MOVE,
3978 _mouse_move_scroller, obj);
3979 elm_smart_scroller_widget_set(wd->scr, obj);
3980 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3981 elm_widget_style_get(obj));
3982 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3983 _elm_config->thumbscroll_bounce_enable);
3984 elm_widget_resize_object_set(obj, wd->scr);
3986 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3987 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3988 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3989 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3990 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3991 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3992 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3993 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3996 wd->mode = ELM_LIST_SCROLL;
3997 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3998 wd->item_cache_max = wd->max_items_per_block * 2;
3999 wd->longpress_timeout = _elm_config->longpress_timeout;
4000 wd->highlight = EINA_TRUE;
4001 wd->tree_effect_enabled = _elm_config->effect_enable;
4003 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
4004 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
4005 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
4006 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
4008 wd->pan_smart = evas_object_smart_add(e, smart);
4009 wd->pan = evas_object_smart_data_get(wd->pan_smart);
4012 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
4013 _pan_set, _pan_get, _pan_max_get,
4014 _pan_min_get, _pan_child_size_get);
4016 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
4018 evas_object_size_hint_min_set(obj, minw, minh);
4020 evas_object_smart_callbacks_descriptions_set(obj, _signals);
4022 _mirrored_set(obj, elm_widget_mirrored_get(obj));
4028 _item_select(Elm_Gen_Item *it)
4031 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
4032 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
4033 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
4037 it->selected = EINA_TRUE;
4038 it->wd->selected = eina_list_append(it->wd->selected, it);
4040 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
4044 if ((it->wd->last_selected_item) &&
4045 (it != (Elm_Gen_Item *) it->wd->last_selected_item))
4046 _item_unfocusable_set((Elm_Gen_Item *)it->wd->last_selected_item, EINA_TRUE);
4048 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
4049 if (it->generation == it->wd->generation)
4050 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
4053 if ((it->wd->clear_me) && (!it->wd->walking))
4054 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
4057 if ((!it->walking) && (it->generation < it->wd->generation))
4062 elm_widget_item_free(it);
4066 it->wd->last_selected_item = (Elm_Object_Item *)it;
4070 static Evas_Object *
4071 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
4073 return edje_object_part_swallow_get(VIEW(it), part);
4077 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
4079 if (content && part)
4081 it->content_objs = eina_list_append(it->content_objs, content);
4082 edje_object_part_swallow(VIEW(it), part, content);
4086 static Evas_Object *
4087 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
4090 obj = edje_object_part_swallow_get(VIEW(it), part);
4091 if (!obj) return NULL;
4092 it->content_objs = eina_list_remove(it->content_objs, obj);
4093 edje_object_part_unswallow(VIEW(it), obj);
4098 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
4100 if (!it->itc->func.text_get) return NULL;
4101 return edje_object_part_text_get(VIEW(it), part);
4105 _item_disable_hook(Elm_Object_Item *it)
4109 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4111 if (_it->generation < _it->wd->generation) return;
4114 elm_genlist_item_selected_set(it, EINA_FALSE);
4118 if (elm_widget_item_disabled_get(it))
4120 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
4121 if (_it->deco_all_view)
4122 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
4126 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
4127 if (_it->deco_all_view)
4128 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
4130 EINA_LIST_FOREACH(_it->content_objs, l, obj)
4131 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
4136 _item_del_pre_hook(Elm_Object_Item *it)
4138 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4140 if ((_it->relcount > 0) || (_it->walking > 0))
4142 elm_genlist_item_subitems_clear(it);
4143 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
4144 _elm_genlist_item_del_notserious(_it);
4145 if (_it->item->block)
4147 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
4148 _it->item->block->changed = EINA_TRUE;
4149 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
4150 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
4154 _it->parent->item->items =
4155 eina_list_remove(_it->parent->item->items, it);
4165 _item_signal_emit_hook(Elm_Object_Item *it,
4166 const char *emission,
4169 edje_object_signal_emit(VIEW(it), emission, source);
4173 _elm_genlist_item_new(Widget_Data *wd,
4174 const Elm_Gen_Item_Class *itc,
4176 Elm_Gen_Item *parent,
4178 const void *func_data)
4182 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
4183 if (!it) return NULL;
4185 it->generation = wd->generation;
4187 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
4188 it->base.data = data;
4189 it->parent = parent;
4190 it->func.func = func;
4191 it->func.data = func_data;
4192 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
4193 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
4194 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
4195 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
4196 elm_widget_item_disable_hook_set(it, _item_disable_hook);
4197 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
4198 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
4201 it->sel_cb = (Ecore_Cb)_item_select;
4206 static Elm_Gen_Item *
4207 _item_new(Widget_Data *wd,
4208 const Elm_Genlist_Item_Class *itc,
4210 Elm_Gen_Item *parent,
4211 Elm_Genlist_Item_Type type,
4213 const void *func_data)
4215 Elm_Gen_Item *it, *it2;
4218 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
4219 if (!it) return NULL;
4220 it->item = ELM_NEW(Elm_Gen_Item_Type);
4221 it->item->type = type;
4222 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
4223 it->item->expanded_depth = 0;
4224 ELM_GEN_ITEM_SETUP(it);
4225 it->mouse_cursor = NULL;
4226 it->can_focus = EINA_TRUE;
4229 if (it->parent->group)
4230 it->item->group_item = parent;
4231 else if (it->parent->item->group_item)
4232 it->item->group_item = it->parent->item->group_item;
4234 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
4236 if (!it2->parent->group) depth += 1;
4238 it->item->expanded_depth = depth;
4244 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
4248 itb = calloc(1, sizeof(Item_Block));
4249 if (!itb) return NULL;
4253 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
4254 _item_block_position_update(wd->blocks, 0);
4258 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4259 itb->position_update = EINA_TRUE;
4260 if (wd->blocks != EINA_INLIST_GET(itb))
4262 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4273 _item_block_add(Widget_Data *wd,
4276 Item_Block *itb = NULL;
4283 itb = calloc(1, sizeof(Item_Block));
4284 if (!itb) return EINA_FALSE;
4286 if (!it->item->rel->item->block)
4289 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4290 itb->items = eina_list_append(itb->items, it);
4291 itb->position_update = EINA_TRUE;
4292 it->position = eina_list_count(itb->items);
4293 it->position_update = EINA_TRUE;
4295 if (wd->blocks != EINA_INLIST_GET(itb))
4297 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4308 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4309 if (it->item->before)
4311 wd->blocks = eina_inlist_prepend_relative
4312 (wd->blocks, EINA_INLIST_GET(itb),
4313 EINA_INLIST_GET(it->item->rel->item->block));
4315 eina_list_prepend_relative_list(itb->items, it, tmp);
4317 /* Update index from where we prepended */
4318 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4319 _item_block_position_update(EINA_INLIST_GET(itb),
4320 it->item->rel->item->block->position);
4324 wd->blocks = eina_inlist_append_relative
4325 (wd->blocks, EINA_INLIST_GET(itb),
4326 EINA_INLIST_GET(it->item->rel->item->block));
4328 eina_list_append_relative_list(itb->items, it, tmp);
4330 /* Update block index from where we appended */
4331 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4332 _item_block_position_update(EINA_INLIST_GET(itb),
4333 it->item->rel->item->block->position + 1);
4339 if (it->item->before)
4343 itb = (Item_Block *)(wd->blocks);
4344 if (itb->count >= wd->max_items_per_block)
4346 itb = _item_block_new(wd, EINA_TRUE);
4347 if (!itb) return EINA_FALSE;
4352 itb = _item_block_new(wd, EINA_TRUE);
4353 if (!itb) return EINA_FALSE;
4355 itb->items = eina_list_prepend(itb->items, it);
4357 _item_position_update(itb->items, 0);
4363 itb = (Item_Block *)(wd->blocks->last);
4364 if (itb->count >= wd->max_items_per_block)
4366 itb = _item_block_new(wd, EINA_FALSE);
4367 if (!itb) return EINA_FALSE;
4372 itb = _item_block_new(wd, EINA_FALSE);
4373 if (!itb) return EINA_FALSE;
4375 itb->items = eina_list_append(itb->items, it);
4376 it->position = eina_list_count(itb->items);
4384 if (it->item->rel->item->queued)
4386 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
4387 on sorted insertion order, so the queue is not always ordered like the item list.
4388 This lead to issue where we depend on an item that is not yet created. As a quick
4389 work around, we reschedule the calc of the item and stop reordering the list to
4390 prevent any nasty issue to show up here.
4392 wd->queue = eina_list_append(wd->queue, it);
4393 wd->requeued = EINA_TRUE;
4394 it->item->queued = EINA_TRUE;
4397 itb = it->item->rel->item->block;
4398 if (!itb) goto newblock;
4399 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4400 if (it->item->before)
4402 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4403 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4407 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4408 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4412 itb->changed = EINA_TRUE;
4413 it->item->block = itb;
4414 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
4415 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
4418 it->item->rel->relcount--;
4419 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
4421 _item_del(it->item->rel);
4422 elm_widget_item_free(it->item->rel);
4424 it->item->rel = NULL;
4426 if (itb->count > itb->wd->max_items_per_block)
4431 Eina_Bool done = EINA_FALSE;
4433 newc = itb->count / 2;
4435 if (EINA_INLIST_GET(itb)->prev)
4437 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4439 if (itbp->count + newc < wd->max_items_per_block / 2)
4441 /* moving items to previous block */
4442 while ((itb->count > newc) && (itb->items))
4444 it2 = eina_list_data_get(itb->items);
4445 itb->items = eina_list_remove_list(itb->items, itb->items);
4448 itbp->items = eina_list_append(itbp->items, it2);
4449 it2->item->block = itbp;
4457 if (!done && EINA_INLIST_GET(itb)->next)
4459 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4461 if (itbn->count + newc < wd->max_items_per_block / 2)
4463 /* moving items to next block */
4464 while ((itb->count > newc) && (itb->items))
4468 l = eina_list_last(itb->items);
4469 it2 = eina_list_data_get(l);
4470 itb->items = eina_list_remove_list(itb->items, l);
4473 itbn->items = eina_list_prepend(itbn->items, it2);
4474 it2->item->block = itbn;
4484 /* moving items to new block */
4485 itb2 = calloc(1, sizeof(Item_Block));
4486 if (!itb2) return EINA_FALSE;
4489 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4490 EINA_INLIST_GET(itb));
4491 itb2->changed = EINA_TRUE;
4492 while ((itb->count > newc) && (itb->items))
4496 l = eina_list_last(itb->items);
4498 itb->items = eina_list_remove_list(itb->items, l);
4501 itb2->items = eina_list_prepend(itb2->items, it2);
4502 it2->item->block = itb2;
4512 _item_process(Widget_Data *wd, Elm_Gen_Item *it)
4514 if (!_item_block_add(wd, it)) return 1;
4516 _item_block_realize(it->item->block);
4521 _item_process_post(Widget_Data *wd, Elm_Gen_Item *it, Eina_Bool qadd)
4523 Eina_Bool showme = EINA_FALSE;
4525 if (it->item->block->changed)
4527 showme = _item_block_recalc(it->item->block, it->item->block->num, qadd);
4528 it->item->block->changed = 0;
4529 if (wd->pan_changed)
4531 if (wd->calc_job) ecore_job_del(wd->calc_job);
4532 wd->calc_job = NULL;
4534 wd->pan_changed = EINA_FALSE;
4537 if (showme) it->item->block->showme = EINA_TRUE;
4538 /* when prepending, move the scroller along with the first selected item to
4539 * create the illusion that we're watching the selected item
4540 * this prevents the selected item being scrolled off the viewport
4542 if (wd->selected && it->item->before)
4546 it2 = wd->selected->data;
4547 elm_smart_scroller_child_pos_get(wd->scr, NULL, &y);
4548 evas_object_geometry_get(wd->pan_smart, NULL, NULL, NULL, &h);
4549 if ((it->y + it->item->block->y > y + h) || (it->y + it->item->block->y + it->item->h < y))
4550 /* offscreen, just update */
4551 elm_smart_scroller_child_region_show(wd->scr,
4552 it2->x + it2->item->block->x,
4554 it2->item->block->w,
4557 elm_smart_scroller_child_region_show(wd->scr,
4558 it->x + it->item->block->x,
4566 _queue_process(Widget_Data *wd)
4571 t0 = ecore_loop_time_get();
4572 //evas_event_freeze(evas_object_evas_get(wd->obj));
4573 for (n = 0; (wd->queue) && (n < 128); n++)
4577 it = eina_list_data_get(wd->queue);
4578 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4579 it->item->queued = EINA_FALSE;
4580 if (_item_process(wd, it)) continue;
4581 t = ecore_time_get();
4582 _item_process_post(wd, it, EINA_TRUE);
4583 /* same as eina_inlist_count > 1 */
4584 if (wd->blocks && wd->blocks->next)
4586 if ((t - t0) > (ecore_animator_frametime_get())) break;
4589 //evas_event_thaw(evas_object_evas_get(wd->obj));
4590 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4595 _idle_process(void *data, Eina_Bool *wakeup)
4597 Widget_Data *wd = data;
4600 //static double q_start = 0.0;
4601 //if (q_start == 0.0) q_start = ecore_time_get();
4603 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4607 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4609 return ECORE_CALLBACK_CANCEL;
4611 return ECORE_CALLBACK_RENEW;
4615 _item_idle_enterer(void *data)
4617 Widget_Data *wd = data;
4618 Eina_Bool wakeup = EINA_FALSE;
4619 Eina_Bool ok = _idle_process(data, &wakeup);
4624 if (wd->calc_job) ecore_job_del(wd->calc_job);
4625 wd->calc_job = ecore_job_add(_calc_job, wd);
4627 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4632 _item_queue(Widget_Data *wd,
4636 if (it->item->queued) return;
4637 if ((wd->blocks) && (wd->homogeneous) && (wd->mode == ELM_LIST_COMPRESS))
4639 if (!_item_process(wd, it))
4640 _item_process_post(wd, it, EINA_FALSE);
4643 it->item->queued = EINA_TRUE;
4644 if (cb && !wd->requeued)
4645 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4647 wd->queue = eina_list_append(wd->queue, it);
4648 // FIXME: why does a freeze then thaw here cause some genlist
4649 // elm_genlist_item_append() to be much much slower?
4650 // evas_event_freeze(evas_object_evas_get(wd->obj));
4651 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4653 if (wd->queue_idle_enterer)
4655 ecore_idle_enterer_del(wd->queue_idle_enterer);
4656 wd->queue_idle_enterer = NULL;
4660 // evas_event_thaw(evas_object_evas_get(wd->obj));
4661 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4662 if (!wd->queue_idle_enterer)
4663 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4667 _elm_genlist_item_compare(const void *data, const void *data1)
4669 const Elm_Gen_Item *it, *item1;
4670 it = ELM_GEN_ITEM_FROM_INLIST(data);
4671 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4672 return it->wd->item_compare_cb(it, item1);
4676 _elm_genlist_item_list_compare(const void *data, const void *data1)
4678 const Elm_Gen_Item *it = data;
4679 const Elm_Gen_Item *item1 = data1;
4680 return it->wd->item_compare_cb(it, item1);
4683 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4685 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4690 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4691 _item_block_del(it);
4693 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4694 it->item->rel = after;
4695 it->item->rel->relcount++;
4696 it->item->before = EINA_FALSE;
4697 if (after->item->group_item) it->item->group_item = after->item->group_item;
4698 _item_queue(it->wd, it, NULL);
4700 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4703 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4705 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4708 if (!before) return;
4710 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4711 _item_block_del(it);
4712 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4713 it->item->rel = before;
4714 it->item->rel->relcount++;
4715 it->item->before = EINA_TRUE;
4716 if (before->item->group_item) it->item->group_item = before->item->group_item;
4717 _item_queue(it->wd, it, NULL);
4719 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4723 elm_genlist_items_count(const Evas_Object *obj)
4725 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4726 Widget_Data *wd = elm_widget_data_get(obj);
4728 return wd->item_count;
4731 EAPI Elm_Object_Item *
4732 elm_genlist_item_append(Evas_Object *obj,
4733 const Elm_Genlist_Item_Class *itc,
4735 Elm_Object_Item *parent,
4736 Elm_Genlist_Item_Type type,
4738 const void *func_data)
4740 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4741 Widget_Data *wd = elm_widget_data_get(obj);
4742 if (!wd) return NULL;
4743 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4745 if (!it) return NULL;
4749 wd->group_items = eina_list_append(wd->group_items, it);
4750 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4751 it->item->rel = NULL;
4755 Elm_Gen_Item *it2 = NULL;
4756 Eina_List *ll = eina_list_last(it->parent->item->items);
4757 if (ll) it2 = ll->data;
4758 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4759 if (!it2) it2 = it->parent;
4761 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4762 EINA_INLIST_GET(it2));
4763 it->item->rel = it2;
4764 it->item->rel->relcount++;
4766 it->item->before = EINA_FALSE;
4767 _item_queue(wd, it, NULL);
4768 return (Elm_Object_Item *)it;
4771 EAPI Elm_Object_Item *
4772 elm_genlist_item_prepend(Evas_Object *obj,
4773 const Elm_Genlist_Item_Class *itc,
4775 Elm_Object_Item *parent,
4776 Elm_Genlist_Item_Type type,
4778 const void *func_data)
4780 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4781 Widget_Data *wd = elm_widget_data_get(obj);
4782 if (!wd) return NULL;
4783 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4785 if (!it) return NULL;
4789 wd->group_items = eina_list_prepend(wd->group_items, it);
4790 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4791 it->item->rel = NULL;
4795 Elm_Gen_Item *it2 = NULL;
4796 Eina_List *ll = it->parent->item->items;
4797 if (ll) it2 = ll->data;
4798 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4799 if (!it2) it2 = it->parent;
4801 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4802 EINA_INLIST_GET(it2));
4803 it->item->rel = it2;
4804 it->item->rel->relcount++;
4806 it->item->before = EINA_TRUE;
4807 _item_queue(wd, it, NULL);
4808 return (Elm_Object_Item *)it;
4811 EAPI Elm_Object_Item *
4812 elm_genlist_item_insert_after(Evas_Object *obj,
4813 const Elm_Genlist_Item_Class *itc,
4815 Elm_Object_Item *parent,
4816 Elm_Object_Item *after,
4817 Elm_Genlist_Item_Type type,
4819 const void *func_data)
4821 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4822 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4823 Widget_Data *wd = elm_widget_data_get(obj);
4824 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4825 if (!wd) return NULL;
4826 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4827 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4829 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4831 if (!it) return NULL;
4834 if ((it->group) && (_after->group))
4835 wd->group_items = eina_list_append_relative(wd->group_items, it,
4840 it->parent->item->items =
4841 eina_list_append_relative(it->parent->item->items, it, _after);
4843 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4844 EINA_INLIST_GET(_after));
4845 it->item->rel = _after;
4846 it->item->rel->relcount++;
4847 it->item->before = EINA_FALSE;
4848 _item_queue(wd, it, NULL);
4849 return (Elm_Object_Item *)it;
4852 EAPI Elm_Object_Item *
4853 elm_genlist_item_insert_before(Evas_Object *obj,
4854 const Elm_Genlist_Item_Class *itc,
4856 Elm_Object_Item *parent,
4857 Elm_Object_Item *before,
4858 Elm_Genlist_Item_Type type,
4860 const void *func_data)
4862 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4863 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4864 Widget_Data *wd = elm_widget_data_get(obj);
4865 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4866 if (!wd) return NULL;
4867 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4868 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4870 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4872 if (!it) return NULL;
4875 if (it->group && _before->group)
4876 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4881 it->parent->item->items =
4882 eina_list_prepend_relative(it->parent->item->items, it, _before);
4884 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4885 EINA_INLIST_GET(_before));
4886 it->item->rel = _before;
4887 it->item->rel->relcount++;
4888 it->item->before = EINA_TRUE;
4889 _item_queue(wd, it, NULL);
4890 return (Elm_Object_Item *)it;
4893 EAPI Elm_Object_Item *
4894 elm_genlist_item_sorted_insert(Evas_Object *obj,
4895 const Elm_Genlist_Item_Class *itc,
4897 Elm_Object_Item *parent,
4898 Elm_Genlist_Item_Type type,
4899 Eina_Compare_Cb comp,
4901 const void *func_data)
4903 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4904 Widget_Data *wd = elm_widget_data_get(obj);
4905 if (!wd) return NULL;
4906 Elm_Gen_Item *rel = NULL;
4907 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4909 if (!it) return NULL;
4911 wd->item_compare_cb = comp;
4918 l = eina_list_search_sorted_near_list(it->parent->item->items,
4919 _elm_genlist_item_list_compare,
4923 rel = eina_list_data_get(l);
4927 if (cmp_result >= 0)
4929 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4930 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4931 it->item->before = EINA_FALSE;
4933 else if (cmp_result < 0)
4935 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4936 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4937 it->item->before = EINA_TRUE;
4944 wd->state = eina_inlist_sorted_state_new();
4945 eina_inlist_sorted_state_init(wd->state, wd->items);
4946 wd->requeued = EINA_FALSE;
4950 wd->group_items = eina_list_append(wd->group_items, it);
4952 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4953 _elm_genlist_item_compare, wd->state);
4955 if (EINA_INLIST_GET(it)->next)
4957 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4958 it->item->before = EINA_TRUE;
4960 else if (EINA_INLIST_GET(it)->prev)
4962 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4963 it->item->before = EINA_FALSE;
4969 it->item->rel = rel;
4970 it->item->rel->relcount++;
4973 _item_queue(wd, it, _elm_genlist_item_list_compare);
4975 return (Elm_Object_Item *)it;
4979 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4981 Eina_Inlist *next, *l;
4982 Widget_Data *wd = elm_widget_data_get(obj);
4985 if (!standby) wd->generation++;
4989 eina_inlist_sorted_state_free(wd->state);
4993 if (wd->walking > 0)
4995 wd->clear_me = EINA_TRUE;
4998 evas_event_freeze(evas_object_evas_get(wd->obj));
4999 for (l = wd->items, next = l ? l->next : NULL;
5001 l = next, next = next ? next->next : NULL)
5003 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
5005 if (it->generation < wd->generation)
5007 Elm_Gen_Item *itn = NULL;
5009 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
5010 if (itn) itn->walking++; /* prevent early death of subitem */
5012 elm_widget_item_free(it);
5013 if (itn) itn->walking--;
5016 wd->clear_me = EINA_FALSE;
5017 wd->pan_changed = EINA_TRUE;
5020 ecore_job_del(wd->calc_job);
5021 wd->calc_job = NULL;
5023 if (wd->selected) wd->selected = eina_list_free(wd->selected);
5024 if (wd->clear_cb) wd->clear_cb(wd);
5030 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
5031 wd->alpha_bg = NULL;
5035 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
5036 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
5038 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
5039 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
5040 evas_event_thaw(evas_object_evas_get(wd->obj));
5041 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
5045 elm_genlist_clear(Evas_Object *obj)
5047 ELM_CHECK_WIDTYPE(obj, widtype);
5048 _elm_genlist_clear(obj, EINA_FALSE);
5052 elm_genlist_multi_select_set(Evas_Object *obj,
5055 ELM_CHECK_WIDTYPE(obj, widtype);
5056 Widget_Data *wd = elm_widget_data_get(obj);
5058 wd->multi = !!multi;
5062 elm_genlist_multi_select_get(const Evas_Object *obj)
5064 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5065 Widget_Data *wd = elm_widget_data_get(obj);
5066 if (!wd) return EINA_FALSE;
5070 EAPI Elm_Object_Item *
5071 elm_genlist_selected_item_get(const Evas_Object *obj)
5073 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5074 Widget_Data *wd = elm_widget_data_get(obj);
5075 if (!wd) return NULL;
5076 if (wd->selected) return wd->selected->data;
5080 EAPI const Eina_List *
5081 elm_genlist_selected_items_get(const Evas_Object *obj)
5083 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5084 Widget_Data *wd = elm_widget_data_get(obj);
5085 if (!wd) return NULL;
5086 return wd->selected;
5090 elm_genlist_realized_items_get(const Evas_Object *obj)
5092 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5093 Widget_Data *wd = elm_widget_data_get(obj);
5094 Eina_List *list = NULL;
5096 Eina_Bool done = EINA_FALSE;
5097 if (!wd) return NULL;
5098 EINA_INLIST_FOREACH(wd->blocks, itb)
5106 EINA_LIST_FOREACH(itb->items, l, it)
5108 if (it->realized) list = eina_list_append(list, it);
5119 EAPI Elm_Object_Item *
5120 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5125 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5126 Widget_Data *wd = elm_widget_data_get(obj);
5127 Evas_Coord ox, oy, ow, oh;
5130 if (!wd) return NULL;
5131 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5133 EINA_INLIST_FOREACH(wd->blocks, itb)
5138 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
5139 oy + itb->y - itb->wd->pan_y,
5140 itb->w, itb->h, x, y, 1, 1))
5142 EINA_LIST_FOREACH(itb->items, l, it)
5144 Evas_Coord itx, ity;
5146 itx = ox + itb->x + it->x - itb->wd->pan_x;
5147 ity = oy + itb->y + it->y - itb->wd->pan_y;
5148 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5152 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5153 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5157 return (Elm_Object_Item *)it;
5159 lasty = ity + it->item->h;
5164 if (y > lasty) *posret = 1;
5170 EAPI Elm_Object_Item *
5171 elm_genlist_first_item_get(const Evas_Object *obj)
5173 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5174 Widget_Data *wd = elm_widget_data_get(obj);
5175 if (!wd) return NULL;
5176 if (!wd->items) return NULL;
5177 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
5178 while ((it) && (it->generation < wd->generation))
5179 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5180 return (Elm_Object_Item *)it;
5183 EAPI Elm_Object_Item *
5184 elm_genlist_last_item_get(const Evas_Object *obj)
5186 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5187 Widget_Data *wd = elm_widget_data_get(obj);
5188 if (!wd) return NULL;
5189 if (!wd->items) return NULL;
5190 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
5191 while ((it) && (it->generation < wd->generation))
5192 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5193 return (Elm_Object_Item *)it;
5196 EAPI Elm_Object_Item *
5197 elm_genlist_item_next_get(const Elm_Object_Item *it)
5199 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5200 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5203 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
5204 if ((_it) && (_it->generation == _it->wd->generation)) break;
5206 return (Elm_Object_Item *) _it;
5209 EAPI Elm_Object_Item *
5210 elm_genlist_item_prev_get(const Elm_Object_Item *it)
5212 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5213 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5216 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
5217 if ((_it) && (_it->generation == _it->wd->generation)) break;
5219 return (Elm_Object_Item *) _it;
5222 EAPI Elm_Object_Item *
5223 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5225 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5226 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
5230 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
5232 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5233 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
5235 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5237 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
5238 _item_subitems_clear(_it);
5241 if (!wd->tree_effect_animator)
5243 wd->expanded_item = _it;
5244 _item_tree_effect_before(_it);
5245 evas_object_raise(wd->alpha_bg);
5246 evas_object_show(wd->alpha_bg);
5247 wd->start_time = ecore_time_get();
5248 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
5251 _item_subitems_clear(_it);
5256 elm_genlist_item_selected_set(Elm_Object_Item *it,
5259 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5260 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5261 Widget_Data *wd = _it->wd;
5263 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
5265 selected = !!selected;
5266 if (_it->selected == selected) return;
5272 while (wd->selected)
5274 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
5275 _it->unsel_cb(wd->selected->data);
5278 _it->highlight_cb(_it);
5282 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
5287 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5289 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5290 return ((Elm_Gen_Item *)it)->selected;
5294 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5297 if (it->item->expanded)
5299 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5303 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5306 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5307 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5314 _elm_genlist_move_items_set(Elm_Gen_Item *it)
5317 Elm_Gen_Item *it2 = NULL;
5318 Evas_Coord ox, oy, ow, oh, dh = 0;
5320 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
5322 if (it->item->expanded)
5324 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
5325 EINA_LIST_FOREACH_SAFE(it->wd->move_items, l, ll, it2)
5327 if (it2 == it->wd->expanded_next_item) break;
5328 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
5333 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
5334 it2 = it->wd->expanded_next_item;
5335 while (it2 && (dh < oy + oh))
5338 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
5339 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5345 elm_genlist_item_expanded_set(Elm_Object_Item *it,
5348 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5349 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5350 expanded = !!expanded;
5351 if (_it->item->expanded == expanded) return;
5352 if (_it->item->type != ELM_GENLIST_ITEM_TREE) return;
5353 _it->item->expanded = expanded;
5354 _it->wd->expanded_item = _it;
5355 _elm_genlist_move_items_set(_it);
5357 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
5358 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
5360 if (_it->item->expanded)
5362 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
5364 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
5365 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
5366 _it->wd->auto_scroll_enabled = EINA_TRUE;
5370 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
5372 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
5373 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
5374 _it->wd->auto_scroll_enabled = EINA_FALSE;
5379 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5381 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5382 return ((Elm_Gen_Item *)it)->item->expanded;
5386 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5388 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
5389 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5392 EINA_DEPRECATED EAPI void
5393 elm_genlist_item_display_only_set(Elm_Object_Item *it,
5394 Eina_Bool display_only)
5396 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5397 display_only = !!display_only;
5400 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
5403 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5404 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5405 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
5409 EINA_DEPRECATED EAPI Eina_Bool
5410 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
5412 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5413 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5414 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5415 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5416 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5422 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
5423 Elm_Genlist_Item_Scrollto_Type type,
5430 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5431 Evas_Coord gith = 0;
5432 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5433 if ((_it->wd->homogeneous) &&
5434 (_it->wd->mode == ELM_LIST_COMPRESS))
5435 goto hm_shortcut; /* homogenous genlist shortcut */
5436 if ((_it->item->queued) || (!_it->item->mincalcd))
5438 _it->wd->show_item = _it;
5439 _it->wd->bring_in = bring_in;
5440 _it->wd->scrollto_type = type;
5441 _it->item->showme = EINA_TRUE;
5445 if (_it->wd->show_item)
5447 _it->wd->show_item->item->showme = EINA_FALSE;
5448 _it->wd->show_item = NULL;
5451 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
5454 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5455 if ((_it->item->group_item) &&
5456 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
5457 gith = _it->item->group_item->item->h;
5459 *y = _it->y + _it->item->block->y - gith;
5461 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5462 if (_it->item->group_item) gith = _it->item->group_item->item->h;
5463 *y = _it->y + _it->item->block->y - gith;
5465 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5466 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
5472 *x = _it->x + _it->item->block->x;
5473 *w = _it->item->block->w;
5478 elm_genlist_item_promote(Elm_Object_Item *it)
5480 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5481 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5482 if (_it->generation < _it->wd->generation) return;
5483 _item_move_before(_it,
5484 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
5488 elm_genlist_item_demote(Elm_Object_Item *it)
5490 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5491 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5492 if (_it->generation < _it->wd->generation) return;
5493 _item_move_after(_it,
5494 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
5498 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5500 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5501 Evas_Coord x, y, w, h;
5502 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5504 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
5505 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
5509 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5512 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5513 Evas_Coord x, y, w, h;
5514 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5516 elm_smart_scroller_child_viewport_size_get(_it->wd->scr, &x, &y);
5518 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
5519 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
5523 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5525 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5527 Evas_Object *content;
5528 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5530 elm_widget_sub_object_del(WIDGET(it), content);
5531 evas_object_smart_member_del(content);
5532 evas_object_hide(content);
5533 if (l) *l = eina_list_append(*l, content);
5538 elm_genlist_item_update(Elm_Object_Item *it)
5540 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5541 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5543 if (!_it->item->block) return;
5544 if (_it->generation < _it->wd->generation) return;
5545 _it->item->mincalcd = EINA_FALSE;
5546 _it->item->updateme = EINA_TRUE;
5547 _it->item->block->updateme = EINA_TRUE;
5548 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5549 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5553 elm_genlist_item_fields_update(Elm_Object_Item *it,
5555 Elm_Genlist_Item_Field_Type itf)
5557 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5558 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5560 if (!_it->item->block) return;
5561 if (_it->generation < _it->wd->generation) return;
5563 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5564 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5565 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5567 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5568 &_it->contents, parts);
5569 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5570 &_it->contents, parts);
5574 _it->item->flip_content_objs =
5575 _item_mode_content_unrealize(_it, VIEW(_it),
5576 &_it->item->flip_contents, parts,
5577 &_it->item->flip_content_objs);
5578 _it->item->flip_content_objs =
5579 _item_mode_content_realize(_it, VIEW(_it),
5580 &_it->item->flip_contents, parts,
5581 &_it->item->flip_content_objs);
5583 if (_it->item->deco_it_view)
5585 _it->item->deco_it_content_objs =
5586 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5587 &_it->item->deco_it_contents, parts,
5588 &_it->item->deco_it_content_objs);
5589 _it->item->deco_it_content_objs =
5590 _item_mode_content_realize(_it, _it->item->deco_it_view,
5591 &_it->item->deco_it_contents, parts,
5592 &_it->item->deco_it_content_objs);
5594 if (_it->wd->decorate_all_mode)
5596 _it->item->deco_all_content_objs =
5597 _item_mode_content_unrealize(_it, _it->deco_all_view,
5598 &_it->item->deco_all_contents, parts,
5599 &_it->item->deco_all_content_objs);
5600 _it->item->deco_all_content_objs =
5601 _item_mode_content_realize(_it, _it->deco_all_view,
5602 &_it->item->deco_all_contents, parts,
5603 &_it->item->deco_all_content_objs);
5606 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5607 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5611 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5612 const Elm_Genlist_Item_Class *itc)
5614 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5615 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5617 if (!_it->item->block) return;
5618 EINA_SAFETY_ON_NULL_RETURN(itc);
5619 if (_it->generation < _it->wd->generation) return;
5621 _it->item->nocache_once = EINA_TRUE;
5623 elm_widget_stringlist_free(_it->texts);
5625 elm_widget_stringlist_free(_it->contents);
5626 _it->contents = NULL;
5627 elm_widget_stringlist_free(_it->states);
5632 elm_widget_stringlist_free(_it->item->flip_contents);
5633 _it->item->flip_contents = NULL;
5635 if (_it->item->deco_it_view)
5637 elm_widget_stringlist_free(_it->item->deco_it_texts);
5638 _it->item->deco_it_texts = NULL;
5639 elm_widget_stringlist_free(_it->item->deco_it_contents);
5640 _it->item->deco_it_contents = NULL;
5642 if (_it->wd->decorate_all_mode)
5644 elm_widget_stringlist_free(_it->item->deco_all_texts);
5645 _it->item->deco_all_texts = NULL;
5646 elm_widget_stringlist_free(_it->item->deco_all_contents);
5647 _it->item->deco_all_contents = NULL;
5650 elm_genlist_item_update(it);
5653 EAPI const Elm_Genlist_Item_Class *
5654 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5656 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5657 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5658 if (_it->generation < _it->wd->generation) return NULL;
5662 static Evas_Object *
5663 _elm_genlist_item_label_create(void *data,
5664 Evas_Object *obj __UNUSED__,
5665 Evas_Object *tooltip,
5666 void *it __UNUSED__)
5668 Evas_Object *label = elm_label_add(tooltip);
5671 elm_object_style_set(label, "tooltip");
5672 elm_object_text_set(label, data);
5677 _elm_genlist_item_label_del_cb(void *data,
5678 Evas_Object *obj __UNUSED__,
5679 void *event_info __UNUSED__)
5681 eina_stringshare_del(data);
5685 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5688 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5689 text = eina_stringshare_add(text);
5690 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5692 _elm_genlist_item_label_del_cb);
5696 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5697 Elm_Tooltip_Item_Content_Cb func,
5699 Evas_Smart_Cb del_cb)
5701 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5702 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5704 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5707 if (_it->tooltip.del_cb)
5708 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5710 _it->tooltip.content_cb = func;
5711 _it->tooltip.data = data;
5712 _it->tooltip.del_cb = del_cb;
5716 elm_widget_item_tooltip_content_cb_set(_it,
5717 _it->tooltip.content_cb,
5718 _it->tooltip.data, NULL);
5719 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5720 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5726 if (del_cb) del_cb((void *)data, NULL, NULL);
5730 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5732 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5733 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5735 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5736 elm_widget_item_tooltip_unset(_it);
5738 if (_it->tooltip.del_cb)
5739 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5740 _it->tooltip.del_cb = NULL;
5741 _it->tooltip.content_cb = NULL;
5742 _it->tooltip.data = NULL;
5743 _it->tooltip.free_size = EINA_FALSE;
5744 if (_it->tooltip.style)
5745 elm_genlist_item_tooltip_style_set(it, NULL);
5749 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5752 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5753 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5755 eina_stringshare_replace(&_it->tooltip.style, style);
5756 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5760 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5762 return elm_object_item_tooltip_style_get(it);
5766 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5769 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5770 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5772 _it->tooltip.free_size = disable;
5773 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5778 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5780 return elm_object_tooltip_window_mode_get(VIEW(it));
5784 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5787 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5788 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5789 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5790 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5794 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5796 return elm_widget_item_cursor_get(it);
5800 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5802 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5803 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5805 if (!_it->mouse_cursor) return;
5807 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5809 eina_stringshare_del(_it->mouse_cursor);
5810 _it->mouse_cursor = NULL;
5814 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5817 elm_widget_item_cursor_style_set(it, style);
5821 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5823 return elm_widget_item_cursor_style_get(it);
5827 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5828 Eina_Bool engine_only)
5830 elm_widget_item_cursor_engine_only_set(it, engine_only);
5834 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5836 return elm_widget_item_cursor_engine_only_get(it);
5840 elm_genlist_item_index_get(const Elm_Object_Item *it)
5842 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5843 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5845 if (_it->item->block)
5846 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5851 elm_genlist_mode_set(Evas_Object *obj,
5854 ELM_CHECK_WIDTYPE(obj, widtype);
5855 Widget_Data *wd = elm_widget_data_get(obj);
5857 if (wd->mode == mode) return;
5864 elm_genlist_mode_get(const Evas_Object *obj)
5866 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5867 Widget_Data *wd = elm_widget_data_get(obj);
5868 if (!wd) return ELM_LIST_LAST;
5873 elm_genlist_bounce_set(Evas_Object *obj,
5877 ELM_CHECK_WIDTYPE(obj, widtype);
5878 Widget_Data *wd = elm_widget_data_get(obj);
5880 wd->h_bounce = !!h_bounce;
5881 wd->v_bounce = !!v_bounce;
5882 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5886 elm_genlist_bounce_get(const Evas_Object *obj,
5887 Eina_Bool *h_bounce,
5888 Eina_Bool *v_bounce)
5890 ELM_CHECK_WIDTYPE(obj, widtype);
5891 Widget_Data *wd = elm_widget_data_get(obj);
5893 if (h_bounce) *h_bounce = wd->h_bounce;
5894 if (v_bounce) *v_bounce = wd->v_bounce;
5898 elm_genlist_homogeneous_set(Evas_Object *obj,
5899 Eina_Bool homogeneous)
5901 ELM_CHECK_WIDTYPE(obj, widtype);
5902 Widget_Data *wd = elm_widget_data_get(obj);
5904 wd->homogeneous = !!homogeneous;
5908 elm_genlist_homogeneous_get(const Evas_Object *obj)
5910 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5911 Widget_Data *wd = elm_widget_data_get(obj);
5912 if (!wd) return EINA_FALSE;
5913 return wd->homogeneous;
5917 elm_genlist_block_count_set(Evas_Object *obj,
5920 ELM_CHECK_WIDTYPE(obj, widtype);
5921 Widget_Data *wd = elm_widget_data_get(obj);
5923 wd->max_items_per_block = count;
5924 wd->item_cache_max = wd->max_items_per_block * 2;
5925 _item_cache_clean(wd);
5929 elm_genlist_block_count_get(const Evas_Object *obj)
5931 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5932 Widget_Data *wd = elm_widget_data_get(obj);
5934 return wd->max_items_per_block;
5938 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5941 ELM_CHECK_WIDTYPE(obj, widtype);
5942 Widget_Data *wd = elm_widget_data_get(obj);
5944 wd->longpress_timeout = timeout;
5948 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5950 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5951 Widget_Data *wd = elm_widget_data_get(obj);
5953 return wd->longpress_timeout;
5957 elm_genlist_scroller_policy_set(Evas_Object *obj,
5958 Elm_Scroller_Policy policy_h,
5959 Elm_Scroller_Policy policy_v)
5961 ELM_CHECK_WIDTYPE(obj, widtype);
5962 Widget_Data *wd = elm_widget_data_get(obj);
5963 if ((!wd) || (!wd->scr)) return;
5964 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5965 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5967 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5971 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5972 Elm_Scroller_Policy *policy_h,
5973 Elm_Scroller_Policy *policy_v)
5975 ELM_CHECK_WIDTYPE(obj, widtype);
5976 Widget_Data *wd = elm_widget_data_get(obj);
5977 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5978 if ((!wd) || (!wd->scr)) return;
5979 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5980 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5981 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5985 elm_genlist_realized_items_update(Evas_Object *obj)
5987 ELM_CHECK_WIDTYPE(obj, widtype);
5989 Eina_List *list, *l;
5990 Elm_Object_Item *it;
5992 list = elm_genlist_realized_items_get(obj);
5993 EINA_LIST_FOREACH(list, l, it)
5994 elm_genlist_item_update(it);
5998 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5999 const char *decorate_it_type,
6000 Eina_Bool decorate_it_set)
6002 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6003 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6005 Widget_Data *wd = _it->wd;
6007 Elm_Object_Item *it2;
6010 if (!decorate_it_type) return;
6011 if ((_it->generation < _it->wd->generation) ||
6012 elm_widget_item_disabled_get(_it)) return;
6013 if (wd->decorate_all_mode) return;
6015 if ((wd->mode_item == _it) &&
6016 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
6019 if (!_it->itc->decorate_item_style) return;
6020 _it->decorate_it_set = decorate_it_set;
6024 EINA_LIST_FOREACH(wd->selected, l, it2)
6025 if (((Elm_Gen_Item *)it2)->realized)
6026 elm_genlist_item_selected_set(it2, EINA_FALSE);
6030 it2 = elm_genlist_selected_item_get(wd->obj);
6031 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
6032 elm_genlist_item_selected_set(it2, EINA_FALSE);
6035 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
6036 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
6037 _decorate_item_unset(wd);
6039 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
6040 if (decorate_it_set) _decorate_item_set(_it);
6044 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
6046 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
6047 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6048 return _it->wd->decorate_it_type;
6051 EAPI const Elm_Object_Item *
6052 elm_genlist_decorated_item_get(const Evas_Object *obj)
6054 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6055 Widget_Data *wd = elm_widget_data_get(obj);
6056 if (!wd) return NULL;
6057 return (Elm_Object_Item *) wd->mode_item;
6061 elm_genlist_decorate_mode_get(const Evas_Object *obj)
6063 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6064 Widget_Data *wd = elm_widget_data_get(obj);
6065 if (!wd) return EINA_FALSE;
6067 return wd->decorate_all_mode;
6071 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
6073 ELM_CHECK_WIDTYPE(obj, widtype);
6074 Eina_List *list, *l;
6077 Widget_Data *wd = elm_widget_data_get(obj);
6079 decorated = !!decorated;
6080 if (wd->decorate_all_mode == decorated) return;
6081 wd->decorate_all_mode = decorated;
6083 if (wd->tree_effect_animator)
6085 ecore_animator_del(wd->tree_effect_animator);
6086 wd->tree_effect_animator = NULL;
6088 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6090 list = elm_genlist_realized_items_get(obj);
6091 if (!wd->decorate_all_mode)
6093 EINA_LIST_FOREACH(list, l, it)
6095 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6096 _decorate_all_item_unrealize(it);
6098 _item_cache_zero(wd);
6102 EINA_LIST_FOREACH(list, l, it)
6104 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6106 if (it->itc->decorate_all_item_style)
6107 _decorate_all_item_realize(it, EINA_TRUE);
6111 eina_list_free(list);
6113 if (wd->calc_job) ecore_job_del(wd->calc_job);
6114 wd->calc_job = ecore_job_add(_calc_job, wd);
6118 elm_genlist_reorder_mode_set(Evas_Object *obj,
6119 Eina_Bool reorder_mode)
6121 Eina_List *list, *l;
6124 ELM_CHECK_WIDTYPE(obj, widtype);
6125 Widget_Data *wd = elm_widget_data_get(obj);
6127 wd->reorder_mode = !!reorder_mode;
6129 list = elm_genlist_realized_items_get(obj);
6130 EINA_LIST_FOREACH(list, l, it)
6132 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6134 if (wd->reorder_mode)
6135 edje_object_signal_emit(VIEW(it), "elm,state,reorder,mode_set", "elm");
6137 edje_object_signal_emit(VIEW(it), "elm,state,reorder,mode_unset", "elm");
6140 eina_list_free(list);
6144 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6146 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6147 Widget_Data *wd = elm_widget_data_get(obj);
6148 if (!wd) return EINA_FALSE;
6149 return wd->reorder_mode;
6152 EAPI Elm_Genlist_Item_Type
6153 elm_genlist_item_type_get(const Elm_Object_Item *it)
6155 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
6156 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6157 return _it->item->type;
6160 EAPI Elm_Genlist_Item_Class *
6161 elm_genlist_item_class_new(void)
6163 Elm_Genlist_Item_Class *itc;
6165 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
6168 itc->version = CLASS_ALLOCATED;
6170 itc->delete_me = EINA_FALSE;
6176 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6178 if (itc && (itc->version == CLASS_ALLOCATED))
6180 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6181 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6191 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6193 if (itc && (itc->version == CLASS_ALLOCATED))
6196 if (itc->refcount == 0) itc->refcount--;
6201 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6203 if (itc && (itc->version == CLASS_ALLOCATED))
6205 if (itc->refcount > 0) itc->refcount--;
6206 if (itc->delete_me && (!itc->refcount))
6207 elm_genlist_item_class_free(itc);
6211 void _flip_job(void *data)
6213 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
6214 _item_unhighlight(it);
6216 _elm_genlist_item_unrealize(it, EINA_FALSE);
6217 it->flipped = EINA_TRUE;
6218 it->item->nocache = EINA_TRUE;
6219 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6220 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
6224 elm_genlist_item_flip_set(Elm_Object_Item *it,
6227 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6228 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6231 if (_it->flipped == flip) return;
6235 ecore_job_add(_flip_job, _it);
6239 _it->flipped = flip;
6240 _item_cache_zero(_it->wd);
6241 elm_genlist_item_update(it);
6242 _it->item->nocache = EINA_FALSE;
6247 elm_genlist_item_flip_get(const Elm_Object_Item *it)
6249 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6250 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6251 return _it->flipped;
6255 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
6257 ELM_CHECK_WIDTYPE(obj, widtype);
6258 Widget_Data *wd = elm_widget_data_get(obj);
6260 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6262 if (wd->select_mode != mode)
6263 wd->select_mode = mode;
6266 EAPI Elm_Object_Select_Mode
6267 elm_genlist_select_mode_get(const Evas_Object *obj)
6269 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
6270 Widget_Data *wd = elm_widget_data_get(obj);
6271 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
6272 return wd->select_mode;
6276 elm_genlist_highlight_mode_set(Evas_Object *obj,
6277 Eina_Bool highlight)
6279 ELM_CHECK_WIDTYPE(obj, widtype);
6280 Widget_Data *wd = elm_widget_data_get(obj);
6282 wd->highlight = !!highlight;
6286 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6288 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6289 Widget_Data *wd = elm_widget_data_get(obj);
6290 if (!wd) return EINA_FALSE;
6291 return wd->highlight;
6295 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
6296 Elm_Object_Select_Mode mode)
6298 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6299 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6301 if (_it->generation < _it->wd->generation) return;
6302 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6304 if (_it->select_mode != mode)
6305 _it->select_mode = mode;
6307 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6309 _it->item->mincalcd = EINA_FALSE;
6310 _it->item->updateme = EINA_TRUE;
6311 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
6312 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
6313 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
6317 EAPI Elm_Object_Select_Mode
6318 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
6320 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
6321 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6322 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
6323 return _it->select_mode;
6326 /* for gengrid as of now */
6328 _elm_genlist_page_relative_set(Evas_Object *obj,
6332 Evas_Coord pagesize_h;
6333 Evas_Coord pagesize_v;
6335 ELM_CHECK_WIDTYPE(obj, widtype);
6336 Widget_Data *wd = elm_widget_data_get(obj);
6339 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
6340 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
6344 /* for gengrid as of now */
6346 _elm_genlist_page_relative_get(const Evas_Object *obj,
6350 ELM_CHECK_WIDTYPE(obj, widtype);
6351 Widget_Data *wd = elm_widget_data_get(obj);
6354 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
6357 /* for gengrid as of now */
6359 _elm_genlist_page_size_set(Evas_Object *obj,
6360 Evas_Coord h_pagesize,
6361 Evas_Coord v_pagesize)
6366 ELM_CHECK_WIDTYPE(obj, widtype);
6367 Widget_Data *wd = elm_widget_data_get(obj);
6369 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
6370 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
6374 /* for gengrid as of now */
6376 _elm_genlist_current_page_get(const Evas_Object *obj,
6380 ELM_CHECK_WIDTYPE(obj, widtype);
6381 Widget_Data *wd = elm_widget_data_get(obj);
6383 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
6386 /* for gengrid as of now */
6388 _elm_genlist_last_page_get(const Evas_Object *obj,
6392 ELM_CHECK_WIDTYPE(obj, widtype);
6393 Widget_Data *wd = elm_widget_data_get(obj);
6395 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
6398 /* for gengrid as of now */
6400 _elm_genlist_page_show(const Evas_Object *obj,
6404 ELM_CHECK_WIDTYPE(obj, widtype);
6405 Widget_Data *wd = elm_widget_data_get(obj);
6407 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
6410 /* for gengrid as of now */
6412 _elm_genlist_page_bring_in(const Evas_Object *obj,
6416 ELM_CHECK_WIDTYPE(obj, widtype);
6417 Widget_Data *wd = elm_widget_data_get(obj);
6419 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
6423 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
6426 Evas_Object *content;
6430 if (!it->realized) return;
6431 if (it->wd->reorder_it == it) return;
6432 if (it->defer_unrealize && !it->item->updateme) return;
6434 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
6436 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
6439 ecore_timer_del(it->long_timer);
6440 it->long_timer = NULL;
6443 EINA_LIST_FOREACH(it->texts, l, part)
6444 edje_object_part_text_set(VIEW(it), part, NULL);
6446 elm_widget_stringlist_free(it->texts);
6448 elm_widget_stringlist_free(it->contents);
6449 it->contents = NULL;
6450 elm_widget_stringlist_free(it->states);
6452 EINA_LIST_FREE(it->content_objs, content)
6453 evas_object_del(content);
6455 it->unrealize_cb(it);
6457 it->realized = EINA_FALSE;
6458 it->want_unrealize = EINA_FALSE;
6459 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
6460 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
6464 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
6466 elm_widget_item_pre_notify_del(it);
6467 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
6469 if ((it->relcount > 0) || (it->walking > 0)) return;
6471 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6473 if (it->itc->func.del)
6474 it->itc->func.del((void *)it->base.data, WIDGET(it));
6478 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
6480 _elm_genlist_item_del_notserious(it);
6481 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6482 if (it->tooltip.del_cb)
6483 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6484 it->wd->walking -= it->walking;
6487 ecore_timer_del(it->long_timer);
6488 it->long_timer = NULL;
6491 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
6495 eina_inlist_sorted_state_free(it->wd->state);
6496 it->wd->state = NULL;
6498 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6499 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
6503 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
6504 it->wd->last_selected_item = NULL;
6505 it->wd->item_count--;
6509 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
6511 ELM_CHECK_WIDTYPE(obj, widtype);
6512 Widget_Data *wd = elm_widget_data_get(obj);
6514 wd->tree_effect_enabled = !!enabled;
6518 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
6520 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6521 Widget_Data *wd = elm_widget_data_get(obj);
6522 if (!wd) return EINA_FALSE;
6523 return wd->tree_effect_enabled;
6527 _create_tray_alpha_bg(const Evas_Object *obj)
6529 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6530 Widget_Data *wd = elm_widget_data_get(obj);
6531 if (!wd) return NULL;
6533 Evas_Object *bg = NULL;
6534 Evas_Coord ox, oy, ow, oh;
6536 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6537 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6538 evas_object_color_set(bg,0,0,0,0);
6539 evas_object_resize(bg , ow, oh);
6540 evas_object_move(bg , ox, oy);
6545 _item_contract_emit(Elm_Gen_Item *it)
6550 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6551 it->item->tree_effect_finished = EINA_FALSE;
6553 EINA_LIST_FOREACH(it->item->items, l, it2)
6554 if (it2) _item_contract_emit(it2);
6558 _item_tree_effect_before(Elm_Gen_Item *it)
6563 EINA_LIST_FOREACH(it->item->items, l, it2)
6565 if (it2->parent && (it == it2->parent))
6568 it2->item->tree_effect_hideme = EINA_TRUE;
6569 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6570 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6571 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6572 _item_contract_emit(it2);
6575 return ECORE_CALLBACK_CANCEL;
6579 _item_tree_effect(Widget_Data *wd, int y)
6581 Elm_Gen_Item *it = NULL, *expanded_next_it;
6583 expanded_next_it = wd->expanded_next_item;
6585 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6587 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6590 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6591 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6592 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6594 if (!it->item->tree_effect_finished)
6596 edje_object_signal_emit(VIEW(it), "flip_item", "");
6597 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6598 it->item->tree_effect_finished = EINA_TRUE;
6601 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6604 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6606 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6609 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6610 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6612 if (!it->item->tree_effect_finished)
6614 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6615 it->item->tree_effect_finished = EINA_TRUE;
6620 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6626 _item_tree_effect_finish(Widget_Data *wd)
6628 Elm_Gen_Item *it = NULL;
6631 if (wd->tree_effect_animator)
6633 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6634 _item_subitems_clear(wd->expanded_item);
6635 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6637 it->item->tree_effect_finished = EINA_TRUE;
6638 it->item->old_scrl_y = it->item->scrl_y;
6639 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6640 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6643 _item_auto_scroll(wd);
6644 evas_object_lower(wd->alpha_bg);
6645 evas_object_hide(wd->alpha_bg);
6646 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6647 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6649 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6650 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6651 evas_object_smart_changed(wd->pan_smart);
6653 wd->tree_effect_animator = NULL;
6657 _tree_effect_animator_cb(void *data)
6659 Widget_Data *wd = data;
6660 if (!wd) return ECORE_CALLBACK_CANCEL;
6661 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6662 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6664 double effect_duration = 0.3, t;
6665 int y = 0, dy = 0, dh = 0;
6666 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6669 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6670 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6671 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6672 if (t > effect_duration) end = EINA_TRUE;
6674 // Below while statement is needed, when the genlist is resized.
6675 it2 = wd->expanded_item;
6678 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6679 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6680 cvx, cvy, cvw, cvh));
6681 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6684 if (wd->expanded_next_item)
6686 expanded_next_it = wd->expanded_next_item;
6689 EINA_LIST_FOREACH(wd->move_items, l, it)
6691 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6693 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6694 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6695 expanded_next_it->item->scrl_y = cvy + cvh;
6697 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6698 cvy + cvh : expanded_next_it->item->scrl_y) -
6699 expanded_next_it->item->old_scrl_y;
6701 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6703 if (expanded_next_it->item->scrl_y > expanded_next_it->item->old_scrl_y) //did not calculate next item position
6704 expanded_next_it->item->old_scrl_y = cvy + cvh;
6706 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6708 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6710 expanded_next_it->item->old_scrl_y = cvy + cvh;
6714 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6715 expanded_next_it->item->old_scrl_y;
6719 if (t <= effect_duration)
6721 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6729 if (!it->realized && !it->item->queued)
6730 _item_realize(it, in, 0);
6733 if (it != expanded_next_it)
6735 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6739 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6740 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6743 _item_tree_effect(wd, y);
6747 int expanded_item_num = 0;
6750 if (wd->expanded_item)
6751 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6756 expanded_item_num++;
6757 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6763 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6764 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6766 if (!it->item->tree_effect_finished)
6768 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6770 edje_object_signal_emit(VIEW(it), "flip_item", "");
6771 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6772 it->item->tree_effect_finished = EINA_TRUE;
6776 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6782 _item_tree_effect_finish(wd);
6783 return ECORE_CALLBACK_CANCEL;
6785 return ECORE_CALLBACK_RENEW;