3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.h"
9 // internally allocated
10 #define CLASS_ALLOCATED 0x3a70f11f
12 #define MAX_ITEMS_PER_BLOCK 32
13 #define REORDER_EFFECT_TIME 0.5
15 #define ELM_GEN_SETUP(wd) \
16 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
17 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
18 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
32 ERR("Genlist_Item_Class(itc) is NULL"); \
35 if ((itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) && \
36 (itc->version != CLASS_ALLOCATED)) \
38 ERR("Genlist_Item_Class version mismatched! current = (%d), required = (%d) or (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION, CLASS_ALLOCATED); \
44 typedef struct _Item_Block Item_Block;
45 typedef struct _Item_Cache Item_Cache;
47 struct Elm_Gen_Item_Type
52 Evas_Coord w, h, minw, minh;
53 Elm_Gen_Item *group_item;
54 Elm_Genlist_Item_Type type;
55 Eina_List *deco_it_texts, *deco_it_contents, *deco_it_states, *deco_it_content_objs;
56 Eina_List *deco_all_texts, *deco_all_contents, *deco_all_states, *deco_all_content_objs;
57 Eina_List *flip_contents, *flip_content_objs;
58 Ecore_Timer *swipe_timer;
59 Evas_Coord scrl_x, scrl_y, old_scrl_y;
62 Evas_Object *deco_it_view;
68 Eina_Bool want_realize : 1;
69 Eina_Bool expanded : 1;
70 Eina_Bool mincalcd : 1;
73 Eina_Bool updateme : 1;
74 Eina_Bool nocache : 1; /* do not use cache for this item */
75 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
76 Eina_Bool stacking_even : 1;
77 Eina_Bool nostacking : 1;
78 Eina_Bool move_effect_enabled : 1;
79 Eina_Bool decorate_all_item_realized : 1;
80 Eina_Bool tree_effect_finished : 1; /* tree effect */
81 Eina_Bool tree_effect_hideme : 1; /* item hide for tree effect */
92 Evas_Coord x, y, w, h, minw, minh;
94 int item_position_stamp;
96 Eina_Bool position_update : 1;
97 Eina_Bool want_unrealize : 1;
98 Eina_Bool realized : 1;
99 Eina_Bool changed : 1;
100 Eina_Bool updateme : 1;
101 Eina_Bool changeme : 1;
102 Eina_Bool showme : 1;
103 Eina_Bool must_recalc : 1;
110 Evas_Object *base_view, *spacer;
112 const char *item_style; // it->itc->item_style
113 Eina_Bool tree : 1; // it->group
115 Eina_Bool selected : 1; // it->selected
116 Eina_Bool disabled : 1; // it->disabled
117 Eina_Bool expanded : 1; // it->item->expanded
120 static const char *widtype = NULL;
121 static void _item_cache_zero(Widget_Data *wd);
122 static void _del_hook(Evas_Object *obj);
123 static void _mirrored_set(Evas_Object *obj,
125 static void _theme_hook(Evas_Object *obj);
126 static void _show_region_hook(void *data,
128 static void _sizing_eval(Evas_Object *obj);
129 static void _item_realize(Elm_Gen_Item *it,
132 static void _item_unrealize_cb(Elm_Gen_Item *it);
133 static void _item_block_unrealize(Item_Block *itb);
134 static void _calc_job(void *data);
135 static void _on_focus_hook(void *data,
137 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
138 static void _changed_job(void *data);
139 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
140 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
141 static Eina_Bool _item_single_select_up(Widget_Data *wd);
142 static Eina_Bool _item_single_select_down(Widget_Data *wd);
143 static Eina_Bool _event_hook(Evas_Object *obj,
145 Evas_Callback_Type type,
147 static void _signal_emit_hook(Evas_Object *obj,
148 const char *emission,
150 static Eina_Bool _deselect_all_items(Widget_Data *wd);
151 static void _pan_calculate(Evas_Object *obj);
152 static void _pan_max_get(Evas_Object *obj,
155 static void _item_position(Elm_Gen_Item *it,
159 static void _decorate_item_realize(Elm_Gen_Item *it);
160 static void _decorate_item_unrealize(Elm_Gen_Item *it);
161 static void _decorate_item_set(Elm_Gen_Item *it);
162 static void _decorate_item_unset(Widget_Data *wd);
163 static void _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity);
164 static void _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
165 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
168 static void _group_items_recalc(void *data);
170 static void _item_move_after(Elm_Gen_Item *it,
171 Elm_Gen_Item *after);
172 static void _item_move_before(Elm_Gen_Item *it,
173 Elm_Gen_Item *before);
174 static void _item_auto_scroll(Widget_Data *wd);
175 static void _elm_genlist_clear(Evas_Object *obj,
177 static void _pan_child_size_get(Evas_Object *obj,
180 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
181 static void _item_contract_emit(Elm_Gen_Item *it);
182 static int _item_tree_effect_before(Elm_Gen_Item *it);
183 static void _item_tree_effect(Widget_Data *wd, int y);
184 static void _item_tree_effect_finish(Widget_Data *wd);
185 static Eina_Bool _tree_effect_animator_cb(void *data);
187 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
189 static const char SIG_ACTIVATED[] = "activated";
190 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
191 static const char SIG_SELECTED[] = "selected";
192 static const char SIG_UNSELECTED[] = "unselected";
193 static const char SIG_EXPANDED[] = "expanded";
194 static const char SIG_CONTRACTED[] = "contracted";
195 static const char SIG_EXPAND_REQUEST[] = "expand,request";
196 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
197 static const char SIG_REALIZED[] = "realized";
198 static const char SIG_UNREALIZED[] = "unrealized";
199 static const char SIG_DRAG_START_UP[] = "drag,start,up";
200 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
201 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
202 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
203 static const char SIG_DRAG_STOP[] = "drag,stop";
204 static const char SIG_DRAG[] = "drag";
205 static const char SIG_LONGPRESSED[] = "longpressed";
206 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
207 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
208 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
209 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
210 static const char SIG_EDGE_TOP[] = "edge,top";
211 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
212 static const char SIG_EDGE_LEFT[] = "edge,left";
213 static const char SIG_EDGE_RIGHT[] = "edge,right";
214 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
215 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
216 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
217 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
218 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
219 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
220 static const char SIG_SWIPE[] = "swipe";
221 static const char SIG_MOVED[] = "moved";
222 static const char SIG_MOVED_AFTER[] = "moved,after";
223 static const char SIG_MOVED_BEFORE[] = "moved,before";
224 static const char SIG_INDEX_UPDATE[] = "index,update";
225 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
227 static const Evas_Smart_Cb_Description _signals[] = {
228 {SIG_CLICKED_DOUBLE, ""},
231 {SIG_UNSELECTED, ""},
233 {SIG_CONTRACTED, ""},
234 {SIG_EXPAND_REQUEST, ""},
235 {SIG_CONTRACT_REQUEST, ""},
237 {SIG_UNREALIZED, ""},
238 {SIG_DRAG_START_UP, ""},
239 {SIG_DRAG_START_DOWN, ""},
240 {SIG_DRAG_START_LEFT, ""},
241 {SIG_DRAG_START_RIGHT, ""},
244 {SIG_LONGPRESSED, ""},
245 {SIG_SCROLL_ANIM_START, ""},
246 {SIG_SCROLL_ANIM_STOP, ""},
247 {SIG_SCROLL_DRAG_START, ""},
248 {SIG_SCROLL_DRAG_STOP, ""},
250 {SIG_EDGE_BOTTOM, ""},
252 {SIG_EDGE_RIGHT, ""},
253 {SIG_MULTI_SWIPE_LEFT, ""},
254 {SIG_MULTI_SWIPE_RIGHT, ""},
255 {SIG_MULTI_SWIPE_UP, ""},
256 {SIG_MULTI_SWIPE_DOWN, ""},
257 {SIG_MULTI_PINCH_OUT, ""},
258 {SIG_MULTI_PINCH_IN, ""},
261 {SIG_MOVED_AFTER, ""},
262 {SIG_MOVED_BEFORE, ""},
263 {SIG_TREE_EFFECT_FINISHED, ""},
268 #undef ELM_CHECK_WIDTYPE
269 #define ELM_CHECK_WIDTYPE(obj, widtype) \
270 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
271 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
272 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
273 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
274 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
276 static const char *_gengrid = NULL;
277 static const char *_genlist = NULL;
279 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
281 elm_genlist_type_check(const Evas_Object *obj,
284 const char *provided, *expected = "(unknown)";
285 static int abort_on_warn = -1;
286 provided = elm_widget_type_get(obj);
287 if (!_genlist) _genlist = eina_stringshare_add("genlist");
288 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
289 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
291 if ((!provided) || (!provided[0]))
293 provided = evas_object_type_get(obj);
294 if ((!provided) || (!provided[0]))
295 provided = "(unknown)";
297 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
298 if (abort_on_warn == -1)
300 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
301 else abort_on_warn = 0;
303 if (abort_on_warn == 1) abort();
308 _event_hook(Evas_Object *obj,
309 Evas_Object *src __UNUSED__,
310 Evas_Callback_Type type,
313 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
314 Evas_Event_Key_Down *ev = event_info;
315 Widget_Data *wd = elm_widget_data_get(obj);
316 Evas_Coord pan_max_x = 0, pan_max_y = 0;
317 if (!wd) return EINA_FALSE;
318 if (!wd->items) return EINA_FALSE;
319 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
320 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
322 Elm_Object_Item *it = NULL;
325 Evas_Coord step_x = 0;
326 Evas_Coord step_y = 0;
329 Evas_Coord page_x = 0;
330 Evas_Coord page_y = 0;
332 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
333 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
334 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
335 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
337 if ((!strcmp(ev->keyname, "Left")) ||
338 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
342 else if ((!strcmp(ev->keyname, "Right")) ||
343 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
347 else if ((!strcmp(ev->keyname, "Up")) ||
348 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
350 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
351 (_item_multi_select_up(wd)))
352 || (_item_single_select_up(wd)))
354 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
360 else if ((!strcmp(ev->keyname, "Down")) ||
361 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
363 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
364 (_item_multi_select_down(wd)))
365 || (_item_single_select_down(wd)))
367 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
373 else if ((!strcmp(ev->keyname, "Home")) ||
374 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
376 it = elm_genlist_first_item_get(obj);
377 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
378 elm_genlist_item_selected_set(it, EINA_TRUE);
379 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
382 else if ((!strcmp(ev->keyname, "End")) ||
383 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
385 it = elm_genlist_last_item_get(obj);
386 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
387 elm_genlist_item_selected_set(it, EINA_TRUE);
388 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
391 else if ((!strcmp(ev->keyname, "Prior")) ||
392 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
395 y -= -(page_y * v_h) / 100;
399 else if ((!strcmp(ev->keyname, "Next")) ||
400 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
403 y += -(page_y * v_h) / 100;
407 else if (!strcmp(ev->keyname, "Escape"))
409 if (!_deselect_all_items(wd)) return EINA_FALSE;
410 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
413 else if (((!strcmp(ev->keyname, "Return")) ||
414 (!strcmp(ev->keyname, "KP_Enter")) ||
415 (!strcmp(ev->keyname, "space")))
416 && (!wd->multi) && (wd->selected))
418 it = elm_genlist_selected_item_get(obj);
419 elm_genlist_item_expanded_set(it,
420 !elm_genlist_item_expanded_get(it));
421 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
423 else return EINA_FALSE;
425 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
426 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
428 if (x > pan_max_x) x = pan_max_x;
430 if (y > pan_max_y) y = pan_max_y;
431 elm_smart_scroller_child_pos_set(wd->scr, x, y);
436 _deselect_all_items(Widget_Data *wd)
438 if (!wd->selected) return EINA_FALSE;
440 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
446 _item_multi_select_up(Widget_Data *wd)
448 if (!wd->selected) return EINA_FALSE;
449 if (!wd->multi) return EINA_FALSE;
451 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
452 if (!prev) return EINA_TRUE;
454 if (elm_genlist_item_selected_get(prev))
456 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
457 wd->last_selected_item = prev;
458 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
462 elm_genlist_item_selected_set(prev, EINA_TRUE);
463 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
469 _item_multi_select_down(Widget_Data *wd)
471 if (!wd->selected) return EINA_FALSE;
472 if (!wd->multi) return EINA_FALSE;
474 Elm_Object_Item *next;
475 next = elm_genlist_item_next_get(wd->last_selected_item);
476 if (!next) return EINA_TRUE;
478 if (elm_genlist_item_selected_get(next))
480 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
481 wd->last_selected_item = next;
482 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
486 elm_genlist_item_selected_set(next, EINA_TRUE);
487 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
493 _item_single_select_up(Widget_Data *wd)
498 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
499 while ((prev) && (prev->generation < wd->generation))
500 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
502 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
504 if (!prev) return EINA_FALSE;
506 _deselect_all_items(wd);
508 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
509 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
514 _item_single_select_down(Widget_Data *wd)
519 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
520 while ((next) && (next->generation < wd->generation))
521 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
523 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
525 if (!next) return EINA_FALSE;
527 _deselect_all_items(wd);
529 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
530 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
535 _on_focus_hook(void *data __UNUSED__,
538 Widget_Data *wd = elm_widget_data_get(obj);
540 if (elm_widget_focus_get(obj))
542 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
543 evas_object_focus_set(wd->obj, EINA_TRUE);
544 if ((wd->items) && (wd->selected) && (!wd->last_selected_item))
545 wd->last_selected_item = eina_list_data_get(wd->selected);
549 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
550 evas_object_focus_set(wd->obj, EINA_FALSE);
555 _del_hook(Evas_Object *obj)
557 Widget_Data *wd = elm_widget_data_get(obj);
559 _item_cache_zero(wd);
560 if (wd->calc_job) ecore_job_del(wd->calc_job);
561 if (wd->update_job) ecore_job_del(wd->update_job);
562 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
563 if (wd->changed_job) ecore_job_del(wd->changed_job);
564 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
565 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
566 if (wd->decorate_it_type) eina_stringshare_del(wd->decorate_it_type);
567 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
568 if (wd->tree_effect_animator) ecore_animator_del(wd->tree_effect_animator);
573 _del_pre_hook(Evas_Object *obj)
575 Widget_Data *wd = elm_widget_data_get(obj);
577 if (wd->decorate_all_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
578 elm_genlist_clear(obj);
579 evas_object_del(wd->pan_smart);
580 wd->pan_smart = NULL;
584 _mirrored_set(Evas_Object *obj,
587 Widget_Data *wd = elm_widget_data_get(obj);
589 _item_cache_zero(wd);
590 elm_smart_scroller_mirrored_set(wd->scr, rtl);
594 _theme_hook(Evas_Object *obj)
596 Widget_Data *wd = elm_widget_data_get(obj);
599 evas_event_freeze(evas_object_evas_get(wd->obj));
600 _item_cache_zero(wd);
601 _elm_widget_mirrored_reload(obj);
602 _mirrored_set(obj, elm_widget_mirrored_get(obj));
603 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
604 elm_widget_style_get(obj));
605 //edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
606 wd->item_width = wd->item_height = 0;
607 wd->group_item_width = wd->group_item_height = 0;
608 wd->minw = wd->minh = wd->realminw = 0;
609 EINA_INLIST_FOREACH(wd->blocks, itb)
614 if (itb->realized) _item_block_unrealize(itb);
615 EINA_LIST_FOREACH(itb->items, l, it)
616 it->item->mincalcd = EINA_FALSE;
618 itb->changed = EINA_TRUE;
620 if (wd->calc_job) ecore_job_del(wd->calc_job);
621 wd->calc_job = ecore_job_add(_calc_job, wd);
623 evas_event_thaw(evas_object_evas_get(wd->obj));
624 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
628 _show_region_hook(void *data,
631 Widget_Data *wd = elm_widget_data_get(data);
632 Evas_Coord x, y, w, h;
634 elm_widget_show_region_get(obj, &x, &y, &w, &h);
635 //x & y are screen coordinates, Add with pan coordinates
638 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
642 _translate_hook(Evas_Object *obj)
644 evas_object_smart_callback_call(obj, "language,changed", NULL);
648 _sizing_eval(Evas_Object *obj)
650 Widget_Data *wd = elm_widget_data_get(obj);
651 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
652 Evas_Coord vmw = 0, vmh = 0;
655 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
656 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
658 edje_object_size_min_calc
659 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
661 if (wd->mode == ELM_LIST_COMPRESS)
665 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
666 if ((vw != 0) && (vw != wd->prev_viewport_w))
670 wd->prev_viewport_w = vw;
671 EINA_INLIST_FOREACH(wd->blocks, itb)
673 itb->must_recalc = EINA_TRUE;
675 if (wd->calc_job) ecore_job_del(wd->calc_job);
676 wd->calc_job = ecore_job_add(_calc_job, wd);
678 edje_object_size_min_calc
679 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
683 else if (wd->mode == ELM_LIST_LIMIT)
686 minw = vmw + wd->realminw;
694 evas_object_size_hint_min_set(obj, minw, minh);
695 evas_object_size_hint_max_set(obj, maxw, maxh);
699 _signal_emit_hook(Evas_Object *obj,
700 const char *emission,
703 Widget_Data *wd = elm_widget_data_get(obj);
704 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
709 _item_highlight(Elm_Gen_Item *it)
711 const char *selectraise;
712 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
713 (!it->wd->highlight) ||
714 (it->generation < it->wd->generation) ||
715 (it->highlighted) || elm_widget_item_disabled_get(it) ||
716 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->deco_it_view) ||
717 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
719 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
720 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
721 selectraise = edje_object_data_get(VIEW(it), "selectraise");
722 if ((selectraise) && (!strcmp(selectraise, "on")))
724 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
725 else evas_object_raise(VIEW(it));
728 if ((it->item->group_item) && (it->item->group_item->realized))
729 evas_object_raise(it->item->VIEW(group_item));
732 it->highlighted = EINA_TRUE;
736 _item_unhighlight(Elm_Gen_Item *it)
738 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
739 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
740 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
741 if (!it->item->nostacking)
743 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
745 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
746 else evas_object_lower(VIEW(it));
750 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
751 else evas_object_raise(VIEW(it));
754 it->highlighted = EINA_FALSE;
758 _item_block_position_update(Eina_Inlist *list, int idx)
762 EINA_INLIST_FOREACH(list, tmp)
764 tmp->position = idx++;
765 tmp->position_update = EINA_TRUE;
770 _item_position_update(Eina_List *list, int idx)
775 EINA_LIST_FOREACH(list, l, it)
777 it->position = idx++;
778 it->position_update = EINA_TRUE;
783 _item_block_del(Elm_Gen_Item *it)
786 Item_Block *itb = it->item->block;
787 Eina_Bool block_changed;
789 itb->items = eina_list_remove(itb->items, it);
791 itb->changed = EINA_TRUE;
792 if (!it->wd->reorder_deleted)
794 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
795 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
799 il = EINA_INLIST_GET(itb);
800 Item_Block *itbn = (Item_Block *)(il->next);
802 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
805 _item_block_position_update(il->next, itb->position);
806 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
809 if (itbn) itbn->changed = EINA_TRUE;
813 if (itb->count < itb->wd->max_items_per_block/2)
815 il = EINA_INLIST_GET(itb);
816 Item_Block *itbp = (Item_Block *)(il->prev);
817 Item_Block *itbn = (Item_Block *)(il->next);
818 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
822 EINA_LIST_FREE(itb->items, it2)
824 it2->item->block = itbp;
825 itbp->items = eina_list_append(itbp->items, it2);
827 itbp->changed = EINA_TRUE;
829 _item_block_position_update(EINA_INLIST_GET(itb)->next,
831 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
832 EINA_INLIST_GET(itb));
834 block_changed = EINA_TRUE;
836 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
840 Eina_List *last = eina_list_last(itb->items);
841 Elm_Gen_Item *it2 = last->data;
843 it2->item->block = itbn;
844 itb->items = eina_list_remove_list(itb->items, last);
845 itbn->items = eina_list_prepend(itbn->items, it2);
847 itbn->changed = EINA_TRUE;
849 _item_block_position_update(EINA_INLIST_GET(itb)->next,
852 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
854 block_changed = EINA_TRUE;
860 it->wd->pan_changed = EINA_TRUE;
861 evas_object_smart_changed(it->wd->pan_smart);
862 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
863 it->wd->calc_job = NULL;
868 _item_subitems_clear(Elm_Gen_Item *it)
870 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
871 Eina_List *tl = NULL, *l;
872 Elm_Object_Item *it2;
874 EINA_LIST_FOREACH(it->item->items, l, it2)
875 tl = eina_list_append(tl, it2);
876 EINA_LIST_FREE(tl, it2)
877 elm_object_item_del(it2);
881 _item_del(Elm_Gen_Item *it)
883 Evas_Object *obj = WIDGET(it);
884 Widget_Data *wd = it->wd;
886 evas_event_freeze(evas_object_evas_get(obj));
887 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
888 if (wd->show_item == it) wd->show_item = NULL;
889 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
890 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
891 if (it->item->block) _item_block_del(it);
892 if (it->item->queued)
893 wd->queue = eina_list_remove(wd->queue, it);
894 if (wd->anchor_item == it)
896 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
897 if (!wd->anchor_item)
898 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
900 if (wd->expanded_item == it)
902 wd->expanded_item = NULL;
903 if (wd->tree_effect_animator)
905 ecore_animator_del(wd->tree_effect_animator);
906 wd->tree_effect_animator = NULL;
908 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
910 if (wd->expanded_next_item == it) wd->expanded_next_item = NULL;
911 if (wd->move_items) wd->move_items = eina_list_remove(wd->move_items, it);
913 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
914 if (it->item->swipe_timer)
916 ecore_timer_del(it->item->swipe_timer);
917 it->item->swipe_timer = NULL;
919 _elm_genlist_item_del_serious(it);
920 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
921 evas_event_thaw(evas_object_evas_get(obj));
922 evas_event_thaw_eval(evas_object_evas_get(obj));
926 _clear_cb(Widget_Data *wd)
928 wd->anchor_item = NULL;
929 if (wd->queue_idle_enterer)
931 ecore_idle_enterer_del(wd->queue_idle_enterer);
932 wd->queue_idle_enterer = NULL;
934 if (wd->must_recalc_idler)
936 ecore_idler_del(wd->must_recalc_idler);
937 wd->must_recalc_idler = NULL;
939 if (wd->queue) wd->queue = eina_list_free(wd->queue);
940 if (wd->reorder_move_animator)
942 ecore_animator_del(wd->reorder_move_animator);
943 wd->reorder_move_animator = NULL;
945 wd->show_item = NULL;
946 wd->reorder_old_pan_y = 0;
950 _item_unselect(Elm_Gen_Item *it)
952 if ((it->generation < it->wd->generation) || (!it->selected)) return;
953 it->selected = EINA_FALSE;
954 it->wd->selected = eina_list_remove(it->wd->selected, it);
955 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
959 _mouse_move(void *data,
960 Evas *evas __UNUSED__,
964 Elm_Gen_Item *it = data;
965 Evas_Event_Mouse_Move *ev = event_info;
966 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
967 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
969 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
971 if (!it->wd->on_hold)
973 it->wd->on_hold = EINA_TRUE;
974 if ((!it->wd->wasselected) && (!it->flipped))
976 _item_unhighlight(it);
981 if (it->wd->multitouched)
983 it->wd->cur_x = ev->cur.canvas.x;
984 it->wd->cur_y = ev->cur.canvas.y;
987 if ((it->dragging) && (it->down))
989 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
992 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
993 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
994 if (abs((it->wd->history[it->wd->movements].x -
995 it->wd->history[0].x)) > 40)
996 it->wd->swipe = EINA_TRUE;
1002 ecore_timer_del(it->long_timer);
1003 it->long_timer = NULL;
1005 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
1008 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
1012 ecore_timer_del(it->long_timer);
1013 it->long_timer = NULL;
1015 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1017 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
1019 if (ev->cur.canvas.y < (oy + (it->wd->reorder_it->item->h / 2)))
1020 it->wd->reorder_fast = 1;
1021 else if (ev->cur.canvas.y > (oy + oh - (it->wd->reorder_it->item->h / 2)))
1022 it->wd->reorder_fast = -1;
1023 else it->wd->reorder_fast = 0;
1025 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
1027 if (!it->wd->reorder_start_y)
1028 it->wd->reorder_start_y = it->item->block->y + it->y;
1032 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
1033 y_pos = oy + oh - it->wd->reorder_it->item->h;
1037 if (it->deco_all_view)
1038 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
1040 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1042 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1043 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1047 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1048 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1049 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1050 x = ev->cur.canvas.x - x;
1051 y = ev->cur.canvas.y - y;
1054 if (adx < 0) adx = -dx;
1057 if (ady < 0) ady = -dy;
1060 if ((adx > minw) || (ady > minh))
1062 it->dragging = EINA_TRUE;
1065 ecore_timer_del(it->long_timer);
1066 it->long_timer = NULL;
1068 if ((!it->wd->wasselected) && (!it->flipped))
1070 _item_unhighlight(it);
1075 if ((ady > adx) && (!it->wd->drag_started))
1076 evas_object_smart_callback_call(WIDGET(it),
1077 SIG_DRAG_START_UP, it);
1081 evas_object_smart_callback_call(WIDGET(it),
1082 SIG_DRAG_START_LEFT, it);
1084 evas_object_smart_callback_call(WIDGET(it),
1085 SIG_DRAG_START_RIGHT, it);
1090 if ((ady > adx) && (!it->wd->drag_started))
1091 evas_object_smart_callback_call(WIDGET(it),
1092 SIG_DRAG_START_DOWN, it);
1096 evas_object_smart_callback_call(WIDGET(it),
1097 SIG_DRAG_START_LEFT, it);
1099 evas_object_smart_callback_call(WIDGET(it),
1100 SIG_DRAG_START_RIGHT, it);
1107 _long_press(void *data)
1109 Elm_Gen_Item *it = data, *it_tmp;
1110 Eina_List *list, *l;
1112 it->long_timer = NULL;
1113 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1114 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1115 return ECORE_CALLBACK_CANCEL;
1116 it->wd->longpressed = EINA_TRUE;
1117 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1118 if ((it->wd->reorder_mode) && (!it->group))
1120 it->wd->reorder_it = it;
1121 it->wd->reorder_start_y = 0;
1122 if (it->deco_all_view)
1123 evas_object_raise(it->deco_all_view);
1125 evas_object_raise(VIEW(it));
1127 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1128 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1130 list = elm_genlist_realized_items_get(it->wd->obj);
1131 EINA_LIST_FOREACH(list, l, it_tmp)
1133 if (it != it_tmp) _item_unselect(it_tmp);
1135 if (it->item->items)
1137 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
1139 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
1141 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
1143 return ECORE_CALLBACK_RENEW;
1147 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1149 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1150 return ECORE_CALLBACK_RENEW;
1153 if (!it->wd->decorate_all_mode)
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 _mouse_down(void *data,
1339 Evas *evas __UNUSED__,
1343 Elm_Gen_Item *it = data;
1344 Evas_Event_Mouse_Down *ev = event_info;
1347 Evas_Object *item_obj;
1349 if (ev->button != 1) return;
1352 EINA_LIST_FOREACH(it->content_objs, l, item_obj)
1354 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1356 if (elm_widget_type_get(obj) == _genlist)
1358 EINA_LIST_FOREACH(it->item->flip_content_objs, l, item_obj)
1360 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1362 EINA_LIST_FOREACH(it->item->deco_all_content_objs, l, item_obj)
1364 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1367 it->can_focus = EINA_TRUE;
1369 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1371 it->wd->on_hold = EINA_TRUE;
1374 it->down = EINA_TRUE;
1375 it->dragging = EINA_FALSE;
1376 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1377 it->dx = ev->canvas.x - x;
1378 it->dy = ev->canvas.y - y;
1379 it->wd->mouse_down = EINA_TRUE;
1380 if (!it->wd->multitouched)
1382 it->wd->prev_x = ev->canvas.x;
1383 it->wd->prev_y = ev->canvas.y;
1384 it->wd->multi_timeout = EINA_FALSE;
1385 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1386 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1388 it->wd->longpressed = EINA_FALSE;
1389 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1390 else it->wd->on_hold = EINA_FALSE;
1391 if (it->wd->on_hold) return;
1392 it->wd->wasselected = it->selected;
1393 _item_highlight(it);
1394 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1395 if ((!elm_widget_item_disabled_get(it)) &&
1396 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1398 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1399 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1401 if (it->long_timer) ecore_timer_del(it->long_timer);
1402 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1403 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1405 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1408 it->long_timer = NULL;
1409 it->wd->swipe = EINA_FALSE;
1410 it->wd->movements = 0;
1414 _mouse_up(void *data,
1415 Evas *evas __UNUSED__,
1416 Evas_Object *obj __UNUSED__,
1419 Elm_Gen_Item *it = data;
1420 Evas_Event_Mouse_Up *ev = event_info;
1421 Eina_Bool dragged = EINA_FALSE;
1423 if (ev->button != 1) return;
1424 it->down = EINA_FALSE;
1425 it->wd->mouse_down = EINA_FALSE;
1426 if (it->wd->multitouched)
1428 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1429 if (it->wd->multi_down) return;
1430 _multi_touch_gesture_eval(data);
1433 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1434 else it->wd->on_hold = EINA_FALSE;
1437 ecore_timer_del(it->long_timer);
1438 it->long_timer = NULL;
1442 it->dragging = EINA_FALSE;
1443 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1446 if (it->item->swipe_timer)
1448 ecore_timer_del(it->item->swipe_timer);
1449 it->item->swipe_timer = NULL;
1451 if (it->wd->multi_timer)
1453 ecore_timer_del(it->wd->multi_timer);
1454 it->wd->multi_timer = NULL;
1455 it->wd->multi_timeout = EINA_FALSE;
1457 if (it->wd->on_hold)
1459 if (it->wd->swipe) _swipe(data);
1460 it->wd->longpressed = EINA_FALSE;
1461 it->wd->on_hold = EINA_FALSE;
1464 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1466 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1467 it->wd->reorder_fast = 0;
1469 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1471 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1472 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1474 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1475 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1479 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1480 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1482 it->wd->reorder_deleted = EINA_FALSE;
1483 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1484 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1485 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1486 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1488 if (it->wd->longpressed)
1490 it->wd->longpressed = EINA_FALSE;
1491 if ((!it->wd->wasselected) && (!it->flipped))
1493 _item_unhighlight(it);
1496 it->wd->wasselected = EINA_FALSE;
1501 if (it->want_unrealize)
1503 _elm_genlist_item_unrealize(it, EINA_FALSE);
1504 if (it->item->block->want_unrealize)
1505 _item_block_unrealize(it->item->block);
1508 if (elm_widget_item_disabled_get(it) || (dragged) ||
1509 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1511 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1516 _item_highlight(it);
1521 _item_unhighlight(it);
1529 Widget_Data *wd = it->wd;
1532 while (wd->selected)
1534 _item_unhighlight(wd->selected->data);
1535 _item_unselect(wd->selected->data);
1541 const Eina_List *l, *l_next;
1544 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1547 _item_unhighlight(it2);
1548 _item_unselect(it2);
1550 //_item_highlight(it);
1553 _item_highlight(it);
1559 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1561 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1563 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1565 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1567 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1569 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1571 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1576 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1578 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1580 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1582 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1584 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1586 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1588 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1594 _mouse_down_scroller(void *data,
1595 Evas *evas __UNUSED__,
1596 Evas_Object *obj __UNUSED__,
1597 void *event_info __UNUSED__)
1599 Widget_Data *wd = elm_widget_data_get(data);
1602 wd->drag_started = EINA_FALSE;
1606 _mouse_up_scroller(void *data,
1607 Evas *evas __UNUSED__,
1608 Evas_Object *obj __UNUSED__,
1609 void *event_info __UNUSED__)
1611 Widget_Data *wd = elm_widget_data_get(data);
1614 wd->drag_started = EINA_FALSE;
1618 _mouse_move_scroller(void *data,
1619 Evas *evas __UNUSED__,
1620 Evas_Object *obj __UNUSED__,
1623 Widget_Data *wd = elm_widget_data_get(data);
1624 Evas_Event_Mouse_Move *ev = event_info;
1625 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
1628 if (wd->drag_started) return;
1630 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1631 dx = ev->cur.canvas.x - ev->prev.canvas.x;
1632 dy = ev->cur.canvas.y - ev->prev.canvas.y;
1635 if (adx < 0) adx = -dx;
1636 if (ady < 0) ady = -dy;
1637 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
1641 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
1642 wd->drag_started = EINA_TRUE;
1646 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
1647 wd->drag_started = EINA_TRUE;
1653 _signal_expand_toggle(void *data,
1654 Evas_Object *obj __UNUSED__,
1655 const char *emission __UNUSED__,
1656 const char *source __UNUSED__)
1658 Elm_Gen_Item *it = data;
1660 if (it->item->expanded)
1661 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1663 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1667 _signal_expand(void *data,
1668 Evas_Object *obj __UNUSED__,
1669 const char *emission __UNUSED__,
1670 const char *source __UNUSED__)
1672 Elm_Gen_Item *it = data;
1674 if (!it->item->expanded)
1675 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1679 _signal_contract(void *data,
1680 Evas_Object *obj __UNUSED__,
1681 const char *emission __UNUSED__,
1682 const char *source __UNUSED__)
1684 Elm_Gen_Item *it = data;
1686 if (it->item->expanded)
1687 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1691 _scr_hold_timer_cb(void *data)
1693 if (!data) return ECORE_CALLBACK_CANCEL;
1694 Widget_Data *wd = data;
1695 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1696 wd->scr_hold_timer = NULL;
1697 return ECORE_CALLBACK_CANCEL;
1701 _decorate_item_finished_signal_cb(void *data,
1703 const char *emission __UNUSED__,
1704 const char *source __UNUSED__)
1708 Elm_Gen_Item *it = data;
1709 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1711 Evas *te = evas_object_evas_get(obj);
1713 evas_event_freeze(te);
1714 it->item->nocache_once = EINA_FALSE;
1715 _decorate_item_unrealize(it);
1716 //FIXME: group raise
1718 if (it->item->group_item)
1719 evas_object_raise(it->item->VIEW(group_item));
1721 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1722 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1723 evas_event_thaw(te);
1724 evas_event_thaw_eval(te);
1728 _item_cache_clean(Widget_Data *wd)
1730 evas_event_freeze(evas_object_evas_get(wd->obj));
1731 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1735 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1736 wd->item_cache = eina_inlist_remove(wd->item_cache,
1737 wd->item_cache->last);
1738 wd->item_cache_count--;
1739 if (itc->spacer) evas_object_del(itc->spacer);
1740 if (itc->base_view) evas_object_del(itc->base_view);
1741 eina_stringshare_del(itc->item_style);
1744 evas_event_thaw(evas_object_evas_get(wd->obj));
1745 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1749 _item_cache_zero(Widget_Data *wd)
1751 int pmax = wd->item_cache_max;
1752 wd->item_cache_max = 0;
1753 _item_cache_clean(wd);
1754 wd->item_cache_max = pmax;
1758 _item_cache_add(Elm_Gen_Item *it)
1762 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1763 if (it->wd->item_cache_max <= 0)
1765 evas_object_del(VIEW(it));
1769 evas_object_del(it->spacer);
1772 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1773 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1777 it->wd->item_cache_count++;
1778 itc = calloc(1, sizeof(Item_Cache));
1781 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1782 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1785 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1786 EINA_INLIST_GET(itc));
1787 itc->spacer = it->spacer;
1789 itc->base_view = VIEW(it);
1791 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1792 evas_object_hide(itc->base_view);
1793 evas_object_move(itc->base_view, -9999, -9999);
1794 itc->item_style = eina_stringshare_add(it->itc->item_style);
1795 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1796 itc->selected = it->selected;
1797 itc->disabled = elm_widget_item_disabled_get(it);
1798 itc->expanded = it->item->expanded;
1801 ecore_timer_del(it->long_timer);
1802 it->long_timer = NULL;
1804 if (it->item->swipe_timer)
1806 ecore_timer_del(it->item->swipe_timer);
1807 it->item->swipe_timer = NULL;
1809 // FIXME: other callbacks?
1810 edje_object_signal_callback_del_full(itc->base_view,
1811 "elm,action,expand,toggle",
1812 "elm", _signal_expand_toggle, it);
1813 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1815 _signal_expand, it);
1816 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1817 "elm", _signal_contract, it);
1818 _item_mouse_callbacks_del(it, itc->base_view);
1819 _item_cache_clean(it->wd);
1820 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1821 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1825 _item_cache_find(Elm_Gen_Item *it)
1830 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1831 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1833 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1835 if ((itc->tree == tree) &&
1836 (((!it->itc->item_style) && (!itc->item_style)) ||
1837 (it->itc->item_style && itc->item_style &&
1838 (!strcmp(it->itc->item_style, itc->item_style)))))
1840 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1841 EINA_INLIST_GET(itc));
1842 it->wd->item_cache_count--;
1850 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1852 if (it->position_update || it->item->block->position_update)
1854 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1855 it->position_update = EINA_FALSE;
1860 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1862 if (!it->item->nostacking)
1864 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1866 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1867 else evas_object_lower(VIEW(it));
1871 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1872 else evas_object_raise(VIEW(it));
1876 if (it->item->order_num_in & 0x1)
1878 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1879 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1883 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1884 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1889 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1893 if (it->selected != itc->selected)
1897 edje_object_signal_emit(VIEW(it),
1898 "elm,state,selected", "elm");
1899 if (it->deco_all_view)
1900 edje_object_signal_emit(it->deco_all_view,
1901 "elm,state,selected", "elm");
1904 if (elm_widget_item_disabled_get(it) != itc->disabled)
1906 if (elm_widget_item_disabled_get(it))
1907 edje_object_signal_emit(VIEW(it),
1908 "elm,state,disabled", "elm");
1909 if (it->deco_all_view)
1910 edje_object_signal_emit(it->deco_all_view,
1911 "elm,state,disabled", "elm");
1913 if (it->item->expanded != itc->expanded)
1915 if (it->item->expanded)
1916 edje_object_signal_emit(VIEW(it),
1917 "elm,state,expanded", "elm");
1918 if (it->deco_all_view)
1919 edje_object_signal_emit(it->deco_all_view,
1920 "elm,state,expanded", "elm");
1927 edje_object_signal_emit(VIEW(it),
1928 "elm,state,selected", "elm");
1929 if (it->deco_all_view)
1930 edje_object_signal_emit(it->deco_all_view,
1931 "elm,state,selected", "elm");
1933 if (elm_widget_item_disabled_get(it))
1935 edje_object_signal_emit(VIEW(it),
1936 "elm,state,disabled", "elm");
1937 if (it->deco_all_view)
1938 edje_object_signal_emit(it->deco_all_view,
1939 "elm,state,disabled", "elm");
1941 if (it->item->expanded)
1943 edje_object_signal_emit(VIEW(it),
1944 "elm,state,expanded", "elm");
1945 if (it->deco_all_view)
1946 edje_object_signal_emit(it->deco_all_view,
1947 "elm,state,expanded", "elm");
1953 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1955 Elm_Gen_Item *it = data;
1956 if (it) it->defer_unrealize = EINA_TRUE;
1960 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1962 Elm_Gen_Item *it = data;
1963 if (it) it->defer_unrealize = EINA_FALSE;
1968 _item_mode_content_realize(Elm_Gen_Item *it,
1969 Evas_Object *target,
1972 Eina_List **contents_list)
1974 Eina_List *res = *contents_list;
1976 if (it->itc->func.content_get)
1982 EINA_LIST_FOREACH(*source, l, key)
1984 if (parts && fnmatch(parts, key, FNM_PERIOD))
1987 ic = it->itc->func.content_get
1988 ((void *)it->base.data, WIDGET(it), key);
1992 res = eina_list_append(res, ic);
1993 edje_object_part_swallow(target, key, ic);
1994 evas_object_show(ic);
1995 elm_widget_sub_object_add(WIDGET(it), ic);
1998 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1999 // genlist does not need to handle this focus thing.
2000 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2001 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2003 if (elm_widget_item_disabled_get(it))
2004 elm_widget_disabled_set(ic, EINA_TRUE);
2013 _item_mode_content_unrealize(Elm_Gen_Item *it,
2014 Evas_Object *target,
2017 Eina_List **contents_list)
2019 Eina_List *res = *contents_list;
2021 if (it->itc->func.content_get)
2025 Evas_Object *ic = NULL;
2027 EINA_LIST_FOREACH(*source, l, key)
2029 if (parts && fnmatch(parts, key, FNM_PERIOD))
2032 ic = edje_object_part_swallow_get(target, key);
2035 res = eina_list_remove(res, ic);
2036 edje_object_part_unswallow(target, ic);
2037 evas_object_del(ic);
2046 _item_cache_free(Item_Cache *itc)
2048 if (itc->spacer) evas_object_del(itc->spacer);
2049 if (itc->base_view) evas_object_del(itc->base_view);
2050 eina_stringshare_del(itc->item_style);
2055 _item_text_realize(Elm_Gen_Item *it,
2056 Evas_Object *target,
2060 if (it->itc->func.text_get)
2066 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
2067 EINA_LIST_FOREACH(*source, l, key)
2069 if (parts && fnmatch(parts, key, FNM_PERIOD))
2072 char *s = it->itc->func.text_get
2073 ((void *)it->base.data, WIDGET(it), key);
2077 edje_object_part_text_escaped_set(target, key, s);
2082 edje_object_part_text_set(target, key, "");
2089 _item_content_unrealize(Elm_Gen_Item *it,
2090 Evas_Object *target,
2094 Eina_List *res = it->content_objs;
2096 if (it->itc->func.content_get)
2100 Evas_Object *ic = NULL;
2102 EINA_LIST_FOREACH(*source, l, key)
2104 if (parts && fnmatch(parts, key, FNM_PERIOD))
2107 ic = edje_object_part_swallow_get(target, key);
2110 res = eina_list_remove(res, ic);
2111 edje_object_part_unswallow(target, ic);
2112 evas_object_del(ic);
2121 _item_content_realize(Elm_Gen_Item *it,
2122 Evas_Object *target,
2126 Eina_List *res = it->content_objs;
2128 if (it->itc->func.content_get)
2132 Evas_Object *ic = NULL;
2135 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
2137 EINA_LIST_FOREACH(*source, l, key)
2139 if (parts && fnmatch(parts, key, FNM_PERIOD))
2142 if (it->itc->func.content_get)
2143 ic = it->itc->func.content_get
2144 ((void *)it->base.data, WIDGET(it), key);
2147 res = eina_list_append(res, ic);
2148 edje_object_part_swallow(target, key, ic);
2149 evas_object_show(ic);
2150 elm_widget_sub_object_add(WIDGET(it), ic);
2151 evas_object_event_callback_add(ic,
2152 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2153 _changed_size_hints, it);
2156 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2157 // genlist does not need to handle this focus thing.
2158 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2159 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2162 if (elm_widget_item_disabled_get(it))
2163 elm_widget_disabled_set(ic, EINA_TRUE);
2172 _item_state_realize(Elm_Gen_Item *it,
2173 Evas_Object *target,
2177 if (it->itc->func.state_get)
2184 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2185 EINA_LIST_FOREACH(*source, l, key)
2187 if (parts && fnmatch(parts, key, FNM_PERIOD))
2190 Eina_Bool on = it->itc->func.state_get
2191 ((void *)it->base.data, WIDGET(it), key);
2195 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2196 edje_object_signal_emit(target, buf, "elm");
2200 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2201 edje_object_signal_emit(target, buf, "elm");
2208 _item_order_update(const Eina_Inlist *l, int start)
2210 Elm_Gen_Item *it, *it2;
2212 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next, it = ELM_GEN_ITEM_FROM_INLIST(l))
2214 it->item->order_num_in = start++;
2215 _elm_genlist_item_odd_even_update(it);
2216 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
2217 if (it2 && (it->item->order_num_in != it2->item->order_num_in)) return;
2222 _item_realize(Elm_Gen_Item *it,
2226 const char *treesize;
2229 Item_Cache *itc = NULL;
2231 if (it->generation < it->wd->generation) return;
2232 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2235 if (it->item->order_num_in != in)
2237 _item_order_update(EINA_INLIST_GET(it), in);
2238 _elm_genlist_item_state_update(it, NULL);
2239 _elm_genlist_item_index_update(it);
2241 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2242 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2245 it->item->order_num_in = in;
2247 if ((it->item->nocache_once) && (!it->flipped))
2248 it->item->nocache_once = EINA_FALSE;
2249 else if (!it->item->nocache)
2250 itc = _item_cache_find(it);
2251 if (itc && (!it->wd->tree_effect_enabled))
2253 VIEW(it) = itc->base_view;
2254 itc->base_view = NULL;
2255 it->spacer = itc->spacer;
2260 const char *stacking_even;
2261 const char *stacking;
2263 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2264 edje_object_scale_set(VIEW(it),
2265 elm_widget_scale_get(WIDGET(it)) *
2266 _elm_config->scale);
2267 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2268 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2270 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2271 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2273 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2275 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2276 elm_widget_style_get(WIDGET(it)));
2278 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2279 if (!stacking_even) stacking_even = "above";
2280 it->item->stacking_even = !!strcmp("above", stacking_even);
2282 stacking = edje_object_data_get(VIEW(it), "stacking");
2283 if (!stacking) stacking = "yes";
2284 it->item->nostacking = !!strcmp("yes", stacking);
2286 edje_object_mirrored_set(VIEW(it),
2287 elm_widget_mirrored_get(WIDGET(it)));
2290 _item_order_update(EINA_INLIST_GET(it), in);
2292 treesize = edje_object_data_get(VIEW(it), "treesize");
2293 if (treesize) tsize = atoi(treesize);
2294 if (!it->spacer && treesize)
2297 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2298 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2299 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2303 evas_object_size_hint_min_set(it->spacer,
2304 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2305 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2309 edje_object_signal_callback_add(VIEW(it),
2310 "elm,action,expand,toggle",
2311 "elm", _signal_expand_toggle, it);
2312 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2313 "elm", _signal_expand, it);
2314 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2315 "elm", _signal_contract, it);
2316 _item_mouse_callbacks_add(it, VIEW(it));
2318 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2319 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2320 _decorate_all_item_realize(it, EINA_FALSE);
2322 _elm_genlist_item_state_update(it, itc);
2323 _elm_genlist_item_index_update(it);
2326 if ((calc) && (it->wd->homogeneous) &&
2327 ((it->wd->item_width) ||
2328 ((it->wd->item_width) && (it->wd->group_item_width))))
2330 /* homogenous genlist shortcut */
2331 if (!it->item->mincalcd)
2335 it->item->w = it->item->minw = it->wd->group_item_width;
2336 it->item->h = it->item->minh = it->wd->group_item_height;
2340 it->item->w = it->item->minw = it->wd->item_width;
2341 it->item->h = it->item->minh = it->wd->item_height;
2343 it->item->mincalcd = EINA_TRUE;
2348 /* FIXME: If you see that assert, please notify us and we
2349 will clean our mess */
2350 assert(eina_list_count(it->content_objs) == 0);
2352 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2353 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2354 _item_state_realize(it, VIEW(it), &it->states, NULL);
2357 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2358 if (!(it->item->flip_contents))
2359 it->item->flip_contents =
2360 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2361 it->item->flip_content_objs =
2362 _item_mode_content_realize(it, VIEW(it),
2363 &it->item->flip_contents, NULL,
2364 &it->item->flip_content_objs);
2367 if (!it->item->mincalcd || ((it->wd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
2369 Evas_Coord mw = -1, mh = -1;
2371 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2372 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2373 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2374 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2376 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2377 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2378 it->item->w = it->item->minw = mw;
2379 it->item->h = it->item->minh = mh;
2380 it->item->mincalcd = EINA_TRUE;
2382 if ((!it->wd->group_item_width) && (it->group))
2384 it->wd->group_item_width = mw;
2385 it->wd->group_item_height = mh;
2387 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2389 it->wd->item_width = mw;
2390 it->wd->item_height = mh;
2393 if (!calc) evas_object_show(VIEW(it));
2396 if (it->tooltip.content_cb)
2398 elm_widget_item_tooltip_content_cb_set(it,
2399 it->tooltip.content_cb,
2400 it->tooltip.data, NULL);
2401 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2402 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2405 if (it->mouse_cursor)
2406 elm_widget_item_cursor_set(it, it->mouse_cursor);
2408 it->realized = EINA_TRUE;
2409 it->want_unrealize = EINA_FALSE;
2411 if (itc) _item_cache_free(itc);
2412 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2413 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2416 if (it->item->tree_effect_hideme)
2418 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2419 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2420 it->item->tree_effect_hideme = EINA_FALSE;
2422 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2425 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2427 if (it->itc->decorate_all_item_style)
2429 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2430 edje_object_message_signal_process(it->deco_all_view);
2433 edje_object_message_signal_process(VIEW(it));
2437 _item_unrealize_cb(Elm_Gen_Item *it)
2439 Evas_Object *content;
2440 elm_widget_stringlist_free(it->item->flip_contents);
2441 it->item->flip_contents = NULL;
2442 EINA_LIST_FREE(it->item->flip_content_objs, content)
2443 evas_object_del(content);
2445 // unswallow VIEW(it) first then manipulate VIEW(it)
2446 _decorate_item_unrealize(it);
2447 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2449 if (it->item->nocache_once || it->item->nocache)
2451 evas_object_del(VIEW(it));
2455 evas_object_del(it->spacer);
2461 edje_object_mirrored_set(VIEW(it),
2462 elm_widget_mirrored_get(WIDGET(it)));
2463 edje_object_scale_set(VIEW(it),
2464 elm_widget_scale_get(WIDGET(it))
2465 * _elm_config->scale);
2466 _item_cache_add(it);
2470 it->realized = EINA_FALSE;
2471 it->want_unrealize = EINA_FALSE;
2475 _item_block_recalc(Item_Block *itb,
2481 Evas_Coord minw = 0, minh = 0;
2482 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2485 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2487 EINA_LIST_FOREACH(itb->items, l, it)
2489 if (it->generation < it->wd->generation) continue;
2490 showme |= it->item->showme;
2495 if (!it->item->mincalcd) changed = EINA_TRUE;
2498 _item_realize(it, in, EINA_TRUE);
2499 _elm_genlist_item_unrealize(it, EINA_TRUE);
2504 if ((itb->wd->homogeneous) &&
2505 (itb->wd->mode == ELM_LIST_COMPRESS))
2509 it->item->w = it->item->minw = it->wd->group_item_width;
2510 it->item->h = it->item->minh = it->wd->group_item_height;
2514 it->item->w = it->item->minw = it->wd->item_width;
2515 it->item->h = it->item->minh = it->wd->item_height;
2520 _item_realize(it, in, EINA_TRUE);
2521 _elm_genlist_item_unrealize(it, EINA_TRUE);
2527 if (!it->item->mincalcd) changed = EINA_TRUE;
2528 _item_realize(it, in, EINA_FALSE);
2530 minh += it->item->minh;
2531 if (minw < it->item->minw) minw = it->item->minw;
2537 if (changed) itb->wd->pan_changed = changed;
2540 itb->changed = EINA_FALSE;
2541 itb->position_update = EINA_FALSE;
2542 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2543 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2548 _item_block_realize(Item_Block *itb)
2550 if (itb->realized) return;
2551 itb->realized = EINA_TRUE;
2552 itb->want_unrealize = EINA_FALSE;
2556 _item_block_unrealize(Item_Block *itb)
2560 Eina_Bool dragging = EINA_FALSE;
2562 if (!itb->realized) return;
2563 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2564 EINA_LIST_FOREACH(itb->items, l, it)
2566 if (itb->must_recalc || !it->group)
2570 dragging = EINA_TRUE;
2571 it->want_unrealize = EINA_TRUE;
2574 _elm_genlist_item_unrealize(it, EINA_FALSE);
2579 itb->realized = EINA_FALSE;
2580 itb->want_unrealize = EINA_TRUE;
2583 itb->want_unrealize = EINA_FALSE;
2584 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2585 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2589 _get_space_for_reorder_item(Elm_Gen_Item *it)
2591 Evas_Coord rox, roy, row, roh, oy, oh;
2592 Eina_Bool top = EINA_FALSE;
2593 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2594 if (!reorder_it) return 0;
2596 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2597 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2599 if ((it->wd->reorder_start_y < it->item->block->y) &&
2600 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2602 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2603 if (it->item->block->count == 1)
2604 it->wd->reorder_rel = it;
2606 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2607 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2609 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2612 it->item->block->reorder_offset = 0;
2614 it->item->scrl_y += it->item->block->reorder_offset;
2616 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2617 rox, roy + (roh / 2), row, 1));
2620 it->wd->reorder_rel = it;
2621 it->item->scrl_y += it->wd->reorder_it->item->h;
2622 return it->wd->reorder_it->item->h;
2629 _reorder_move_animator_cb(void *data)
2631 Elm_Gen_Item *it = data;
2632 Eina_Bool down = EINA_FALSE;
2634 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2636 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2638 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2641 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2642 if (diff > it->item->h) y = diff / 2;
2644 if (it->item->old_scrl_y < it->item->scrl_y)
2646 it->item->old_scrl_y += y;
2649 else if (it->item->old_scrl_y > it->item->scrl_y)
2651 it->item->old_scrl_y -= y;
2655 if (it->deco_all_view)
2656 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2658 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2659 //FIXME : group raise
2661 _group_items_recalc(it->wd);
2664 if ((it->wd->reorder_pan_move) ||
2665 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2666 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2668 it->item->old_scrl_y = it->item->scrl_y;
2669 it->item->move_effect_enabled = EINA_FALSE;
2670 it->wd->reorder_move_animator = NULL;
2671 return ECORE_CALLBACK_CANCEL;
2673 return ECORE_CALLBACK_RENEW;
2677 _item_position(Elm_Gen_Item *it,
2685 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2686 evas_object_resize(view, it->item->w, it->item->h);
2687 evas_object_move(view, it_x, it_y);
2688 evas_object_show(view);
2689 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2690 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2694 _item_block_position(Item_Block *itb,
2699 //FIXME : group raise
2703 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2704 Eina_Bool vis = EINA_FALSE;
2705 Evas_Coord minh = 0;
2707 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2708 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2709 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2711 EINA_LIST_FOREACH(itb->items, l, it)
2713 if (it->generation < it->wd->generation) continue;
2714 else if (it->wd->reorder_it == it) continue;
2717 it->item->w = itb->w;
2718 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2719 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2721 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2722 cvx, cvy, cvw, cvh));
2723 //FIXME : group raise
2728 if ((itb->realized) && (!it->realized))
2730 if (vis) _item_realize(it, in, EINA_FALSE);
2734 if (vis || it->dragging)
2736 if (it->wd->reorder_mode)
2737 y += _get_space_for_reorder_item(it);
2738 //FIXME : group raise
2740 git = it->item->group_item;
2743 if (git->item->scrl_y < oy)
2744 git->item->scrl_y = oy;
2745 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2746 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2747 git->item->want_realize = EINA_TRUE;
2750 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2752 if (!it->item->move_effect_enabled)
2754 it->item->move_effect_enabled = EINA_TRUE;
2755 it->wd->reorder_move_animator =
2757 _reorder_move_animator_cb, it);
2760 if (!it->item->move_effect_enabled)
2762 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2763 _decorate_all_item_position(it, it->item->scrl_x,
2767 if (!it->wd->tree_effect_enabled ||
2768 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2769 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2770 (it->item->old_scrl_y == it->item->scrl_y)))
2772 if (it->item->deco_it_view)
2773 _item_position(it, it->item->deco_it_view,
2777 _item_position(it, VIEW(it), it->item->scrl_x,
2781 it->item->old_scrl_y = it->item->scrl_y;
2786 if (!it->wd->tree_effect_animator)
2788 it->want_unrealize = EINA_TRUE;
2789 _elm_genlist_item_unrealize(it, EINA_FALSE);
2795 //FIXME : group raise
2799 if (vis) it->item->want_realize = EINA_TRUE;
2803 minh += it->item->minh;
2805 if (!itb->wd->reorder_it) itb->minh = minh;
2806 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2807 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2810 //FIXME: group raise
2813 _group_items_recalc(void *data)
2815 Widget_Data *wd = data;
2819 evas_event_freeze(evas_object_evas_get(wd->obj));
2820 EINA_LIST_FOREACH(wd->group_items, l, git)
2822 if (git->item->want_realize)
2825 _item_realize(git, 0, EINA_FALSE);
2826 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2827 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2828 evas_object_show(VIEW(git));
2829 evas_object_raise(VIEW(git));
2831 else if (!git->item->want_realize && git->realized)
2834 _elm_genlist_item_unrealize(git, EINA_FALSE);
2837 evas_event_thaw(evas_object_evas_get(wd->obj));
2838 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2843 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2845 Elm_Gen_Item *it = data;
2847 if (it->want_unrealize) return;
2848 it->item->mincalcd = EINA_FALSE;
2849 it->item->block->changeme = EINA_TRUE;
2850 if (it->wd->changed_job) ecore_job_del(it->wd->changed_job);
2851 it->wd->changed_job = ecore_job_add(_changed_job, it->wd);
2855 _must_recalc_idler(void *data)
2857 Widget_Data *wd = data;
2858 if (wd->calc_job) ecore_job_del(wd->calc_job);
2859 wd->calc_job = ecore_job_add(_calc_job, wd);
2860 wd->must_recalc_idler = NULL;
2861 return ECORE_CALLBACK_CANCEL;
2865 _scroll_item(Widget_Data *wd)
2867 Elm_Gen_Item *it = NULL;
2868 //FIXME: group raise
2870 Evas_Coord gith = 0;
2872 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2873 if (!wd->show_item) return;
2875 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2877 dx = it->x + it->item->block->x;
2878 dy = it->y + it->item->block->y;
2879 dw = it->item->block->w;
2881 switch (wd->scrollto_type)
2883 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2884 //FIXME: group raise
2886 if (it->item->group_item) gith = it->item->group_item->item->h;
2890 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2891 dy += ((it->item->h / 2) - (oh / 2));
2893 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2895 if ((wd->expanded_item) &&
2896 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2897 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2899 it = wd->expanded_item;
2900 dx = it->x + it->item->block->x;
2901 dy = it->y + it->item->block->y;
2902 //FIXME: group raise
2904 if (it->item->group_item) gith = it->item->group_item->item->h;
2905 dx = it->x + it->item->block->x;
2906 dy = it->y + it->item->block->y - gith;
2908 dw = it->item->block->w;
2912 //FIXME: group raise
2914 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2915 gith = it->item->group_item->item->h;
2923 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2925 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2927 it->item->showme = EINA_FALSE;
2928 wd->show_item = NULL;
2929 wd->auto_scroll_enabled = EINA_FALSE;
2930 wd->check_scroll = EINA_FALSE;
2934 _calc_job(void *data)
2936 Widget_Data *wd = data;
2937 Item_Block *itb, *chb = NULL;
2938 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2939 Evas_Coord pan_w = 0, pan_h = 0;
2941 Eina_Bool minw_change = EINA_FALSE;
2942 Eina_Bool did_must_recalc = EINA_FALSE;
2945 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2946 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2951 evas_event_freeze(evas_object_evas_get(wd->obj));
2952 EINA_INLIST_FOREACH(wd->blocks, itb)
2954 Eina_Bool showme = EINA_FALSE;
2957 showme = itb->showme;
2958 itb->showme = EINA_FALSE;
2961 if (itb->realized) _item_block_unrealize(itb);
2963 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2965 if (itb->must_recalc)
2969 EINA_LIST_FOREACH(itb->items, l, it)
2970 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2971 itb->changed = EINA_TRUE;
2972 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2973 if (itb->realized) _item_block_unrealize(itb);
2974 itb->must_recalc = EINA_FALSE;
2976 showme = _item_block_recalc(itb, in, EINA_FALSE);
2982 if (minw == -1) minw = itb->minw;
2983 else if ((!itb->must_recalc) && (minw < itb->minw))
2986 minw_change = EINA_TRUE;
2991 minw_change = EINA_TRUE;
2997 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2998 wd->check_scroll = EINA_TRUE;
3002 EINA_INLIST_FOREACH(wd->blocks, itb)
3008 if ((chb) && (EINA_INLIST_GET(chb)->next))
3010 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
3012 if (itb->realized) _item_block_unrealize(itb);
3015 wd->realminw = minw;
3016 if (minw < wd->w) minw = wd->w;
3017 if ((minw != wd->minw) || (minh != wd->minh))
3021 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3022 _sizing_eval(wd->obj);
3023 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
3028 it = wd->anchor_item;
3029 it_y = wd->anchor_y;
3030 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
3031 it->item->block->y + it->y + it_y);
3032 wd->anchor_item = it;
3033 wd->anchor_y = it_y;
3036 if (did_must_recalc)
3038 if (!wd->must_recalc_idler)
3039 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
3041 if (wd->check_scroll)
3043 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
3044 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
3045 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3046 switch (wd->scrollto_type)
3048 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
3051 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
3054 case ELM_GENLIST_ITEM_SCROLLTO_IN:
3059 if ((wd->show_item) && (wd->show_item->item->block))
3061 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
3062 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
3068 wd->calc_job = NULL;
3069 evas_object_smart_changed(wd->pan_smart);
3070 evas_event_thaw(evas_object_evas_get(wd->obj));
3071 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3075 _update_job(void *data)
3077 Widget_Data *wd = data;
3081 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
3083 wd->update_job = NULL;
3086 evas_event_freeze(evas_object_evas_get(wd->obj));
3087 EINA_INLIST_FOREACH(wd->blocks, itb)
3089 Evas_Coord itminw, itminh;
3096 _item_block_position(itb, num);
3100 recalc = EINA_FALSE;
3101 EINA_LIST_FOREACH(itb->items, l2, it)
3103 if (it->item->updateme)
3105 itminw = it->item->minw;
3106 itminh = it->item->minh;
3110 _elm_genlist_item_unrealize(it, EINA_FALSE);
3111 _item_realize(it, num, EINA_FALSE);
3112 position = EINA_TRUE;
3116 _item_realize(it, num, EINA_TRUE);
3117 _elm_genlist_item_unrealize(it, EINA_TRUE);
3119 if ((it->item->minw != itminw) || (it->item->minh != itminh))
3121 it->item->updateme = EINA_FALSE;
3125 itb->updateme = EINA_FALSE;
3128 position = EINA_TRUE;
3129 itb->changed = EINA_TRUE;
3130 _item_block_recalc(itb, num0, EINA_FALSE);
3131 _item_block_position(itb, num0);
3136 if (wd->calc_job) ecore_job_del(wd->calc_job);
3137 wd->calc_job = ecore_job_add(_calc_job, wd);
3139 evas_event_thaw(evas_object_evas_get(wd->obj));
3140 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3144 _changed_job(void *data)
3146 Widget_Data *wd = data; Eina_List *l2;
3148 int num, num0, position = 0;
3149 Eina_Bool width_changed = EINA_FALSE, height_changed = EINA_FALSE;
3151 wd->changed_job = NULL;
3153 EINA_INLIST_FOREACH(wd->blocks, itb)
3155 Evas_Coord itminw, itminh;
3162 _item_block_position(itb, num);
3166 width_changed = height_changed = EINA_FALSE;
3167 EINA_LIST_FOREACH(itb->items, l2, it)
3169 if ((!it->item->mincalcd) && (it->realized))
3171 Evas_Coord mw = -1, mh = -1;
3172 itminw = it->item->minw;
3173 itminh = it->item->minh;
3175 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->w;
3176 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3177 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3178 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
3179 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
3180 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3181 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3183 width_changed = EINA_TRUE;
3186 it->item->w = it->item->minw = mw;
3187 it->item->h = it->item->minh = mh;
3188 it->item->mincalcd = EINA_TRUE;
3190 //if ((it->item->minw != itminw) || (it->item->minh != itminh))
3191 //if ((it->item->minh != itminh))
3193 if ((it->item->minw != itminw))
3194 width_changed = EINA_TRUE;
3195 if ((it->item->minh != itminh))
3196 height_changed = EINA_TRUE;
3198 if ((!it->wd->group_item_width) && (it->group))
3200 it->wd->group_item_width = mw;
3201 it->wd->group_item_height = mh;
3203 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
3205 it->wd->item_width = mw;
3206 it->wd->item_height = mh;
3211 itb->changeme = EINA_FALSE;
3212 // TODO: why this is separated.
3216 itb->changed = EINA_TRUE;
3217 _item_block_recalc(itb, num0, 0);
3218 _item_block_position(itb, num0);
3220 else if (width_changed)
3222 _item_block_position(itb, num0);
3227 if (wd->calc_job) ecore_job_del(wd->calc_job);
3228 wd->calc_job = ecore_job_add(_calc_job, wd);
3233 _viewport_coord_get(Widget_Data *wd,
3239 Evas_Coord x, y, w, h;
3240 EINA_SAFETY_ON_NULL_RETURN(wd);
3242 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
3243 elm_smart_scroller_child_viewport_size_get(wd->scr, &w, &h);
3245 if (w > wd->minw) x -= ((w - wd->minw) / 2);
3246 if (h > wd->minh) y -= ((h - wd->minh) / 2);
3255 _pan_set(Evas_Object *obj,
3259 Pan *sd = evas_object_smart_data_get(obj);
3263 // Evas_Coord ow, oh;
3264 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3265 // ow = sd->wd->minw - ow;
3266 // if (ow < 0) ow = 0;
3267 // oh = sd->wd->minh - oh;
3268 // if (oh < 0) oh = 0;
3269 // if (x < 0) x = 0;
3270 // if (y < 0) y = 0;
3271 // if (x > ow) x = ow;
3272 // if (y > oh) y = oh;
3273 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
3277 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3279 if ((itb->y + itb->h) > y)
3284 EINA_LIST_FOREACH(itb->items, l2, it)
3286 if ((itb->y + it->y) >= y)
3288 sd->wd->anchor_item = it;
3289 sd->wd->anchor_y = -(itb->y + it->y - y);
3296 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
3300 _pan_get(Evas_Object *obj,
3304 Pan *sd = evas_object_smart_data_get(obj);
3307 if (x) *x = sd->wd->pan_x;
3308 if (y) *y = sd->wd->pan_y;
3312 _pan_max_get(Evas_Object *obj,
3316 Pan *sd = evas_object_smart_data_get(obj);
3320 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3321 ow = sd->wd->minw - ow;
3323 oh = sd->wd->minh - oh;
3330 _pan_min_get(Evas_Object *obj __UNUSED__,
3339 _pan_child_size_get(Evas_Object *obj,
3343 Pan *sd = evas_object_smart_data_get(obj);
3346 if (w) *w = sd->wd->minw;
3347 if (h) *h = sd->wd->minh;
3351 _pan_add(Evas_Object *obj)
3354 Evas_Object_Smart_Clipped_Data *cd;
3357 cd = evas_object_smart_data_get(obj);
3360 sd->__clipped_data = *cd;
3362 evas_object_smart_data_set(obj, sd);
3366 _pan_del(Evas_Object *obj)
3368 Pan *sd = evas_object_smart_data_get(obj);
3373 ecore_job_del(sd->resize_job);
3374 sd->resize_job = NULL;
3380 _pan_resize_job(void *data)
3384 _sizing_eval(sd->wd->obj);
3385 sd->resize_job = NULL;
3389 _pan_resize(Evas_Object *obj,
3393 Pan *sd = evas_object_smart_data_get(obj);
3397 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3398 if ((ow == w) && (oh == h)) return;
3399 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3402 if (sd->resize_job) ecore_job_del(sd->resize_job);
3403 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3405 sd->wd->pan_changed = EINA_TRUE;
3406 evas_object_smart_changed(obj);
3407 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3408 sd->wd->calc_job = NULL;
3412 _pan_calculate(Evas_Object *obj)
3414 Pan *sd = evas_object_smart_data_get(obj);
3416 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3418 //FIXME: group raise
3425 evas_event_freeze(evas_object_evas_get(obj));
3427 if (sd->wd->pan_changed)
3430 sd->wd->pan_changed = EINA_FALSE;
3433 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3434 sd->wd->prev_viewport_w = ow;
3435 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3436 //FIXME: group raise
3438 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3440 git->item->want_realize = EINA_FALSE;
3444 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3446 if (!sd->wd->tree_effect_animator)
3448 _item_tree_effect_before(sd->wd->expanded_item);
3449 evas_object_raise(sd->wd->alpha_bg);
3450 evas_object_show(sd->wd->alpha_bg);
3451 sd->wd->start_time = ecore_time_get();
3452 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3456 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3458 itb->w = sd->wd->minw;
3459 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3460 itb->y - sd->wd->pan_y + oy,
3462 cvx, cvy, cvw, cvh))
3464 if ((!itb->realized) || (itb->changed))
3466 _item_block_realize(itb);
3468 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3469 sd->wd->calc_job = NULL;
3472 _item_block_position(itb, in);
3476 if (itb->realized) _item_block_unrealize(itb);
3480 //FIXME: group raise
3482 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3483 _group_items_recalc(sd->wd);
3485 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3487 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3488 sd->wd->reorder_pan_move = EINA_TRUE;
3489 else sd->wd->reorder_pan_move = EINA_FALSE;
3490 evas_object_raise(sd->wd->VIEW(reorder_it));
3491 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3492 sd->wd->start_time = ecore_loop_time_get();
3495 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3496 _item_auto_scroll(sd->wd);
3498 Evas_Coord vx, vy, vw, vh;
3499 _viewport_coord_get(sd->wd, &vx, &vy, &vw, &vh);
3501 if (sd->wd->reorder_fast == 1)
3502 elm_smart_scroller_child_region_show(sd->wd->scr, vx, vy - 10, vw, vh);
3503 else if (sd->wd->reorder_fast == -1)
3504 elm_smart_scroller_child_region_show(sd->wd->scr, vx, vy + 10, vw, vh);
3506 evas_event_thaw(evas_object_evas_get(obj));
3507 evas_event_thaw_eval(evas_object_evas_get(obj));
3511 _pan_move(Evas_Object *obj,
3512 Evas_Coord x __UNUSED__,
3513 Evas_Coord y __UNUSED__)
3515 Pan *sd = evas_object_smart_data_get(obj);
3519 sd->wd->pan_changed = EINA_TRUE;
3520 evas_object_smart_changed(obj);
3521 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3522 sd->wd->calc_job = NULL;
3526 _hold_on(void *data __UNUSED__,
3528 void *event_info __UNUSED__)
3530 Widget_Data *wd = elm_widget_data_get(obj);
3532 elm_smart_scroller_hold_set(wd->scr, 1);
3536 _hold_off(void *data __UNUSED__,
3538 void *event_info __UNUSED__)
3540 Widget_Data *wd = elm_widget_data_get(obj);
3542 elm_smart_scroller_hold_set(wd->scr, 0);
3546 _freeze_on(void *data __UNUSED__,
3548 void *event_info __UNUSED__)
3550 Widget_Data *wd = elm_widget_data_get(obj);
3552 elm_smart_scroller_freeze_set(wd->scr, 1);
3556 _freeze_off(void *data __UNUSED__,
3558 void *event_info __UNUSED__)
3560 Widget_Data *wd = elm_widget_data_get(obj);
3562 elm_smart_scroller_freeze_set(wd->scr, 0);
3566 _scr_anim_start(void *data,
3567 Evas_Object *obj __UNUSED__,
3568 void *event_info __UNUSED__)
3570 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3574 _scr_anim_stop(void *data,
3575 Evas_Object *obj __UNUSED__,
3576 void *event_info __UNUSED__)
3578 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3582 _scr_drag_start(void *data,
3583 Evas_Object *obj __UNUSED__,
3584 void *event_info __UNUSED__)
3586 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3590 _scr_drag_stop(void *data,
3591 Evas_Object *obj __UNUSED__,
3592 void *event_info __UNUSED__)
3594 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3598 _edge_left(void *data,
3599 Evas_Object *scr __UNUSED__,
3600 void *event_info __UNUSED__)
3602 Evas_Object *obj = data;
3603 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3607 _edge_right(void *data,
3608 Evas_Object *scr __UNUSED__,
3609 void *event_info __UNUSED__)
3611 Evas_Object *obj = data;
3612 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3616 _edge_top(void *data,
3617 Evas_Object *scr __UNUSED__,
3618 void *event_info __UNUSED__)
3620 Evas_Object *obj = data;
3621 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3625 _edge_bottom(void *data,
3626 Evas_Object *scr __UNUSED__,
3627 void *event_info __UNUSED__)
3629 Evas_Object *obj = data;
3630 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3634 _decorate_item_realize(Elm_Gen_Item *it)
3638 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3640 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3641 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3642 edje_object_scale_set(it->item->deco_it_view,
3643 elm_widget_scale_get(WIDGET(it)) *
3644 _elm_config->scale);
3645 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3646 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3648 strncpy(buf, "item", sizeof(buf));
3649 if (it->wd->mode == ELM_LIST_COMPRESS)
3650 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3652 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3653 strncat(buf, "/", sizeof(buf) - strlen(buf));
3654 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3656 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3657 elm_widget_style_get(WIDGET(it)));
3658 edje_object_mirrored_set(it->item->deco_it_view,
3659 elm_widget_mirrored_get(WIDGET(it)));
3661 /* signal callback add */
3662 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3664 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3666 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3669 /* text_get, content_get, state_get */
3670 /* FIXME: If you see that assert, please notify us and we
3671 will clean our mess */
3672 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3674 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3675 if (!it->item->deco_it_contents)
3676 it->item->deco_it_contents =
3677 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3678 it->item->deco_it_content_objs =
3679 _item_mode_content_realize(it, it->item->deco_it_view,
3680 &it->item->deco_it_contents, NULL,
3681 &it->item->deco_it_content_objs);
3682 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3683 edje_object_part_swallow(it->item->deco_it_view,
3684 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3687 it->want_unrealize = EINA_FALSE;
3688 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3689 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3693 _decorate_item_unrealize(Elm_Gen_Item *it)
3695 Widget_Data *wd = it->wd;
3696 Evas_Object *content;
3697 if (!it->item->deco_it_view) return;
3699 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3700 elm_widget_stringlist_free(it->item->deco_it_texts);
3701 it->item->deco_it_texts = NULL;
3702 elm_widget_stringlist_free(it->item->deco_it_contents);
3703 it->item->deco_it_contents = NULL;
3704 elm_widget_stringlist_free(it->item->deco_it_states);
3706 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3707 evas_object_del(content);
3709 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3710 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3711 evas_object_del(it->item->deco_it_view);
3712 it->item->deco_it_view = NULL;
3714 if (wd->mode_item == it)
3715 wd->mode_item = NULL;
3716 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3717 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3721 _decorate_item_set(Elm_Gen_Item *it)
3724 Widget_Data *wd = it->wd;
3729 it->item->nocache_once = EINA_TRUE;
3731 if (wd->scr_hold_timer)
3733 ecore_timer_del(wd->scr_hold_timer);
3734 wd->scr_hold_timer = NULL;
3736 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3737 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3739 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3740 _decorate_item_realize(it);
3741 if (it->item->group_item)
3742 evas_object_raise(it->item->VIEW(group_item));
3743 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3744 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3745 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3747 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3748 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3752 _decorate_item_unset(Widget_Data *wd)
3755 if (!wd->mode_item) return;
3756 char buf[1024], buf2[1024];
3760 it->item->nocache_once = EINA_TRUE;
3762 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3763 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3765 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3766 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3768 wd->mode_item = NULL;
3772 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3774 if ((!it) || (!it->wd->decorate_all_mode)) return;
3775 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3776 evas_object_move(it->deco_all_view, itx, ity);
3780 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3783 const char *stacking_even;
3784 const char *stacking;
3786 if ((!it) || (it->item->decorate_all_item_realized) ||
3787 (it->generation < it->wd->generation))
3790 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3791 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3792 _elm_config->scale);
3793 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3794 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3796 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3797 strncpy(buf, "tree", sizeof(buf));
3798 else strncpy(buf, "item", sizeof(buf));
3799 if (it->wd->mode == ELM_LIST_COMPRESS)
3800 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3802 strncat(buf, "/", sizeof(buf) - strlen(buf));
3803 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3805 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3806 elm_widget_style_get(WIDGET(it)));
3808 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3809 if (!stacking_even) stacking_even = "above";
3810 it->item->stacking_even = !!strcmp("above", stacking_even);
3812 stacking = edje_object_data_get(VIEW(it), "stacking");
3813 if (!stacking) stacking = "yes";
3814 it->item->nostacking = !!strcmp("yes", stacking);
3816 edje_object_mirrored_set(it->deco_all_view,
3817 elm_widget_mirrored_get(WIDGET(it)));
3819 _elm_genlist_item_odd_even_update(it);
3820 _elm_genlist_item_state_update(it, NULL);
3822 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3823 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3825 _item_mouse_callbacks_del(it, VIEW(it));
3826 _item_mouse_callbacks_add(it, it->deco_all_view);
3828 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3829 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3830 if (!it->item->deco_all_contents)
3831 it->item->deco_all_contents =
3832 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "decorate_contents"));
3833 it->item->deco_all_content_objs =
3834 _item_mode_content_realize(it, it->deco_all_view,
3835 &it->item->deco_all_contents, NULL,
3836 &it->item->deco_all_content_objs);
3837 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3838 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3840 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3841 evas_object_show(it->deco_all_view);
3843 if (it->selected) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
3845 it->item->decorate_all_item_realized = EINA_TRUE;
3846 it->want_unrealize = EINA_FALSE;
3850 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3853 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3855 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3856 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3857 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3858 _elm_genlist_item_odd_even_update(it);
3859 _elm_genlist_item_state_update(it, NULL);
3861 evas_object_del(it->deco_all_view);
3862 it->deco_all_view = NULL;
3863 elm_widget_stringlist_free(it->item->deco_all_texts);
3864 it->item->deco_all_texts = NULL;
3865 elm_widget_stringlist_free(it->item->deco_all_contents);
3866 it->item->deco_all_contents = NULL;
3867 elm_widget_stringlist_free(it->item->deco_all_states);
3868 it->item->deco_all_states = NULL;
3869 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3870 evas_object_del(icon);
3871 edje_object_message_signal_process(it->deco_all_view);
3872 _item_mouse_callbacks_del(it, it->deco_all_view);
3873 _item_mouse_callbacks_add(it, VIEW(it));
3875 it->item->decorate_all_item_realized = EINA_FALSE;
3879 _item_auto_scroll(Widget_Data *wd)
3882 Elm_Gen_Item *tmp_item = NULL;
3884 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3886 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3887 if (!tmp_item) return;
3888 wd->show_item = tmp_item;
3889 wd->bring_in = EINA_TRUE;
3890 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3891 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3893 wd->show_item->item->showme = EINA_TRUE;
3894 wd->auto_scroll_enabled = EINA_FALSE;
3902 elm_genlist_add(Evas_Object *parent)
3907 Evas_Coord minw, minh;
3908 static Evas_Smart *smart = NULL;
3912 static Evas_Smart_Class sc;
3914 evas_object_smart_clipped_smart_set(&_pan_sc);
3916 sc.name = "elm_genlist_pan";
3917 sc.version = EVAS_SMART_CLASS_VERSION;
3920 sc.resize = _pan_resize;
3921 sc.move = _pan_move;
3922 sc.calculate = _pan_calculate;
3923 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3926 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3928 ELM_SET_WIDTYPE(widtype, "genlist");
3930 elm_widget_type_set(obj, "genlist");
3931 elm_widget_sub_object_add(parent, obj);
3932 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3933 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3934 elm_widget_data_set(obj, wd);
3935 elm_widget_del_hook_set(obj, _del_hook);
3936 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3937 elm_widget_theme_hook_set(obj, _theme_hook);
3938 elm_widget_can_focus_set(obj, EINA_TRUE);
3939 elm_widget_event_hook_set(obj, _event_hook);
3940 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3941 elm_widget_translate_hook_set(obj, _translate_hook);
3944 wd->scr = elm_smart_scroller_add(e);
3945 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_DOWN,
3946 _mouse_down_scroller, obj);
3947 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_UP,
3948 _mouse_up_scroller, obj);
3949 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_MOVE,
3950 _mouse_move_scroller, obj);
3951 elm_smart_scroller_widget_set(wd->scr, obj);
3952 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3953 elm_widget_style_get(obj));
3954 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3955 _elm_config->thumbscroll_bounce_enable);
3956 elm_widget_resize_object_set(obj, wd->scr);
3958 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3959 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3960 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3961 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3962 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3963 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3964 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3965 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3968 wd->mode = ELM_LIST_SCROLL;
3969 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3970 wd->item_cache_max = wd->max_items_per_block * 2;
3971 wd->longpress_timeout = _elm_config->longpress_timeout;
3972 wd->highlight = EINA_TRUE;
3973 wd->tree_effect_enabled = _elm_config->effect_enable;
3975 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3976 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3977 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3978 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3980 wd->pan_smart = evas_object_smart_add(e, smart);
3981 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3984 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3985 _pan_set, _pan_get, _pan_max_get,
3986 _pan_min_get, _pan_child_size_get);
3988 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3990 evas_object_size_hint_min_set(obj, minw, minh);
3992 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3994 _mirrored_set(obj, elm_widget_mirrored_get(obj));
4000 _item_select(Elm_Gen_Item *it)
4003 Evas_Object *obj = WIDGET(it);
4004 Evas_Object *item_obj;
4006 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
4007 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
4008 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
4012 it->selected = EINA_TRUE;
4013 it->wd->selected = eina_list_append(it->wd->selected, it);
4015 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
4017 evas_object_ref(obj);
4020 if (it->wd->last_selected_item &&
4021 (it != (Elm_Gen_Item *) it->wd->last_selected_item))
4023 Elm_Gen_Item *_lsit = (Elm_Gen_Item *)it->wd->last_selected_item;
4025 EINA_LIST_FOREACH(_lsit->content_objs, l, item_obj)
4027 elm_widget_focused_object_clear(item_obj);
4028 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
4030 if (elm_widget_type_get(obj) == _genlist)
4032 EINA_LIST_FOREACH(_lsit->item->flip_content_objs, l, item_obj)
4034 elm_widget_focused_object_clear(item_obj);
4035 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
4037 EINA_LIST_FOREACH(_lsit->item->deco_all_content_objs, l, item_obj)
4039 elm_widget_focused_object_clear(item_obj);
4040 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
4043 _lsit->can_focus = EINA_FALSE;
4045 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
4046 if (it->generation == it->wd->generation)
4047 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
4050 if ((it->wd->clear_me) && (!it->wd->walking))
4051 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
4054 if ((!it->walking) && (it->generation < it->wd->generation))
4059 elm_widget_item_free(it);
4063 it->wd->last_selected_item = (Elm_Object_Item *)it;
4065 evas_object_unref(obj);
4068 static Evas_Object *
4069 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
4071 return edje_object_part_swallow_get(VIEW(it), part);
4075 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
4077 if (content && part)
4079 it->content_objs = eina_list_append(it->content_objs, content);
4080 edje_object_part_swallow(VIEW(it), part, content);
4084 static Evas_Object *
4085 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
4088 obj = edje_object_part_swallow_get(VIEW(it), part);
4089 if (!obj) return NULL;
4090 it->content_objs = eina_list_remove(it->content_objs, obj);
4091 edje_object_part_unswallow(VIEW(it), obj);
4096 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
4098 if (!it->itc->func.text_get) return NULL;
4099 return edje_object_part_text_get(VIEW(it), part);
4103 _item_disable_hook(Elm_Object_Item *it)
4107 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4109 if (_it->generation < _it->wd->generation) return;
4112 elm_genlist_item_selected_set(it, EINA_FALSE);
4116 if (elm_widget_item_disabled_get(it))
4118 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
4119 if (_it->deco_all_view)
4120 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
4124 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
4125 if (_it->deco_all_view)
4126 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
4128 EINA_LIST_FOREACH(_it->content_objs, l, obj)
4129 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
4134 _item_del_pre_hook(Elm_Object_Item *it)
4136 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4138 if ((_it->relcount > 0) || (_it->walking > 0))
4140 elm_genlist_item_subitems_clear(it);
4141 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
4142 _elm_genlist_item_del_notserious(_it);
4143 if (_it->item->block)
4145 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
4146 _it->item->block->changed = EINA_TRUE;
4147 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
4148 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
4152 _it->parent->item->items =
4153 eina_list_remove(_it->parent->item->items, it);
4163 _item_signal_emit_hook(Elm_Object_Item *it,
4164 const char *emission,
4167 edje_object_signal_emit(VIEW(it), emission, source);
4171 _elm_genlist_item_new(Widget_Data *wd,
4172 const Elm_Gen_Item_Class *itc,
4174 Elm_Gen_Item *parent,
4176 const void *func_data)
4180 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
4181 if (!it) return NULL;
4183 it->generation = wd->generation;
4185 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
4186 it->base.data = data;
4187 it->parent = parent;
4188 it->func.func = func;
4189 it->func.data = func_data;
4190 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
4191 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
4192 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
4193 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
4194 elm_widget_item_disable_hook_set(it, _item_disable_hook);
4195 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
4196 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
4199 it->sel_cb = (Ecore_Cb)_item_select;
4204 static Elm_Gen_Item *
4205 _item_new(Widget_Data *wd,
4206 const Elm_Genlist_Item_Class *itc,
4208 Elm_Gen_Item *parent,
4209 Elm_Genlist_Item_Type type,
4211 const void *func_data)
4213 Elm_Gen_Item *it, *it2;
4216 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
4217 if (!it) return NULL;
4218 it->item = ELM_NEW(Elm_Gen_Item_Type);
4219 it->item->type = type;
4220 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
4221 it->item->expanded_depth = 0;
4222 ELM_GEN_ITEM_SETUP(it);
4223 it->mouse_cursor = NULL;
4224 it->can_focus = EINA_TRUE;
4227 if (it->parent->group)
4228 it->item->group_item = parent;
4229 else if (it->parent->item->group_item)
4230 it->item->group_item = it->parent->item->group_item;
4232 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
4234 if (!it2->parent->group) depth += 1;
4236 it->item->expanded_depth = depth;
4242 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
4246 itb = calloc(1, sizeof(Item_Block));
4247 if (!itb) return NULL;
4251 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
4252 _item_block_position_update(wd->blocks, 0);
4256 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4257 itb->position_update = EINA_TRUE;
4258 if (wd->blocks != EINA_INLIST_GET(itb))
4260 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4271 _item_block_add(Widget_Data *wd,
4274 Item_Block *itb = NULL;
4281 itb = calloc(1, sizeof(Item_Block));
4282 if (!itb) return EINA_FALSE;
4284 if (!it->item->rel->item->block)
4287 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4288 itb->items = eina_list_append(itb->items, it);
4289 itb->position_update = EINA_TRUE;
4290 it->position = eina_list_count(itb->items);
4291 it->position_update = EINA_TRUE;
4293 if (wd->blocks != EINA_INLIST_GET(itb))
4295 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4306 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4307 if (it->item->before)
4309 wd->blocks = eina_inlist_prepend_relative
4310 (wd->blocks, EINA_INLIST_GET(itb),
4311 EINA_INLIST_GET(it->item->rel->item->block));
4313 eina_list_prepend_relative_list(itb->items, it, tmp);
4315 /* Update index from where we prepended */
4316 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4317 _item_block_position_update(EINA_INLIST_GET(itb),
4318 it->item->rel->item->block->position);
4322 wd->blocks = eina_inlist_append_relative
4323 (wd->blocks, EINA_INLIST_GET(itb),
4324 EINA_INLIST_GET(it->item->rel->item->block));
4326 eina_list_append_relative_list(itb->items, it, tmp);
4328 /* Update block index from where we appended */
4329 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4330 _item_block_position_update(EINA_INLIST_GET(itb),
4331 it->item->rel->item->block->position + 1);
4337 if (it->item->before)
4341 itb = (Item_Block *)(wd->blocks);
4342 if (itb->count >= wd->max_items_per_block)
4344 itb = _item_block_new(wd, EINA_TRUE);
4345 if (!itb) return EINA_FALSE;
4350 itb = _item_block_new(wd, EINA_TRUE);
4351 if (!itb) return EINA_FALSE;
4353 itb->items = eina_list_prepend(itb->items, it);
4355 _item_position_update(itb->items, 0);
4361 itb = (Item_Block *)(wd->blocks->last);
4362 if (itb->count >= wd->max_items_per_block)
4364 itb = _item_block_new(wd, EINA_FALSE);
4365 if (!itb) return EINA_FALSE;
4370 itb = _item_block_new(wd, EINA_FALSE);
4371 if (!itb) return EINA_FALSE;
4373 itb->items = eina_list_append(itb->items, it);
4374 it->position = eina_list_count(itb->items);
4382 if (it->item->rel->item->queued)
4384 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
4385 on sorted insertion order, so the queue is not always ordered like the item list.
4386 This lead to issue where we depend on an item that is not yet created. As a quick
4387 work around, we reschedule the calc of the item and stop reordering the list to
4388 prevent any nasty issue to show up here.
4390 wd->queue = eina_list_append(wd->queue, it);
4391 wd->requeued = EINA_TRUE;
4392 it->item->queued = EINA_TRUE;
4395 itb = it->item->rel->item->block;
4396 if (!itb) goto newblock;
4397 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4398 if (it->item->before)
4400 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4401 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4405 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4406 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4410 itb->changed = EINA_TRUE;
4411 it->item->block = itb;
4412 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
4413 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
4416 it->item->rel->relcount--;
4417 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
4419 _item_del(it->item->rel);
4420 elm_widget_item_free(it->item->rel);
4422 it->item->rel = NULL;
4424 if (itb->count > itb->wd->max_items_per_block)
4429 Eina_Bool done = EINA_FALSE;
4431 newc = itb->count / 2;
4433 if (EINA_INLIST_GET(itb)->prev)
4435 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4437 if (itbp->count + newc < wd->max_items_per_block / 2)
4439 /* moving items to previous block */
4440 while ((itb->count > newc) && (itb->items))
4442 it2 = eina_list_data_get(itb->items);
4443 itb->items = eina_list_remove_list(itb->items, itb->items);
4446 itbp->items = eina_list_append(itbp->items, it2);
4447 it2->item->block = itbp;
4455 if (!done && EINA_INLIST_GET(itb)->next)
4457 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4459 if (itbn->count + newc < wd->max_items_per_block / 2)
4461 /* moving items to next block */
4462 while ((itb->count > newc) && (itb->items))
4466 l = eina_list_last(itb->items);
4467 it2 = eina_list_data_get(l);
4468 itb->items = eina_list_remove_list(itb->items, l);
4471 itbn->items = eina_list_prepend(itbn->items, it2);
4472 it2->item->block = itbn;
4482 /* moving items to new block */
4483 itb2 = calloc(1, sizeof(Item_Block));
4484 if (!itb2) return EINA_FALSE;
4487 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4488 EINA_INLIST_GET(itb));
4489 itb2->changed = EINA_TRUE;
4490 while ((itb->count > newc) && (itb->items))
4494 l = eina_list_last(itb->items);
4496 itb->items = eina_list_remove_list(itb->items, l);
4499 itb2->items = eina_list_prepend(itb2->items, it2);
4500 it2->item->block = itb2;
4510 _item_process(Widget_Data *wd, Elm_Gen_Item *it)
4512 if (!_item_block_add(wd, it)) return 1;
4514 _item_block_realize(it->item->block);
4519 _item_process_post(Widget_Data *wd, Elm_Gen_Item *it, Eina_Bool qadd)
4521 Eina_Bool showme = EINA_FALSE;
4523 if (it->item->block->changed)
4525 showme = _item_block_recalc(it->item->block, it->item->block->num, qadd);
4526 it->item->block->changed = 0;
4527 if (wd->pan_changed)
4529 if (wd->calc_job) ecore_job_del(wd->calc_job);
4530 wd->calc_job = NULL;
4532 wd->pan_changed = EINA_FALSE;
4535 if (showme) it->item->block->showme = EINA_TRUE;
4536 /* when prepending, move the scroller along with the first selected item to
4537 * create the illusion that we're watching the selected item
4538 * this prevents the selected item being scrolled off the viewport
4540 if (wd->selected && it->item->before)
4544 it2 = wd->selected->data;
4545 elm_smart_scroller_child_pos_get(wd->scr, NULL, &y);
4546 evas_object_geometry_get(wd->pan_smart, NULL, NULL, NULL, &h);
4547 if ((it->y + it->item->block->y > y + h) || (it->y + it->item->block->y + it->item->h < y))
4548 /* offscreen, just update */
4549 elm_smart_scroller_child_region_show(wd->scr,
4550 it2->x + it2->item->block->x,
4552 it2->item->block->w,
4555 elm_smart_scroller_child_region_show(wd->scr,
4556 it->x + it->item->block->x,
4564 _queue_process(Widget_Data *wd)
4569 t0 = ecore_loop_time_get();
4570 //evas_event_freeze(evas_object_evas_get(wd->obj));
4571 for (n = 0; (wd->queue) && (n < 128); n++)
4575 it = eina_list_data_get(wd->queue);
4576 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4577 it->item->queued = EINA_FALSE;
4578 if (_item_process(wd, it)) continue;
4579 t = ecore_time_get();
4580 _item_process_post(wd, it, EINA_TRUE);
4581 /* same as eina_inlist_count > 1 */
4582 if (wd->blocks && wd->blocks->next)
4584 if ((t - t0) > (ecore_animator_frametime_get())) break;
4587 //evas_event_thaw(evas_object_evas_get(wd->obj));
4588 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4593 _idle_process(void *data, Eina_Bool *wakeup)
4595 Widget_Data *wd = data;
4598 //static double q_start = 0.0;
4599 //if (q_start == 0.0) q_start = ecore_time_get();
4601 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4605 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4607 return ECORE_CALLBACK_CANCEL;
4609 return ECORE_CALLBACK_RENEW;
4613 _item_idle_enterer(void *data)
4615 Widget_Data *wd = data;
4616 Eina_Bool wakeup = EINA_FALSE;
4617 Eina_Bool ok = _idle_process(data, &wakeup);
4622 if (wd->calc_job) ecore_job_del(wd->calc_job);
4623 wd->calc_job = ecore_job_add(_calc_job, wd);
4625 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4630 _item_queue(Widget_Data *wd,
4634 if (it->item->queued) return;
4635 if ((wd->blocks) && (wd->homogeneous) && (wd->mode == ELM_LIST_COMPRESS))
4637 if (!_item_process(wd, it))
4638 _item_process_post(wd, it, EINA_FALSE);
4641 it->item->queued = EINA_TRUE;
4642 if (cb && !wd->requeued)
4643 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4645 wd->queue = eina_list_append(wd->queue, it);
4646 // FIXME: why does a freeze then thaw here cause some genlist
4647 // elm_genlist_item_append() to be much much slower?
4648 // evas_event_freeze(evas_object_evas_get(wd->obj));
4649 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4651 if (wd->queue_idle_enterer)
4653 ecore_idle_enterer_del(wd->queue_idle_enterer);
4654 wd->queue_idle_enterer = NULL;
4658 // evas_event_thaw(evas_object_evas_get(wd->obj));
4659 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4660 if (!wd->queue_idle_enterer)
4661 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4665 _elm_genlist_item_compare(const void *data, const void *data1)
4667 const Elm_Gen_Item *it, *item1;
4668 it = ELM_GEN_ITEM_FROM_INLIST(data);
4669 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4670 return it->wd->item_compare_cb(it, item1);
4674 _elm_genlist_item_list_compare(const void *data, const void *data1)
4676 const Elm_Gen_Item *it = data;
4677 const Elm_Gen_Item *item1 = data1;
4678 return it->wd->item_compare_cb(it, item1);
4681 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4683 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4688 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4689 _item_block_del(it);
4691 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4692 it->item->rel = after;
4693 it->item->rel->relcount++;
4694 it->item->before = EINA_FALSE;
4695 if (after->item->group_item) it->item->group_item = after->item->group_item;
4696 _item_queue(it->wd, it, NULL);
4698 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4701 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4703 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4706 if (!before) return;
4708 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4709 _item_block_del(it);
4710 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4711 it->item->rel = before;
4712 it->item->rel->relcount++;
4713 it->item->before = EINA_TRUE;
4714 if (before->item->group_item) it->item->group_item = before->item->group_item;
4715 _item_queue(it->wd, it, NULL);
4717 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4721 elm_genlist_items_count(const Evas_Object *obj)
4723 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4724 Widget_Data *wd = elm_widget_data_get(obj);
4726 return wd->item_count;
4729 EAPI Elm_Object_Item *
4730 elm_genlist_item_append(Evas_Object *obj,
4731 const Elm_Genlist_Item_Class *itc,
4733 Elm_Object_Item *parent,
4734 Elm_Genlist_Item_Type type,
4736 const void *func_data)
4738 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4739 Widget_Data *wd = elm_widget_data_get(obj);
4740 if (!wd) return NULL;
4741 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4743 if (!it) return NULL;
4747 wd->group_items = eina_list_append(wd->group_items, it);
4748 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4749 it->item->rel = NULL;
4753 Elm_Gen_Item *it2 = NULL;
4754 Eina_List *ll = eina_list_last(it->parent->item->items);
4755 if (ll) it2 = ll->data;
4756 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4757 if (!it2) it2 = it->parent;
4759 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4760 EINA_INLIST_GET(it2));
4761 it->item->rel = it2;
4762 it->item->rel->relcount++;
4764 it->item->before = EINA_FALSE;
4765 _item_queue(wd, it, NULL);
4766 return (Elm_Object_Item *)it;
4769 EAPI Elm_Object_Item *
4770 elm_genlist_item_prepend(Evas_Object *obj,
4771 const Elm_Genlist_Item_Class *itc,
4773 Elm_Object_Item *parent,
4774 Elm_Genlist_Item_Type type,
4776 const void *func_data)
4778 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4779 Widget_Data *wd = elm_widget_data_get(obj);
4780 if (!wd) return NULL;
4781 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4783 if (!it) return NULL;
4787 wd->group_items = eina_list_prepend(wd->group_items, it);
4788 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4789 it->item->rel = NULL;
4793 Elm_Gen_Item *it2 = NULL;
4794 Eina_List *ll = it->parent->item->items;
4795 if (ll) it2 = ll->data;
4796 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4797 if (!it2) it2 = it->parent;
4799 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4800 EINA_INLIST_GET(it2));
4801 it->item->rel = it2;
4802 it->item->rel->relcount++;
4804 it->item->before = EINA_TRUE;
4805 _item_queue(wd, it, NULL);
4806 return (Elm_Object_Item *)it;
4809 EAPI Elm_Object_Item *
4810 elm_genlist_item_insert_after(Evas_Object *obj,
4811 const Elm_Genlist_Item_Class *itc,
4813 Elm_Object_Item *parent,
4814 Elm_Object_Item *after,
4815 Elm_Genlist_Item_Type type,
4817 const void *func_data)
4819 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4820 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4821 Widget_Data *wd = elm_widget_data_get(obj);
4822 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4823 if (!wd) return NULL;
4824 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4825 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4827 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4829 if (!it) return NULL;
4832 if ((it->group) && (_after->group))
4833 wd->group_items = eina_list_append_relative(wd->group_items, it,
4838 it->parent->item->items =
4839 eina_list_append_relative(it->parent->item->items, it, _after);
4841 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4842 EINA_INLIST_GET(_after));
4843 it->item->rel = _after;
4844 it->item->rel->relcount++;
4845 it->item->before = EINA_FALSE;
4846 _item_queue(wd, it, NULL);
4847 return (Elm_Object_Item *)it;
4850 EAPI Elm_Object_Item *
4851 elm_genlist_item_insert_before(Evas_Object *obj,
4852 const Elm_Genlist_Item_Class *itc,
4854 Elm_Object_Item *parent,
4855 Elm_Object_Item *before,
4856 Elm_Genlist_Item_Type type,
4858 const void *func_data)
4860 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4861 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4862 Widget_Data *wd = elm_widget_data_get(obj);
4863 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4864 if (!wd) return NULL;
4865 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4866 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4868 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4870 if (!it) return NULL;
4873 if (it->group && _before->group)
4874 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4879 it->parent->item->items =
4880 eina_list_prepend_relative(it->parent->item->items, it, _before);
4882 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4883 EINA_INLIST_GET(_before));
4884 it->item->rel = _before;
4885 it->item->rel->relcount++;
4886 it->item->before = EINA_TRUE;
4887 _item_queue(wd, it, NULL);
4888 return (Elm_Object_Item *)it;
4891 EAPI Elm_Object_Item *
4892 elm_genlist_item_sorted_insert(Evas_Object *obj,
4893 const Elm_Genlist_Item_Class *itc,
4895 Elm_Object_Item *parent,
4896 Elm_Genlist_Item_Type type,
4897 Eina_Compare_Cb comp,
4899 const void *func_data)
4901 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4902 Widget_Data *wd = elm_widget_data_get(obj);
4903 if (!wd) return NULL;
4904 Elm_Gen_Item *rel = NULL;
4905 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4907 if (!it) return NULL;
4909 wd->item_compare_cb = comp;
4916 l = eina_list_search_sorted_near_list(it->parent->item->items,
4917 _elm_genlist_item_list_compare,
4921 rel = eina_list_data_get(l);
4925 if (cmp_result >= 0)
4927 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4928 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4929 it->item->before = EINA_FALSE;
4931 else if (cmp_result < 0)
4933 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4934 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4935 it->item->before = EINA_TRUE;
4942 wd->state = eina_inlist_sorted_state_new();
4943 eina_inlist_sorted_state_init(wd->state, wd->items);
4944 wd->requeued = EINA_FALSE;
4948 wd->group_items = eina_list_append(wd->group_items, it);
4950 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4951 _elm_genlist_item_compare, wd->state);
4953 if (EINA_INLIST_GET(it)->next)
4955 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4956 it->item->before = EINA_TRUE;
4958 else if (EINA_INLIST_GET(it)->prev)
4960 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4961 it->item->before = EINA_FALSE;
4967 it->item->rel = rel;
4968 it->item->rel->relcount++;
4971 _item_queue(wd, it, _elm_genlist_item_list_compare);
4973 return (Elm_Object_Item *)it;
4977 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4979 Eina_Inlist *next, *l;
4980 Widget_Data *wd = elm_widget_data_get(obj);
4983 if (!standby) wd->generation++;
4987 eina_inlist_sorted_state_free(wd->state);
4991 if (wd->walking > 0)
4993 wd->clear_me = EINA_TRUE;
4996 evas_event_freeze(evas_object_evas_get(wd->obj));
4997 for (l = wd->items, next = l ? l->next : NULL;
4999 l = next, next = next ? next->next : NULL)
5001 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
5003 if (it->generation < wd->generation)
5005 Elm_Gen_Item *itn = NULL;
5007 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
5008 if (itn) itn->walking++; /* prevent early death of subitem */
5010 elm_widget_item_free(it);
5011 if (itn) itn->walking--;
5014 wd->clear_me = EINA_FALSE;
5015 wd->pan_changed = EINA_TRUE;
5018 ecore_job_del(wd->calc_job);
5019 wd->calc_job = NULL;
5021 if (wd->selected) wd->selected = eina_list_free(wd->selected);
5022 if (wd->clear_cb) wd->clear_cb(wd);
5028 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
5029 wd->alpha_bg = NULL;
5033 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
5034 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
5036 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
5037 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
5038 evas_event_thaw(evas_object_evas_get(wd->obj));
5039 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
5043 elm_genlist_clear(Evas_Object *obj)
5045 ELM_CHECK_WIDTYPE(obj, widtype);
5046 _elm_genlist_clear(obj, EINA_FALSE);
5050 elm_genlist_multi_select_set(Evas_Object *obj,
5053 ELM_CHECK_WIDTYPE(obj, widtype);
5054 Widget_Data *wd = elm_widget_data_get(obj);
5056 wd->multi = !!multi;
5060 elm_genlist_multi_select_get(const Evas_Object *obj)
5062 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5063 Widget_Data *wd = elm_widget_data_get(obj);
5064 if (!wd) return EINA_FALSE;
5068 EAPI Elm_Object_Item *
5069 elm_genlist_selected_item_get(const Evas_Object *obj)
5071 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5072 Widget_Data *wd = elm_widget_data_get(obj);
5073 if (!wd) return NULL;
5074 if (wd->selected) return wd->selected->data;
5078 EAPI const Eina_List *
5079 elm_genlist_selected_items_get(const Evas_Object *obj)
5081 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5082 Widget_Data *wd = elm_widget_data_get(obj);
5083 if (!wd) return NULL;
5084 return wd->selected;
5088 elm_genlist_realized_items_get(const Evas_Object *obj)
5090 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5091 Widget_Data *wd = elm_widget_data_get(obj);
5092 Eina_List *list = NULL;
5094 Eina_Bool done = EINA_FALSE;
5095 if (!wd) return NULL;
5096 EINA_INLIST_FOREACH(wd->blocks, itb)
5104 EINA_LIST_FOREACH(itb->items, l, it)
5106 if (it->realized) list = eina_list_append(list, it);
5117 EAPI Elm_Object_Item *
5118 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5123 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5124 Widget_Data *wd = elm_widget_data_get(obj);
5125 Evas_Coord ox, oy, ow, oh;
5128 if (!wd) return NULL;
5129 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5131 EINA_INLIST_FOREACH(wd->blocks, itb)
5136 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
5137 oy + itb->y - itb->wd->pan_y,
5138 itb->w, itb->h, x, y, 1, 1))
5140 EINA_LIST_FOREACH(itb->items, l, it)
5142 Evas_Coord itx, ity;
5144 itx = ox + itb->x + it->x - itb->wd->pan_x;
5145 ity = oy + itb->y + it->y - itb->wd->pan_y;
5146 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5150 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5151 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5155 return (Elm_Object_Item *)it;
5157 lasty = ity + it->item->h;
5162 if (y > lasty) *posret = 1;
5168 EAPI Elm_Object_Item *
5169 elm_genlist_first_item_get(const Evas_Object *obj)
5171 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5172 Widget_Data *wd = elm_widget_data_get(obj);
5173 if (!wd) return NULL;
5174 if (!wd->items) return NULL;
5175 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
5176 while ((it) && (it->generation < wd->generation))
5177 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5178 return (Elm_Object_Item *)it;
5181 EAPI Elm_Object_Item *
5182 elm_genlist_last_item_get(const Evas_Object *obj)
5184 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5185 Widget_Data *wd = elm_widget_data_get(obj);
5186 if (!wd) return NULL;
5187 if (!wd->items) return NULL;
5188 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
5189 while ((it) && (it->generation < wd->generation))
5190 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5191 return (Elm_Object_Item *)it;
5194 EAPI Elm_Object_Item *
5195 elm_genlist_item_next_get(const Elm_Object_Item *it)
5197 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5198 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5201 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
5202 if ((_it) && (_it->generation == _it->wd->generation)) break;
5204 return (Elm_Object_Item *) _it;
5207 EAPI Elm_Object_Item *
5208 elm_genlist_item_prev_get(const Elm_Object_Item *it)
5210 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5211 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5214 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
5215 if ((_it) && (_it->generation == _it->wd->generation)) break;
5217 return (Elm_Object_Item *) _it;
5220 EAPI Elm_Object_Item *
5221 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5223 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5224 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
5228 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
5230 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5231 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
5233 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5235 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
5236 _item_subitems_clear(_it);
5239 if (!wd->tree_effect_animator)
5241 wd->expanded_item = _it;
5242 _item_tree_effect_before(_it);
5243 evas_object_raise(wd->alpha_bg);
5244 evas_object_show(wd->alpha_bg);
5245 wd->start_time = ecore_time_get();
5246 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
5249 _item_subitems_clear(_it);
5254 elm_genlist_item_selected_set(Elm_Object_Item *it,
5257 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5258 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5259 Widget_Data *wd = _it->wd;
5261 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
5263 selected = !!selected;
5264 if (_it->selected == selected) return;
5270 while (wd->selected)
5272 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
5273 _it->unsel_cb(wd->selected->data);
5276 _it->highlight_cb(_it);
5280 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
5285 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5287 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5288 return ((Elm_Gen_Item *)it)->selected;
5292 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5295 if (it->item->expanded)
5297 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5301 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5304 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5305 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5312 _elm_genlist_move_items_set(Elm_Gen_Item *it)
5315 Elm_Gen_Item *it2 = NULL;
5316 Evas_Coord ox, oy, ow, oh, dh = 0;
5318 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
5320 if (it->item->expanded)
5322 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
5323 EINA_LIST_FOREACH_SAFE(it->wd->move_items, l, ll, it2)
5325 if (it2 == it->wd->expanded_next_item) break;
5326 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
5331 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
5332 it2 = it->wd->expanded_next_item;
5333 while (it2 && (dh < oy + oh))
5336 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
5337 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5343 elm_genlist_item_expanded_set(Elm_Object_Item *it,
5346 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5347 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5348 expanded = !!expanded;
5349 if (_it->item->expanded == expanded) return;
5350 if (_it->item->type != ELM_GENLIST_ITEM_TREE) return;
5351 _it->item->expanded = expanded;
5352 _it->wd->expanded_item = _it;
5353 _elm_genlist_move_items_set(_it);
5355 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
5356 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
5358 if (_it->item->expanded)
5360 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
5362 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
5363 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
5364 _it->wd->auto_scroll_enabled = EINA_TRUE;
5368 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
5370 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
5371 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
5372 _it->wd->auto_scroll_enabled = EINA_FALSE;
5377 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5379 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5380 return ((Elm_Gen_Item *)it)->item->expanded;
5384 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5386 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
5387 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5390 EINA_DEPRECATED EAPI void
5391 elm_genlist_item_display_only_set(Elm_Object_Item *it,
5392 Eina_Bool display_only)
5394 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5395 display_only = !!display_only;
5398 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
5401 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5402 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5403 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
5407 EINA_DEPRECATED EAPI Eina_Bool
5408 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
5410 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5411 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5412 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5413 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5414 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5420 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
5421 Elm_Genlist_Item_Scrollto_Type type,
5428 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5429 Evas_Coord gith = 0;
5430 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5431 if ((_it->wd->homogeneous) &&
5432 (_it->wd->mode == ELM_LIST_COMPRESS))
5433 goto hm_shortcut; /* homogenous genlist shortcut */
5434 if ((_it->item->queued) || (!_it->item->mincalcd))
5436 _it->wd->show_item = _it;
5437 _it->wd->bring_in = bring_in;
5438 _it->wd->scrollto_type = type;
5439 _it->item->showme = EINA_TRUE;
5443 if (_it->wd->show_item)
5445 _it->wd->show_item->item->showme = EINA_FALSE;
5446 _it->wd->show_item = NULL;
5449 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
5452 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5453 if ((_it->item->group_item) &&
5454 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
5455 gith = _it->item->group_item->item->h;
5457 *y = _it->y + _it->item->block->y - gith;
5459 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5460 if (_it->item->group_item) gith = _it->item->group_item->item->h;
5461 *y = _it->y + _it->item->block->y - gith;
5463 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5464 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
5470 *x = _it->x + _it->item->block->x;
5471 *w = _it->item->block->w;
5476 elm_genlist_item_promote(Elm_Object_Item *it)
5478 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5479 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5480 if (_it->generation < _it->wd->generation) return;
5481 _item_move_before(_it,
5482 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
5486 elm_genlist_item_demote(Elm_Object_Item *it)
5488 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5489 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5490 if (_it->generation < _it->wd->generation) return;
5491 _item_move_after(_it,
5492 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
5496 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5498 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5499 Evas_Coord x, y, w, h;
5500 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5502 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
5503 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
5507 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5510 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5511 Evas_Coord x, y, w, h;
5512 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5514 elm_smart_scroller_child_viewport_size_get(_it->wd->scr, &x, &y);
5516 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
5517 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
5521 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5523 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5525 Evas_Object *content;
5526 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5528 elm_widget_sub_object_del(WIDGET(it), content);
5529 evas_object_smart_member_del(content);
5530 evas_object_hide(content);
5531 if (l) *l = eina_list_append(*l, content);
5536 elm_genlist_item_update(Elm_Object_Item *it)
5538 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5539 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5541 if (!_it->item->block) return;
5542 if (_it->generation < _it->wd->generation) return;
5543 _it->item->mincalcd = EINA_FALSE;
5544 _it->item->updateme = EINA_TRUE;
5545 _it->item->block->updateme = EINA_TRUE;
5546 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5547 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5551 elm_genlist_item_fields_update(Elm_Object_Item *it,
5553 Elm_Genlist_Item_Field_Type itf)
5555 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5556 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5558 if (!_it->item->block) return;
5559 if (_it->generation < _it->wd->generation) return;
5561 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5562 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5563 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5565 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5566 &_it->contents, parts);
5567 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5568 &_it->contents, parts);
5572 _it->item->flip_content_objs =
5573 _item_mode_content_unrealize(_it, VIEW(_it),
5574 &_it->item->flip_contents, parts,
5575 &_it->item->flip_content_objs);
5576 _it->item->flip_content_objs =
5577 _item_mode_content_realize(_it, VIEW(_it),
5578 &_it->item->flip_contents, parts,
5579 &_it->item->flip_content_objs);
5581 if (_it->item->deco_it_view)
5583 _it->item->deco_it_content_objs =
5584 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5585 &_it->item->deco_it_contents, parts,
5586 &_it->item->deco_it_content_objs);
5587 _it->item->deco_it_content_objs =
5588 _item_mode_content_realize(_it, _it->item->deco_it_view,
5589 &_it->item->deco_it_contents, parts,
5590 &_it->item->deco_it_content_objs);
5592 if (_it->wd->decorate_all_mode)
5594 _it->item->deco_all_content_objs =
5595 _item_mode_content_unrealize(_it, _it->deco_all_view,
5596 &_it->item->deco_all_contents, parts,
5597 &_it->item->deco_all_content_objs);
5598 _it->item->deco_all_content_objs =
5599 _item_mode_content_realize(_it, _it->deco_all_view,
5600 &_it->item->deco_all_contents, parts,
5601 &_it->item->deco_all_content_objs);
5604 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5605 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5609 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5610 const Elm_Genlist_Item_Class *itc)
5612 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5613 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5615 if (!_it->item->block) return;
5616 EINA_SAFETY_ON_NULL_RETURN(itc);
5617 if (_it->generation < _it->wd->generation) return;
5619 _it->item->nocache_once = EINA_TRUE;
5621 elm_widget_stringlist_free(_it->texts);
5623 elm_widget_stringlist_free(_it->contents);
5624 _it->contents = NULL;
5625 elm_widget_stringlist_free(_it->states);
5630 elm_widget_stringlist_free(_it->item->flip_contents);
5631 _it->item->flip_contents = NULL;
5633 if (_it->item->deco_it_view)
5635 elm_widget_stringlist_free(_it->item->deco_it_texts);
5636 _it->item->deco_it_texts = NULL;
5637 elm_widget_stringlist_free(_it->item->deco_it_contents);
5638 _it->item->deco_it_contents = NULL;
5640 if (_it->wd->decorate_all_mode)
5642 elm_widget_stringlist_free(_it->item->deco_all_texts);
5643 _it->item->deco_all_texts = NULL;
5644 elm_widget_stringlist_free(_it->item->deco_all_contents);
5645 _it->item->deco_all_contents = NULL;
5648 elm_genlist_item_update(it);
5651 EAPI const Elm_Genlist_Item_Class *
5652 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5654 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5655 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5656 if (_it->generation < _it->wd->generation) return NULL;
5660 static Evas_Object *
5661 _elm_genlist_item_label_create(void *data,
5662 Evas_Object *obj __UNUSED__,
5663 Evas_Object *tooltip,
5664 void *it __UNUSED__)
5666 Evas_Object *label = elm_label_add(tooltip);
5669 elm_object_style_set(label, "tooltip");
5670 elm_object_text_set(label, data);
5675 _elm_genlist_item_label_del_cb(void *data,
5676 Evas_Object *obj __UNUSED__,
5677 void *event_info __UNUSED__)
5679 eina_stringshare_del(data);
5683 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5686 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5687 text = eina_stringshare_add(text);
5688 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5690 _elm_genlist_item_label_del_cb);
5694 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5695 Elm_Tooltip_Item_Content_Cb func,
5697 Evas_Smart_Cb del_cb)
5699 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5700 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5702 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5705 if (_it->tooltip.del_cb)
5706 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5708 _it->tooltip.content_cb = func;
5709 _it->tooltip.data = data;
5710 _it->tooltip.del_cb = del_cb;
5714 elm_widget_item_tooltip_content_cb_set(_it,
5715 _it->tooltip.content_cb,
5716 _it->tooltip.data, NULL);
5717 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5718 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5724 if (del_cb) del_cb((void *)data, NULL, NULL);
5728 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5730 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5731 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5733 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5734 elm_widget_item_tooltip_unset(_it);
5736 if (_it->tooltip.del_cb)
5737 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5738 _it->tooltip.del_cb = NULL;
5739 _it->tooltip.content_cb = NULL;
5740 _it->tooltip.data = NULL;
5741 _it->tooltip.free_size = EINA_FALSE;
5742 if (_it->tooltip.style)
5743 elm_genlist_item_tooltip_style_set(it, NULL);
5747 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5750 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5751 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5753 eina_stringshare_replace(&_it->tooltip.style, style);
5754 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5758 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5760 return elm_object_item_tooltip_style_get(it);
5764 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5767 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5768 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5770 _it->tooltip.free_size = disable;
5771 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5776 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5778 return elm_object_tooltip_window_mode_get(VIEW(it));
5782 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5785 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5786 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5787 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5788 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5792 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5794 return elm_widget_item_cursor_get(it);
5798 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5800 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5801 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5803 if (!_it->mouse_cursor) return;
5805 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5807 eina_stringshare_del(_it->mouse_cursor);
5808 _it->mouse_cursor = NULL;
5812 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5815 elm_widget_item_cursor_style_set(it, style);
5819 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5821 return elm_widget_item_cursor_style_get(it);
5825 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5826 Eina_Bool engine_only)
5828 elm_widget_item_cursor_engine_only_set(it, engine_only);
5832 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5834 return elm_widget_item_cursor_engine_only_get(it);
5838 elm_genlist_item_index_get(const Elm_Object_Item *it)
5840 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5841 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5843 if (_it->item->block)
5844 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5849 elm_genlist_mode_set(Evas_Object *obj,
5852 ELM_CHECK_WIDTYPE(obj, widtype);
5853 Widget_Data *wd = elm_widget_data_get(obj);
5855 if (wd->mode == mode) return;
5862 elm_genlist_mode_get(const Evas_Object *obj)
5864 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5865 Widget_Data *wd = elm_widget_data_get(obj);
5866 if (!wd) return ELM_LIST_LAST;
5871 elm_genlist_bounce_set(Evas_Object *obj,
5875 ELM_CHECK_WIDTYPE(obj, widtype);
5876 Widget_Data *wd = elm_widget_data_get(obj);
5878 wd->h_bounce = !!h_bounce;
5879 wd->v_bounce = !!v_bounce;
5880 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5884 elm_genlist_bounce_get(const Evas_Object *obj,
5885 Eina_Bool *h_bounce,
5886 Eina_Bool *v_bounce)
5888 ELM_CHECK_WIDTYPE(obj, widtype);
5889 Widget_Data *wd = elm_widget_data_get(obj);
5891 if (h_bounce) *h_bounce = wd->h_bounce;
5892 if (v_bounce) *v_bounce = wd->v_bounce;
5896 elm_genlist_homogeneous_set(Evas_Object *obj,
5897 Eina_Bool homogeneous)
5899 ELM_CHECK_WIDTYPE(obj, widtype);
5900 Widget_Data *wd = elm_widget_data_get(obj);
5902 wd->homogeneous = !!homogeneous;
5906 elm_genlist_homogeneous_get(const Evas_Object *obj)
5908 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5909 Widget_Data *wd = elm_widget_data_get(obj);
5910 if (!wd) return EINA_FALSE;
5911 return wd->homogeneous;
5915 elm_genlist_block_count_set(Evas_Object *obj,
5918 ELM_CHECK_WIDTYPE(obj, widtype);
5919 Widget_Data *wd = elm_widget_data_get(obj);
5921 wd->max_items_per_block = count;
5922 wd->item_cache_max = wd->max_items_per_block * 2;
5923 _item_cache_clean(wd);
5927 elm_genlist_block_count_get(const Evas_Object *obj)
5929 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5930 Widget_Data *wd = elm_widget_data_get(obj);
5932 return wd->max_items_per_block;
5936 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5939 ELM_CHECK_WIDTYPE(obj, widtype);
5940 Widget_Data *wd = elm_widget_data_get(obj);
5942 wd->longpress_timeout = timeout;
5946 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5948 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5949 Widget_Data *wd = elm_widget_data_get(obj);
5951 return wd->longpress_timeout;
5955 elm_genlist_scroller_policy_set(Evas_Object *obj,
5956 Elm_Scroller_Policy policy_h,
5957 Elm_Scroller_Policy policy_v)
5959 ELM_CHECK_WIDTYPE(obj, widtype);
5960 Widget_Data *wd = elm_widget_data_get(obj);
5961 if ((!wd) || (!wd->scr)) return;
5962 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5963 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5965 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5969 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5970 Elm_Scroller_Policy *policy_h,
5971 Elm_Scroller_Policy *policy_v)
5973 ELM_CHECK_WIDTYPE(obj, widtype);
5974 Widget_Data *wd = elm_widget_data_get(obj);
5975 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5976 if ((!wd) || (!wd->scr)) return;
5977 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5978 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5979 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5983 elm_genlist_realized_items_update(Evas_Object *obj)
5985 ELM_CHECK_WIDTYPE(obj, widtype);
5987 Eina_List *list, *l;
5988 Elm_Object_Item *it;
5990 list = elm_genlist_realized_items_get(obj);
5991 EINA_LIST_FOREACH(list, l, it)
5992 elm_genlist_item_update(it);
5996 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5997 const char *decorate_it_type,
5998 Eina_Bool decorate_it_set)
6000 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6001 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6003 Widget_Data *wd = _it->wd;
6005 Elm_Object_Item *it2;
6008 if (!decorate_it_type) return;
6009 if ((_it->generation < _it->wd->generation) ||
6010 elm_widget_item_disabled_get(_it)) return;
6011 if (wd->decorate_all_mode) return;
6013 if ((wd->mode_item == _it) &&
6014 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
6017 if (!_it->itc->decorate_item_style) return;
6018 _it->decorate_it_set = decorate_it_set;
6022 EINA_LIST_FOREACH(wd->selected, l, it2)
6023 if (((Elm_Gen_Item *)it2)->realized)
6024 elm_genlist_item_selected_set(it2, EINA_FALSE);
6028 it2 = elm_genlist_selected_item_get(wd->obj);
6029 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
6030 elm_genlist_item_selected_set(it2, EINA_FALSE);
6033 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
6034 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
6035 _decorate_item_unset(wd);
6037 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
6038 if (decorate_it_set) _decorate_item_set(_it);
6042 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
6044 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
6045 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6046 return _it->wd->decorate_it_type;
6049 EAPI const Elm_Object_Item *
6050 elm_genlist_decorated_item_get(const Evas_Object *obj)
6052 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6053 Widget_Data *wd = elm_widget_data_get(obj);
6054 if (!wd) return NULL;
6055 return (Elm_Object_Item *) wd->mode_item;
6059 elm_genlist_decorate_mode_get(const Evas_Object *obj)
6061 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6062 Widget_Data *wd = elm_widget_data_get(obj);
6063 if (!wd) return EINA_FALSE;
6065 return wd->decorate_all_mode;
6069 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
6071 ELM_CHECK_WIDTYPE(obj, widtype);
6072 Eina_List *list, *l;
6075 Widget_Data *wd = elm_widget_data_get(obj);
6077 decorated = !!decorated;
6078 if (wd->decorate_all_mode == decorated) return;
6079 wd->decorate_all_mode = decorated;
6081 if (wd->tree_effect_animator)
6083 ecore_animator_del(wd->tree_effect_animator);
6084 wd->tree_effect_animator = NULL;
6086 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6088 list = elm_genlist_realized_items_get(obj);
6089 if (!wd->decorate_all_mode)
6091 EINA_LIST_FOREACH(list, l, it)
6093 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6094 _decorate_all_item_unrealize(it);
6096 _item_cache_zero(wd);
6100 EINA_LIST_FOREACH(list, l, it)
6102 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6104 if (it->itc->decorate_all_item_style)
6105 _decorate_all_item_realize(it, EINA_TRUE);
6109 if (wd->calc_job) ecore_job_del(wd->calc_job);
6110 wd->calc_job = ecore_job_add(_calc_job, wd);
6114 elm_genlist_reorder_mode_set(Evas_Object *obj,
6115 Eina_Bool reorder_mode)
6117 ELM_CHECK_WIDTYPE(obj, widtype);
6118 Widget_Data *wd = elm_widget_data_get(obj);
6120 wd->reorder_mode = !!reorder_mode;
6124 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6126 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6127 Widget_Data *wd = elm_widget_data_get(obj);
6128 if (!wd) return EINA_FALSE;
6129 return wd->reorder_mode;
6132 EAPI Elm_Genlist_Item_Type
6133 elm_genlist_item_type_get(const Elm_Object_Item *it)
6135 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
6136 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6137 return _it->item->type;
6140 EAPI Elm_Genlist_Item_Class *
6141 elm_genlist_item_class_new(void)
6143 Elm_Genlist_Item_Class *itc;
6145 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
6148 itc->version = CLASS_ALLOCATED;
6150 itc->delete_me = EINA_FALSE;
6156 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6158 if (itc && (itc->version == CLASS_ALLOCATED))
6160 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6161 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6171 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6173 if (itc && (itc->version == CLASS_ALLOCATED))
6176 if (itc->refcount == 0) itc->refcount--;
6181 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6183 if (itc && (itc->version == CLASS_ALLOCATED))
6185 if (itc->refcount > 0) itc->refcount--;
6186 if (itc->delete_me && (!itc->refcount))
6187 elm_genlist_item_class_free(itc);
6191 void _flip_job(void *data)
6193 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
6194 _item_unhighlight(it);
6196 _elm_genlist_item_unrealize(it, EINA_FALSE);
6197 it->flipped = EINA_TRUE;
6198 it->item->nocache = EINA_TRUE;
6199 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6200 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
6204 elm_genlist_item_flip_set(Elm_Object_Item *it,
6207 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6208 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6211 if (_it->flipped == flip) return;
6215 ecore_job_add(_flip_job, _it);
6219 _it->flipped = flip;
6220 _item_cache_zero(_it->wd);
6221 elm_genlist_item_update(it);
6222 _it->item->nocache = EINA_FALSE;
6227 elm_genlist_item_flip_get(const Elm_Object_Item *it)
6229 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6230 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6231 return _it->flipped;
6235 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
6237 ELM_CHECK_WIDTYPE(obj, widtype);
6238 Widget_Data *wd = elm_widget_data_get(obj);
6240 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6242 if (wd->select_mode != mode)
6243 wd->select_mode = mode;
6246 EAPI Elm_Object_Select_Mode
6247 elm_genlist_select_mode_get(const Evas_Object *obj)
6249 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
6250 Widget_Data *wd = elm_widget_data_get(obj);
6251 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
6252 return wd->select_mode;
6256 elm_genlist_highlight_mode_set(Evas_Object *obj,
6257 Eina_Bool highlight)
6259 ELM_CHECK_WIDTYPE(obj, widtype);
6260 Widget_Data *wd = elm_widget_data_get(obj);
6262 wd->highlight = !!highlight;
6266 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6268 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6269 Widget_Data *wd = elm_widget_data_get(obj);
6270 if (!wd) return EINA_FALSE;
6271 return wd->highlight;
6275 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
6276 Elm_Object_Select_Mode mode)
6278 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6279 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6281 if (_it->generation < _it->wd->generation) return;
6282 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6284 if (_it->select_mode != mode)
6285 _it->select_mode = mode;
6287 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6289 _it->item->mincalcd = EINA_FALSE;
6290 _it->item->updateme = EINA_TRUE;
6291 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
6292 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
6293 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
6297 EAPI Elm_Object_Select_Mode
6298 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
6300 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
6301 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6302 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
6303 return _it->select_mode;
6306 /* for gengrid as of now */
6308 _elm_genlist_page_relative_set(Evas_Object *obj,
6312 Evas_Coord pagesize_h;
6313 Evas_Coord pagesize_v;
6315 ELM_CHECK_WIDTYPE(obj, widtype);
6316 Widget_Data *wd = elm_widget_data_get(obj);
6319 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
6320 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
6324 /* for gengrid as of now */
6326 _elm_genlist_page_relative_get(const Evas_Object *obj,
6330 ELM_CHECK_WIDTYPE(obj, widtype);
6331 Widget_Data *wd = elm_widget_data_get(obj);
6334 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
6337 /* for gengrid as of now */
6339 _elm_genlist_page_size_set(Evas_Object *obj,
6340 Evas_Coord h_pagesize,
6341 Evas_Coord v_pagesize)
6346 ELM_CHECK_WIDTYPE(obj, widtype);
6347 Widget_Data *wd = elm_widget_data_get(obj);
6349 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
6350 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
6354 /* for gengrid as of now */
6356 _elm_genlist_current_page_get(const Evas_Object *obj,
6360 ELM_CHECK_WIDTYPE(obj, widtype);
6361 Widget_Data *wd = elm_widget_data_get(obj);
6363 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
6366 /* for gengrid as of now */
6368 _elm_genlist_last_page_get(const Evas_Object *obj,
6372 ELM_CHECK_WIDTYPE(obj, widtype);
6373 Widget_Data *wd = elm_widget_data_get(obj);
6375 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
6378 /* for gengrid as of now */
6380 _elm_genlist_page_show(const Evas_Object *obj,
6384 ELM_CHECK_WIDTYPE(obj, widtype);
6385 Widget_Data *wd = elm_widget_data_get(obj);
6387 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
6390 /* for gengrid as of now */
6392 _elm_genlist_page_bring_in(const Evas_Object *obj,
6396 ELM_CHECK_WIDTYPE(obj, widtype);
6397 Widget_Data *wd = elm_widget_data_get(obj);
6399 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
6403 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
6406 Evas_Object *content;
6410 if (!it->realized) return;
6411 if (it->wd->reorder_it == it) return;
6412 if (it->defer_unrealize && !it->item->updateme) return;
6414 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
6416 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
6419 ecore_timer_del(it->long_timer);
6420 it->long_timer = NULL;
6423 EINA_LIST_FOREACH(it->texts, l, part)
6424 edje_object_part_text_set(VIEW(it), part, NULL);
6426 elm_widget_stringlist_free(it->texts);
6428 elm_widget_stringlist_free(it->contents);
6429 it->contents = NULL;
6430 elm_widget_stringlist_free(it->states);
6432 EINA_LIST_FREE(it->content_objs, content)
6433 evas_object_del(content);
6435 it->unrealize_cb(it);
6437 it->realized = EINA_FALSE;
6438 it->want_unrealize = EINA_FALSE;
6439 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
6440 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
6444 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
6446 elm_widget_item_pre_notify_del(it);
6447 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
6449 if ((it->relcount > 0) || (it->walking > 0)) return;
6451 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6453 if (it->itc->func.del)
6454 it->itc->func.del((void *)it->base.data, WIDGET(it));
6458 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
6460 _elm_genlist_item_del_notserious(it);
6461 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6462 if (it->tooltip.del_cb)
6463 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6464 it->wd->walking -= it->walking;
6467 ecore_timer_del(it->long_timer);
6468 it->long_timer = NULL;
6471 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
6475 eina_inlist_sorted_state_free(it->wd->state);
6476 it->wd->state = NULL;
6478 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6479 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
6483 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
6484 it->wd->last_selected_item = NULL;
6485 it->wd->item_count--;
6489 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
6491 ELM_CHECK_WIDTYPE(obj, widtype);
6492 Widget_Data *wd = elm_widget_data_get(obj);
6494 wd->tree_effect_enabled = !!enabled;
6498 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
6500 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6501 Widget_Data *wd = elm_widget_data_get(obj);
6502 if (!wd) return EINA_FALSE;
6503 return wd->tree_effect_enabled;
6507 _create_tray_alpha_bg(const Evas_Object *obj)
6509 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6510 Widget_Data *wd = elm_widget_data_get(obj);
6511 if (!wd) return NULL;
6513 Evas_Object *bg = NULL;
6514 Evas_Coord ox, oy, ow, oh;
6516 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6517 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6518 evas_object_color_set(bg,0,0,0,0);
6519 evas_object_resize(bg , ow, oh);
6520 evas_object_move(bg , ox, oy);
6525 _item_contract_emit(Elm_Gen_Item *it)
6530 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6531 it->item->tree_effect_finished = EINA_FALSE;
6533 EINA_LIST_FOREACH(it->item->items, l, it2)
6534 if (it2) _item_contract_emit(it2);
6538 _item_tree_effect_before(Elm_Gen_Item *it)
6543 EINA_LIST_FOREACH(it->item->items, l, it2)
6545 if (it2->parent && (it == it2->parent))
6548 it2->item->tree_effect_hideme = EINA_TRUE;
6549 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6550 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6551 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6552 _item_contract_emit(it2);
6555 return ECORE_CALLBACK_CANCEL;
6559 _item_tree_effect(Widget_Data *wd, int y)
6561 Elm_Gen_Item *it = NULL, *expanded_next_it;
6563 expanded_next_it = wd->expanded_next_item;
6565 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6567 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6570 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6571 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6572 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6574 if (!it->item->tree_effect_finished)
6576 edje_object_signal_emit(VIEW(it), "flip_item", "");
6577 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6578 it->item->tree_effect_finished = EINA_TRUE;
6581 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6584 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6586 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6589 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6590 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6592 if (!it->item->tree_effect_finished)
6594 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6595 it->item->tree_effect_finished = EINA_TRUE;
6600 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6606 _item_tree_effect_finish(Widget_Data *wd)
6608 Elm_Gen_Item *it = NULL;
6611 if (wd->tree_effect_animator)
6613 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6614 _item_subitems_clear(wd->expanded_item);
6615 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6617 it->item->tree_effect_finished = EINA_TRUE;
6618 it->item->old_scrl_y = it->item->scrl_y;
6619 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6620 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6623 _item_auto_scroll(wd);
6624 evas_object_lower(wd->alpha_bg);
6625 evas_object_hide(wd->alpha_bg);
6626 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6627 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6629 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6630 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6631 evas_object_smart_changed(wd->pan_smart);
6633 wd->tree_effect_animator = NULL;
6637 _tree_effect_animator_cb(void *data)
6639 Widget_Data *wd = data;
6640 if (!wd) return ECORE_CALLBACK_CANCEL;
6641 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6642 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6644 double effect_duration = 0.3, t;
6645 int y = 0, dy = 0, dh = 0;
6646 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6649 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6650 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6651 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6652 if (t > effect_duration) end = EINA_TRUE;
6654 // Below while statement is needed, when the genlist is resized.
6655 it2 = wd->expanded_item;
6658 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6659 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6660 cvx, cvy, cvw, cvh));
6661 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6664 if (wd->expanded_next_item)
6666 expanded_next_it = wd->expanded_next_item;
6669 EINA_LIST_FOREACH(wd->move_items, l, it)
6671 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6673 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6674 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6675 expanded_next_it->item->scrl_y = cvy + cvh;
6677 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6678 cvy + cvh : expanded_next_it->item->scrl_y) -
6679 expanded_next_it->item->old_scrl_y;
6681 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6683 if (expanded_next_it->item->scrl_y > expanded_next_it->item->old_scrl_y) //did not calculate next item position
6684 expanded_next_it->item->old_scrl_y = cvy + cvh;
6686 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6688 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6690 expanded_next_it->item->old_scrl_y = cvy + cvh;
6694 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6695 expanded_next_it->item->old_scrl_y;
6699 if (t <= effect_duration)
6701 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6709 if (!it->realized && !it->item->queued)
6710 _item_realize(it, in, 0);
6713 if (it != expanded_next_it)
6715 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6719 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6720 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6723 _item_tree_effect(wd, y);
6727 int expanded_item_num = 0;
6730 if (wd->expanded_item)
6731 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6736 expanded_item_num++;
6737 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6743 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6744 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6746 if (!it->item->tree_effect_finished)
6748 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6750 edje_object_signal_emit(VIEW(it), "flip_item", "");
6751 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6752 it->item->tree_effect_finished = EINA_TRUE;
6756 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6762 _item_tree_effect_finish(wd);
6763 return ECORE_CALLBACK_CANCEL;
6765 return ECORE_CALLBACK_RENEW;