3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.h"
9 // internally allocated
10 #define CLASS_ALLOCATED 0x3a70f11f
12 #define MAX_ITEMS_PER_BLOCK 32
13 #define REORDER_EFFECT_TIME 0.5
15 #define ELM_GEN_SETUP(wd) \
16 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
17 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
18 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
32 ERR("Genlist_Item_Class(itc) is NULL"); \
35 if ((itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) && \
36 (itc->version != CLASS_ALLOCATED)) \
38 ERR("Genlist_Item_Class version mismatched! current = (%d), required = (%d) or (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION, CLASS_ALLOCATED); \
44 typedef struct _Item_Block Item_Block;
45 typedef struct _Item_Cache Item_Cache;
47 struct Elm_Gen_Item_Type
52 Evas_Coord w, h, minw, minh;
53 Elm_Gen_Item *group_item;
54 Elm_Genlist_Item_Type type;
55 Eina_List *deco_it_texts, *deco_it_contents, *deco_it_states, *deco_it_content_objs;
56 Eina_List *deco_all_texts, *deco_all_contents, *deco_all_states, *deco_all_content_objs;
57 Eina_List *flip_contents, *flip_content_objs;
58 Ecore_Timer *swipe_timer;
59 Evas_Coord scrl_x, scrl_y, old_scrl_y;
62 Evas_Object *deco_it_view;
68 Eina_Bool want_realize : 1;
69 Eina_Bool expanded : 1;
70 Eina_Bool mincalcd : 1;
73 Eina_Bool updateme : 1;
74 Eina_Bool nocache : 1; /* do not use cache for this item */
75 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
76 Eina_Bool stacking_even : 1;
77 Eina_Bool nostacking : 1;
78 Eina_Bool move_effect_enabled : 1;
79 Eina_Bool decorate_all_item_realized : 1;
80 Eina_Bool tree_effect_finished : 1; /* tree effect */
81 Eina_Bool tree_effect_hideme : 1; /* item hide for tree effect */
92 Evas_Coord x, y, w, h, minw, minh;
94 int item_position_stamp;
96 Eina_Bool position_update : 1;
97 Eina_Bool want_unrealize : 1;
98 Eina_Bool realized : 1;
99 Eina_Bool changed : 1;
100 Eina_Bool updateme : 1;
101 Eina_Bool changeme : 1;
102 Eina_Bool showme : 1;
103 Eina_Bool must_recalc : 1;
110 Evas_Object *base_view, *spacer;
112 const char *item_style; // it->itc->item_style
113 Eina_Bool tree : 1; // it->group
115 Eina_Bool selected : 1; // it->selected
116 Eina_Bool disabled : 1; // it->disabled
117 Eina_Bool expanded : 1; // it->item->expanded
120 static const char *widtype = NULL;
121 static void _item_cache_zero(Widget_Data *wd);
122 static void _del_hook(Evas_Object *obj);
123 static void _mirrored_set(Evas_Object *obj,
125 static void _theme_hook(Evas_Object *obj);
126 static void _show_region_hook(void *data,
128 static void _sizing_eval(Evas_Object *obj);
129 static void _item_realize(Elm_Gen_Item *it,
132 static void _item_unrealize_cb(Elm_Gen_Item *it);
133 static void _item_block_unrealize(Item_Block *itb);
134 static void _calc_job(void *data);
135 static void _on_focus_hook(void *data,
137 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
138 static void _changed_job(void *data);
139 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
140 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
141 static Eina_Bool _item_single_select_up(Widget_Data *wd);
142 static Eina_Bool _item_single_select_down(Widget_Data *wd);
143 static Eina_Bool _event_hook(Evas_Object *obj,
145 Evas_Callback_Type type,
147 static void _signal_emit_hook(Evas_Object *obj,
148 const char *emission,
150 static Eina_Bool _deselect_all_items(Widget_Data *wd);
151 static void _pan_calculate(Evas_Object *obj);
152 static void _pan_max_get(Evas_Object *obj,
155 static void _item_position(Elm_Gen_Item *it,
159 static void _decorate_item_realize(Elm_Gen_Item *it);
160 static void _decorate_item_unrealize(Elm_Gen_Item *it);
161 static void _decorate_item_set(Elm_Gen_Item *it);
162 static void _decorate_item_unset(Widget_Data *wd);
163 static void _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity);
164 static void _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
165 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
168 static void _group_items_recalc(void *data);
170 static void _item_move_after(Elm_Gen_Item *it,
171 Elm_Gen_Item *after);
172 static void _item_move_before(Elm_Gen_Item *it,
173 Elm_Gen_Item *before);
174 static void _item_auto_scroll(Widget_Data *wd);
175 static void _elm_genlist_clear(Evas_Object *obj,
177 static void _pan_child_size_get(Evas_Object *obj,
180 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
181 static void _item_contract_emit(Elm_Gen_Item *it);
182 static int _item_tree_effect_before(Elm_Gen_Item *it);
183 static void _item_tree_effect(Widget_Data *wd, int y);
184 static void _item_tree_effect_finish(Widget_Data *wd);
185 static Eina_Bool _tree_effect_animator_cb(void *data);
187 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
189 static const char SIG_ACTIVATED[] = "activated";
190 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
191 static const char SIG_SELECTED[] = "selected";
192 static const char SIG_UNSELECTED[] = "unselected";
193 static const char SIG_EXPANDED[] = "expanded";
194 static const char SIG_CONTRACTED[] = "contracted";
195 static const char SIG_EXPAND_REQUEST[] = "expand,request";
196 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
197 static const char SIG_REALIZED[] = "realized";
198 static const char SIG_UNREALIZED[] = "unrealized";
199 static const char SIG_DRAG_START_UP[] = "drag,start,up";
200 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
201 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
202 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
203 static const char SIG_DRAG_STOP[] = "drag,stop";
204 static const char SIG_DRAG[] = "drag";
205 static const char SIG_LONGPRESSED[] = "longpressed";
206 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
207 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
208 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
209 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
210 static const char SIG_EDGE_TOP[] = "edge,top";
211 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
212 static const char SIG_EDGE_LEFT[] = "edge,left";
213 static const char SIG_EDGE_RIGHT[] = "edge,right";
214 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
215 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
216 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
217 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
218 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
219 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
220 static const char SIG_SWIPE[] = "swipe";
221 static const char SIG_MOVED[] = "moved";
222 static const char SIG_MOVED_AFTER[] = "moved,after";
223 static const char SIG_MOVED_BEFORE[] = "moved,before";
224 static const char SIG_INDEX_UPDATE[] = "index,update";
225 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
227 static const Evas_Smart_Cb_Description _signals[] = {
228 {SIG_CLICKED_DOUBLE, ""},
231 {SIG_UNSELECTED, ""},
233 {SIG_CONTRACTED, ""},
234 {SIG_EXPAND_REQUEST, ""},
235 {SIG_CONTRACT_REQUEST, ""},
237 {SIG_UNREALIZED, ""},
238 {SIG_DRAG_START_UP, ""},
239 {SIG_DRAG_START_DOWN, ""},
240 {SIG_DRAG_START_LEFT, ""},
241 {SIG_DRAG_START_RIGHT, ""},
244 {SIG_LONGPRESSED, ""},
245 {SIG_SCROLL_ANIM_START, ""},
246 {SIG_SCROLL_ANIM_STOP, ""},
247 {SIG_SCROLL_DRAG_START, ""},
248 {SIG_SCROLL_DRAG_STOP, ""},
250 {SIG_EDGE_BOTTOM, ""},
252 {SIG_EDGE_RIGHT, ""},
253 {SIG_MULTI_SWIPE_LEFT, ""},
254 {SIG_MULTI_SWIPE_RIGHT, ""},
255 {SIG_MULTI_SWIPE_UP, ""},
256 {SIG_MULTI_SWIPE_DOWN, ""},
257 {SIG_MULTI_PINCH_OUT, ""},
258 {SIG_MULTI_PINCH_IN, ""},
261 {SIG_MOVED_AFTER, ""},
262 {SIG_MOVED_BEFORE, ""},
263 {SIG_TREE_EFFECT_FINISHED, ""},
268 #undef ELM_CHECK_WIDTYPE
269 #define ELM_CHECK_WIDTYPE(obj, widtype) \
270 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
271 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
272 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
273 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
274 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
276 static const char *_gengrid = NULL;
277 static const char *_genlist = NULL;
279 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
281 elm_genlist_type_check(const Evas_Object *obj,
284 const char *provided, *expected = "(unknown)";
285 static int abort_on_warn = -1;
286 provided = elm_widget_type_get(obj);
287 if (!_genlist) _genlist = eina_stringshare_add("genlist");
288 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
289 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
291 if ((!provided) || (!provided[0]))
293 provided = evas_object_type_get(obj);
294 if ((!provided) || (!provided[0]))
295 provided = "(unknown)";
297 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
298 if (abort_on_warn == -1)
300 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
301 else abort_on_warn = 0;
303 if (abort_on_warn == 1) abort();
308 _event_hook(Evas_Object *obj,
309 Evas_Object *src __UNUSED__,
310 Evas_Callback_Type type,
313 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
314 Evas_Event_Key_Down *ev = event_info;
315 Widget_Data *wd = elm_widget_data_get(obj);
316 Evas_Coord pan_max_x = 0, pan_max_y = 0;
317 if (!wd) return EINA_FALSE;
318 if (!wd->items) return EINA_FALSE;
319 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
320 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
322 Elm_Object_Item *it = NULL;
325 Evas_Coord step_x = 0;
326 Evas_Coord step_y = 0;
329 Evas_Coord page_x = 0;
330 Evas_Coord page_y = 0;
332 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
333 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
334 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
335 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
337 if ((!strcmp(ev->keyname, "Left")) ||
338 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
342 else if ((!strcmp(ev->keyname, "Right")) ||
343 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
347 else if ((!strcmp(ev->keyname, "Up")) ||
348 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
350 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
351 (_item_multi_select_up(wd)))
352 || (_item_single_select_up(wd)))
354 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
360 else if ((!strcmp(ev->keyname, "Down")) ||
361 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
363 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
364 (_item_multi_select_down(wd)))
365 || (_item_single_select_down(wd)))
367 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
373 else if ((!strcmp(ev->keyname, "Home")) ||
374 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
376 it = elm_genlist_first_item_get(obj);
377 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
378 elm_genlist_item_selected_set(it, EINA_TRUE);
379 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
382 else if ((!strcmp(ev->keyname, "End")) ||
383 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
385 it = elm_genlist_last_item_get(obj);
386 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
387 elm_genlist_item_selected_set(it, EINA_TRUE);
388 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
391 else if ((!strcmp(ev->keyname, "Prior")) ||
392 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
395 y -= -(page_y * v_h) / 100;
399 else if ((!strcmp(ev->keyname, "Next")) ||
400 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
403 y += -(page_y * v_h) / 100;
407 else if (!strcmp(ev->keyname, "Escape"))
409 if (!_deselect_all_items(wd)) return EINA_FALSE;
410 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
413 else if (((!strcmp(ev->keyname, "Return")) ||
414 (!strcmp(ev->keyname, "KP_Enter")) ||
415 (!strcmp(ev->keyname, "space")))
416 && (!wd->multi) && (wd->selected))
418 it = elm_genlist_selected_item_get(obj);
419 elm_genlist_item_expanded_set(it,
420 !elm_genlist_item_expanded_get(it));
421 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
423 else return EINA_FALSE;
425 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
426 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
428 if (x > pan_max_x) x = pan_max_x;
430 if (y > pan_max_y) y = pan_max_y;
431 elm_smart_scroller_child_pos_set(wd->scr, x, y);
436 _deselect_all_items(Widget_Data *wd)
438 if (!wd->selected) return EINA_FALSE;
440 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
446 _item_multi_select_up(Widget_Data *wd)
448 if (!wd->selected) return EINA_FALSE;
449 if (!wd->multi) return EINA_FALSE;
451 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
452 if (!prev) return EINA_TRUE;
454 if (elm_genlist_item_selected_get(prev))
456 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
457 wd->last_selected_item = prev;
458 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
462 elm_genlist_item_selected_set(prev, EINA_TRUE);
463 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
469 _item_multi_select_down(Widget_Data *wd)
471 if (!wd->selected) return EINA_FALSE;
472 if (!wd->multi) return EINA_FALSE;
474 Elm_Object_Item *next;
475 next = elm_genlist_item_next_get(wd->last_selected_item);
476 if (!next) return EINA_TRUE;
478 if (elm_genlist_item_selected_get(next))
480 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
481 wd->last_selected_item = next;
482 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
486 elm_genlist_item_selected_set(next, EINA_TRUE);
487 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
493 _item_single_select_up(Widget_Data *wd)
498 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
499 while ((prev) && (prev->generation < wd->generation))
500 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
502 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
504 if (!prev) return EINA_FALSE;
506 _deselect_all_items(wd);
508 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
509 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
514 _item_single_select_down(Widget_Data *wd)
519 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
520 while ((next) && (next->generation < wd->generation))
521 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
523 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
525 if (!next) return EINA_FALSE;
527 _deselect_all_items(wd);
529 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
530 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
535 _on_focus_hook(void *data __UNUSED__,
538 Widget_Data *wd = elm_widget_data_get(obj);
540 if (elm_widget_focus_get(obj))
542 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
543 evas_object_focus_set(wd->obj, EINA_TRUE);
544 if ((wd->items) && (wd->selected) && (!wd->last_selected_item))
545 wd->last_selected_item = eina_list_data_get(wd->selected);
549 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
550 evas_object_focus_set(wd->obj, EINA_FALSE);
555 _del_hook(Evas_Object *obj)
557 Widget_Data *wd = elm_widget_data_get(obj);
559 _item_cache_zero(wd);
560 if (wd->calc_job) ecore_job_del(wd->calc_job);
561 if (wd->update_job) ecore_job_del(wd->update_job);
562 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
563 if (wd->changed_job) ecore_job_del(wd->changed_job);
564 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
565 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
566 if (wd->decorate_it_type) eina_stringshare_del(wd->decorate_it_type);
567 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
568 if (wd->tree_effect_animator) ecore_animator_del(wd->tree_effect_animator);
573 _del_pre_hook(Evas_Object *obj)
575 Widget_Data *wd = elm_widget_data_get(obj);
577 if (wd->decorate_all_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
578 elm_genlist_clear(obj);
579 evas_object_del(wd->pan_smart);
580 wd->pan_smart = NULL;
584 _mirrored_set(Evas_Object *obj,
587 Widget_Data *wd = elm_widget_data_get(obj);
589 _item_cache_zero(wd);
590 elm_smart_scroller_mirrored_set(wd->scr, rtl);
594 _theme_hook(Evas_Object *obj)
596 Widget_Data *wd = elm_widget_data_get(obj);
599 evas_event_freeze(evas_object_evas_get(wd->obj));
600 _item_cache_zero(wd);
601 _elm_widget_mirrored_reload(obj);
602 _mirrored_set(obj, elm_widget_mirrored_get(obj));
603 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
604 elm_widget_style_get(obj));
605 //edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
606 wd->item_width = wd->item_height = 0;
607 wd->group_item_width = wd->group_item_height = 0;
608 wd->minw = wd->minh = wd->realminw = 0;
609 EINA_INLIST_FOREACH(wd->blocks, itb)
614 if (itb->realized) _item_block_unrealize(itb);
615 EINA_LIST_FOREACH(itb->items, l, it)
616 it->item->mincalcd = EINA_FALSE;
618 itb->changed = EINA_TRUE;
620 if (wd->calc_job) ecore_job_del(wd->calc_job);
621 wd->calc_job = ecore_job_add(_calc_job, wd);
623 evas_event_thaw(evas_object_evas_get(wd->obj));
624 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
628 _show_region_hook(void *data,
631 Widget_Data *wd = elm_widget_data_get(data);
632 Evas_Coord x, y, w, h;
634 elm_widget_show_region_get(obj, &x, &y, &w, &h);
635 //x & y are screen coordinates, Add with pan coordinates
638 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
642 _translate_hook(Evas_Object *obj)
644 evas_object_smart_callback_call(obj, "language,changed", NULL);
648 _sizing_eval(Evas_Object *obj)
650 Widget_Data *wd = elm_widget_data_get(obj);
651 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
652 Evas_Coord vmw = 0, vmh = 0;
655 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
656 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
658 edje_object_size_min_calc
659 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
661 if (wd->mode == ELM_LIST_COMPRESS)
665 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
666 if ((vw != 0) && (vw != wd->prev_viewport_w))
670 wd->prev_viewport_w = vw;
671 EINA_INLIST_FOREACH(wd->blocks, itb)
673 itb->must_recalc = EINA_TRUE;
675 if (wd->calc_job) ecore_job_del(wd->calc_job);
676 wd->calc_job = ecore_job_add(_calc_job, wd);
678 edje_object_size_min_calc
679 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
683 else if (wd->mode == ELM_LIST_LIMIT)
686 minw = vmw + wd->realminw;
694 evas_object_size_hint_min_set(obj, minw, minh);
695 evas_object_size_hint_max_set(obj, maxw, maxh);
699 _signal_emit_hook(Evas_Object *obj,
700 const char *emission,
703 Widget_Data *wd = elm_widget_data_get(obj);
704 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
709 _item_highlight(Elm_Gen_Item *it)
711 const char *selectraise;
712 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
713 (!it->wd->highlight) ||
714 (it->generation < it->wd->generation) ||
715 (it->highlighted) || elm_widget_item_disabled_get(it) ||
716 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->deco_it_view) ||
717 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
719 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
720 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
721 selectraise = edje_object_data_get(VIEW(it), "selectraise");
722 if ((selectraise) && (!strcmp(selectraise, "on")))
724 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
725 else evas_object_raise(VIEW(it));
728 if ((it->item->group_item) && (it->item->group_item->realized))
729 evas_object_raise(it->item->VIEW(group_item));
732 it->highlighted = EINA_TRUE;
736 _item_unhighlight(Elm_Gen_Item *it)
738 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
739 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
740 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
741 if (!it->item->nostacking)
743 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
745 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
746 else evas_object_lower(VIEW(it));
750 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
751 else evas_object_raise(VIEW(it));
754 it->highlighted = EINA_FALSE;
758 _item_block_position_update(Eina_Inlist *list, int idx)
762 EINA_INLIST_FOREACH(list, tmp)
764 tmp->position = idx++;
765 tmp->position_update = EINA_TRUE;
770 _item_position_update(Eina_List *list, int idx)
775 EINA_LIST_FOREACH(list, l, it)
777 it->position = idx++;
778 it->position_update = EINA_TRUE;
783 _item_block_del(Elm_Gen_Item *it)
786 Item_Block *itb = it->item->block;
787 Eina_Bool block_changed;
789 itb->items = eina_list_remove(itb->items, it);
791 itb->changed = EINA_TRUE;
792 if (!it->wd->reorder_deleted)
794 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
795 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
799 il = EINA_INLIST_GET(itb);
800 Item_Block *itbn = (Item_Block *)(il->next);
802 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
805 _item_block_position_update(il->next, itb->position);
806 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
809 if (itbn) itbn->changed = EINA_TRUE;
813 if (itb->count < itb->wd->max_items_per_block/2)
815 il = EINA_INLIST_GET(itb);
816 Item_Block *itbp = (Item_Block *)(il->prev);
817 Item_Block *itbn = (Item_Block *)(il->next);
818 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
822 EINA_LIST_FREE(itb->items, it2)
824 it2->item->block = itbp;
825 itbp->items = eina_list_append(itbp->items, it2);
827 itbp->changed = EINA_TRUE;
829 _item_block_position_update(EINA_INLIST_GET(itb)->next,
831 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
832 EINA_INLIST_GET(itb));
834 block_changed = EINA_TRUE;
836 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
840 Eina_List *last = eina_list_last(itb->items);
841 Elm_Gen_Item *it2 = last->data;
843 it2->item->block = itbn;
844 itb->items = eina_list_remove_list(itb->items, last);
845 itbn->items = eina_list_prepend(itbn->items, it2);
847 itbn->changed = EINA_TRUE;
849 _item_block_position_update(EINA_INLIST_GET(itb)->next,
852 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
854 block_changed = EINA_TRUE;
860 it->wd->pan_changed = EINA_TRUE;
861 evas_object_smart_changed(it->wd->pan_smart);
862 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
863 it->wd->calc_job = NULL;
868 _item_subitems_clear(Elm_Gen_Item *it)
870 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
871 Eina_List *tl = NULL, *l;
872 Elm_Object_Item *it2;
874 EINA_LIST_FOREACH(it->item->items, l, it2)
875 tl = eina_list_append(tl, it2);
876 EINA_LIST_FREE(tl, it2)
877 elm_object_item_del(it2);
881 _item_del(Elm_Gen_Item *it)
883 Evas_Object *obj = WIDGET(it);
884 Widget_Data *wd = it->wd;
886 evas_event_freeze(evas_object_evas_get(obj));
887 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
888 if (wd->show_item == it) wd->show_item = NULL;
889 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
890 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
891 if (it->item->block) _item_block_del(it);
892 if (it->item->queued)
893 wd->queue = eina_list_remove(wd->queue, it);
894 if (wd->anchor_item == it)
896 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
897 if (!wd->anchor_item)
898 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
900 if (wd->expanded_item == it)
902 wd->expanded_item = NULL;
903 if (wd->tree_effect_animator)
905 ecore_animator_del(wd->tree_effect_animator);
906 wd->tree_effect_animator = NULL;
908 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
910 if (wd->expanded_next_item == it) wd->expanded_next_item = NULL;
911 if (wd->move_items) wd->move_items = eina_list_remove(wd->move_items, it);
913 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
914 if (it->item->swipe_timer)
916 ecore_timer_del(it->item->swipe_timer);
917 it->item->swipe_timer = NULL;
919 _elm_genlist_item_del_serious(it);
920 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
921 evas_event_thaw(evas_object_evas_get(obj));
922 evas_event_thaw_eval(evas_object_evas_get(obj));
926 _clear_cb(Widget_Data *wd)
928 wd->anchor_item = NULL;
929 if (wd->queue_idle_enterer)
931 ecore_idle_enterer_del(wd->queue_idle_enterer);
932 wd->queue_idle_enterer = NULL;
934 if (wd->must_recalc_idler)
936 ecore_idler_del(wd->must_recalc_idler);
937 wd->must_recalc_idler = NULL;
939 if (wd->queue) wd->queue = eina_list_free(wd->queue);
940 if (wd->reorder_move_animator)
942 ecore_animator_del(wd->reorder_move_animator);
943 wd->reorder_move_animator = NULL;
945 wd->show_item = NULL;
946 wd->reorder_old_pan_y = 0;
950 _item_unselect(Elm_Gen_Item *it)
952 if ((it->generation < it->wd->generation) || (!it->selected)) return;
953 it->selected = EINA_FALSE;
954 it->wd->selected = eina_list_remove(it->wd->selected, it);
955 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
959 _mouse_move(void *data,
960 Evas *evas __UNUSED__,
964 Elm_Gen_Item *it = data;
965 Evas_Event_Mouse_Move *ev = event_info;
966 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
967 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
969 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
971 if (!it->wd->on_hold)
973 it->wd->on_hold = EINA_TRUE;
974 if ((!it->wd->wasselected) && (!it->flipped))
976 _item_unhighlight(it);
981 if (it->wd->multitouched)
983 it->wd->cur_x = ev->cur.canvas.x;
984 it->wd->cur_y = ev->cur.canvas.y;
987 if ((it->dragging) && (it->down))
989 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
992 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
993 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
994 if (abs((it->wd->history[it->wd->movements].x -
995 it->wd->history[0].x)) > 40)
996 it->wd->swipe = EINA_TRUE;
1002 ecore_timer_del(it->long_timer);
1003 it->long_timer = NULL;
1005 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
1008 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
1012 ecore_timer_del(it->long_timer);
1013 it->long_timer = NULL;
1015 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1017 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
1018 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
1020 if (!it->wd->reorder_start_y)
1021 it->wd->reorder_start_y = it->item->block->y + it->y;
1025 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
1026 y_pos = oy + oh - it->wd->reorder_it->item->h;
1030 if (it->deco_all_view)
1031 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
1033 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1035 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1036 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1040 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1041 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1042 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1043 x = ev->cur.canvas.x - x;
1044 y = ev->cur.canvas.y - y;
1047 if (adx < 0) adx = -dx;
1050 if (ady < 0) ady = -dy;
1053 if ((adx > minw) || (ady > minh))
1055 it->dragging = EINA_TRUE;
1058 ecore_timer_del(it->long_timer);
1059 it->long_timer = NULL;
1061 if ((!it->wd->wasselected) && (!it->flipped))
1063 _item_unhighlight(it);
1068 if ((ady > adx) && (!it->wd->drag_started))
1069 evas_object_smart_callback_call(WIDGET(it),
1070 SIG_DRAG_START_UP, it);
1074 evas_object_smart_callback_call(WIDGET(it),
1075 SIG_DRAG_START_LEFT, it);
1077 evas_object_smart_callback_call(WIDGET(it),
1078 SIG_DRAG_START_RIGHT, it);
1083 if ((ady > adx) && (!it->wd->drag_started))
1084 evas_object_smart_callback_call(WIDGET(it),
1085 SIG_DRAG_START_DOWN, it);
1089 evas_object_smart_callback_call(WIDGET(it),
1090 SIG_DRAG_START_LEFT, it);
1092 evas_object_smart_callback_call(WIDGET(it),
1093 SIG_DRAG_START_RIGHT, it);
1100 _long_press(void *data)
1102 Elm_Gen_Item *it = data, *it_tmp;
1103 Eina_List *list, *l;
1105 it->long_timer = NULL;
1106 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1107 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1108 return ECORE_CALLBACK_CANCEL;
1109 it->wd->longpressed = EINA_TRUE;
1110 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1111 if ((it->wd->reorder_mode) && (!it->group))
1113 it->wd->reorder_it = it;
1114 it->wd->reorder_start_y = 0;
1115 if (it->deco_all_view)
1116 evas_object_raise(it->deco_all_view);
1118 evas_object_raise(VIEW(it));
1120 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1121 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1123 list = elm_genlist_realized_items_get(it->wd->obj);
1124 EINA_LIST_FOREACH(list, l, it_tmp)
1126 if (it != it_tmp) _item_unselect(it_tmp);
1128 if (it->item->items)
1130 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
1132 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
1134 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
1136 return ECORE_CALLBACK_RENEW;
1140 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1142 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1143 return ECORE_CALLBACK_RENEW;
1146 if (!it->wd->decorate_all_mode)
1147 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1149 return ECORE_CALLBACK_CANCEL;
1153 _swipe(Elm_Gen_Item *it)
1158 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1159 elm_widget_item_disabled_get(it)) return;
1160 it->wd->swipe = EINA_FALSE;
1161 for (i = 0; i < it->wd->movements; i++)
1163 sum += it->wd->history[i].x;
1164 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1167 sum /= it->wd->movements;
1168 if (abs(sum - it->wd->history[0].x) <= 10) return;
1169 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1173 _swipe_cancel(void *data)
1175 Elm_Gen_Item *it = data;
1177 if (!it) return ECORE_CALLBACK_CANCEL;
1178 it->wd->swipe = EINA_FALSE;
1179 it->wd->movements = 0;
1180 return ECORE_CALLBACK_RENEW;
1184 _multi_cancel(void *data)
1186 Widget_Data *wd = data;
1188 if (!wd) return ECORE_CALLBACK_CANCEL;
1189 wd->multi_timeout = EINA_TRUE;
1190 return ECORE_CALLBACK_RENEW;
1194 _multi_touch_gesture_eval(void *data)
1196 Elm_Gen_Item *it = data;
1198 it->wd->multitouched = EINA_FALSE;
1199 if (it->wd->multi_timer)
1201 ecore_timer_del(it->wd->multi_timer);
1202 it->wd->multi_timer = NULL;
1204 if (it->wd->multi_timeout)
1206 it->wd->multi_timeout = EINA_FALSE;
1210 Evas_Coord minw = 0, minh = 0;
1211 Evas_Coord off_x, off_y, off_mx, off_my;
1213 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1214 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1215 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1216 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1217 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1219 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1221 if ((off_x + off_mx) > (off_y + off_my))
1223 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1224 evas_object_smart_callback_call(WIDGET(it),
1225 SIG_MULTI_SWIPE_RIGHT, it);
1226 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1227 evas_object_smart_callback_call(WIDGET(it),
1228 SIG_MULTI_SWIPE_LEFT, it);
1229 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1230 evas_object_smart_callback_call(WIDGET(it),
1231 SIG_MULTI_PINCH_OUT, it);
1233 evas_object_smart_callback_call(WIDGET(it),
1234 SIG_MULTI_PINCH_IN, it);
1238 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1239 evas_object_smart_callback_call(WIDGET(it),
1240 SIG_MULTI_SWIPE_DOWN, it);
1241 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1242 evas_object_smart_callback_call(WIDGET(it),
1243 SIG_MULTI_SWIPE_UP, it);
1244 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1245 evas_object_smart_callback_call(WIDGET(it),
1246 SIG_MULTI_PINCH_OUT, it);
1248 evas_object_smart_callback_call(WIDGET(it),
1249 SIG_MULTI_PINCH_IN, it);
1252 it->wd->multi_timeout = EINA_FALSE;
1256 _multi_down(void *data,
1257 Evas *evas __UNUSED__,
1258 Evas_Object *obj __UNUSED__,
1261 Elm_Gen_Item *it = data;
1262 Evas_Event_Multi_Down *ev = event_info;
1264 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1265 it->wd->multi_device = ev->device;
1266 it->wd->multi_down = EINA_TRUE;
1267 it->wd->multitouched = EINA_TRUE;
1268 it->wd->prev_mx = ev->canvas.x;
1269 it->wd->prev_my = ev->canvas.y;
1270 if (!it->wd->wasselected)
1272 _item_unhighlight(it);
1275 it->wd->wasselected = EINA_FALSE;
1276 it->wd->longpressed = EINA_FALSE;
1279 ecore_timer_del(it->long_timer);
1280 it->long_timer = NULL;
1284 it->dragging = EINA_FALSE;
1285 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1287 if (it->item->swipe_timer)
1289 ecore_timer_del(it->item->swipe_timer);
1290 it->item->swipe_timer = NULL;
1292 if (it->wd->on_hold)
1294 it->wd->swipe = EINA_FALSE;
1295 it->wd->movements = 0;
1296 it->wd->on_hold = EINA_FALSE;
1301 _multi_up(void *data,
1302 Evas *evas __UNUSED__,
1303 Evas_Object *obj __UNUSED__,
1306 Elm_Gen_Item *it = data;
1307 Evas_Event_Multi_Up *ev = event_info;
1309 if (it->wd->multi_device != ev->device) return;
1310 it->wd->multi_device = 0;
1311 it->wd->multi_down = EINA_FALSE;
1312 if (it->wd->mouse_down) return;
1313 _multi_touch_gesture_eval(data);
1317 _multi_move(void *data,
1318 Evas *evas __UNUSED__,
1319 Evas_Object *obj __UNUSED__,
1322 Elm_Gen_Item *it = data;
1323 Evas_Event_Multi_Move *ev = event_info;
1325 if (it->wd->multi_device != ev->device) return;
1326 it->wd->cur_mx = ev->cur.canvas.x;
1327 it->wd->cur_my = ev->cur.canvas.y;
1331 _mouse_down(void *data,
1332 Evas *evas __UNUSED__,
1336 Elm_Gen_Item *it = data;
1337 Evas_Event_Mouse_Down *ev = event_info;
1340 Evas_Object *item_obj;
1342 if (ev->button != 1) return;
1345 EINA_LIST_FOREACH(it->content_objs, l, item_obj)
1347 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1349 if (elm_widget_type_get(obj) == _genlist)
1351 EINA_LIST_FOREACH(it->item->flip_content_objs, l, item_obj)
1353 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1355 EINA_LIST_FOREACH(it->item->deco_all_content_objs, l, item_obj)
1357 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1360 it->can_focus = EINA_TRUE;
1362 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1364 it->wd->on_hold = EINA_TRUE;
1367 it->down = EINA_TRUE;
1368 it->dragging = EINA_FALSE;
1369 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1370 it->dx = ev->canvas.x - x;
1371 it->dy = ev->canvas.y - y;
1372 it->wd->mouse_down = EINA_TRUE;
1373 if (!it->wd->multitouched)
1375 it->wd->prev_x = ev->canvas.x;
1376 it->wd->prev_y = ev->canvas.y;
1377 it->wd->multi_timeout = EINA_FALSE;
1378 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1379 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1381 it->wd->longpressed = EINA_FALSE;
1382 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1383 else it->wd->on_hold = EINA_FALSE;
1384 if (it->wd->on_hold) return;
1385 it->wd->wasselected = it->selected;
1386 _item_highlight(it);
1387 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1388 if ((!elm_widget_item_disabled_get(it)) &&
1389 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1391 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1392 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1394 if (it->long_timer) ecore_timer_del(it->long_timer);
1395 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1396 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1398 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1401 it->long_timer = NULL;
1402 it->wd->swipe = EINA_FALSE;
1403 it->wd->movements = 0;
1407 _mouse_up(void *data,
1408 Evas *evas __UNUSED__,
1409 Evas_Object *obj __UNUSED__,
1412 Elm_Gen_Item *it = data;
1413 Evas_Event_Mouse_Up *ev = event_info;
1414 Eina_Bool dragged = EINA_FALSE;
1416 if (ev->button != 1) return;
1417 it->down = EINA_FALSE;
1418 it->wd->mouse_down = EINA_FALSE;
1419 if (it->wd->multitouched)
1421 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1422 if (it->wd->multi_down) return;
1423 _multi_touch_gesture_eval(data);
1426 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1427 else it->wd->on_hold = EINA_FALSE;
1430 ecore_timer_del(it->long_timer);
1431 it->long_timer = NULL;
1435 it->dragging = EINA_FALSE;
1436 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1439 if (it->item->swipe_timer)
1441 ecore_timer_del(it->item->swipe_timer);
1442 it->item->swipe_timer = NULL;
1444 if (it->wd->multi_timer)
1446 ecore_timer_del(it->wd->multi_timer);
1447 it->wd->multi_timer = NULL;
1448 it->wd->multi_timeout = EINA_FALSE;
1450 if (it->wd->on_hold)
1452 if (it->wd->swipe) _swipe(data);
1453 it->wd->longpressed = EINA_FALSE;
1454 it->wd->on_hold = EINA_FALSE;
1457 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1459 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1461 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1463 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1464 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1466 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1467 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1471 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1472 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1474 it->wd->reorder_deleted = EINA_FALSE;
1475 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1476 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1477 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1478 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1480 if (it->wd->longpressed)
1482 it->wd->longpressed = EINA_FALSE;
1483 if ((!it->wd->wasselected) && (!it->flipped))
1485 _item_unhighlight(it);
1488 it->wd->wasselected = EINA_FALSE;
1493 if (it->want_unrealize)
1495 _elm_genlist_item_unrealize(it, EINA_FALSE);
1496 if (it->item->block->want_unrealize)
1497 _item_block_unrealize(it->item->block);
1500 if (elm_widget_item_disabled_get(it) || (dragged) ||
1501 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1503 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1508 _item_highlight(it);
1513 _item_unhighlight(it);
1521 Widget_Data *wd = it->wd;
1524 while (wd->selected)
1526 _item_unhighlight(wd->selected->data);
1527 _item_unselect(wd->selected->data);
1533 const Eina_List *l, *l_next;
1536 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1539 _item_unhighlight(it2);
1540 _item_unselect(it2);
1542 //_item_highlight(it);
1545 _item_highlight(it);
1551 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1553 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1555 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1557 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1559 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1561 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1563 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1568 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1570 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1572 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1574 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1576 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1578 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1580 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1586 _mouse_down_scroller(void *data,
1587 Evas *evas __UNUSED__,
1588 Evas_Object *obj __UNUSED__,
1589 void *event_info __UNUSED__)
1591 Widget_Data *wd = elm_widget_data_get(data);
1594 wd->drag_started = EINA_FALSE;
1598 _mouse_up_scroller(void *data,
1599 Evas *evas __UNUSED__,
1600 Evas_Object *obj __UNUSED__,
1601 void *event_info __UNUSED__)
1603 Widget_Data *wd = elm_widget_data_get(data);
1606 wd->drag_started = EINA_FALSE;
1610 _mouse_move_scroller(void *data,
1611 Evas *evas __UNUSED__,
1612 Evas_Object *obj __UNUSED__,
1615 Widget_Data *wd = elm_widget_data_get(data);
1616 Evas_Event_Mouse_Move *ev = event_info;
1617 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
1620 if (wd->drag_started) return;
1622 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1623 dx = ev->cur.canvas.x - ev->prev.canvas.x;
1624 dy = ev->cur.canvas.y - ev->prev.canvas.y;
1627 if (adx < 0) adx = -dx;
1628 if (ady < 0) ady = -dy;
1629 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
1633 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
1634 wd->drag_started = EINA_TRUE;
1638 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
1639 wd->drag_started = EINA_TRUE;
1645 _signal_expand_toggle(void *data,
1646 Evas_Object *obj __UNUSED__,
1647 const char *emission __UNUSED__,
1648 const char *source __UNUSED__)
1650 Elm_Gen_Item *it = data;
1652 if (it->item->expanded)
1653 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1655 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1659 _signal_expand(void *data,
1660 Evas_Object *obj __UNUSED__,
1661 const char *emission __UNUSED__,
1662 const char *source __UNUSED__)
1664 Elm_Gen_Item *it = data;
1666 if (!it->item->expanded)
1667 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1671 _signal_contract(void *data,
1672 Evas_Object *obj __UNUSED__,
1673 const char *emission __UNUSED__,
1674 const char *source __UNUSED__)
1676 Elm_Gen_Item *it = data;
1678 if (it->item->expanded)
1679 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1683 _scr_hold_timer_cb(void *data)
1685 if (!data) return ECORE_CALLBACK_CANCEL;
1686 Widget_Data *wd = data;
1687 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1688 wd->scr_hold_timer = NULL;
1689 return ECORE_CALLBACK_CANCEL;
1693 _decorate_item_finished_signal_cb(void *data,
1695 const char *emission __UNUSED__,
1696 const char *source __UNUSED__)
1700 Elm_Gen_Item *it = data;
1701 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1703 Evas *te = evas_object_evas_get(obj);
1705 evas_event_freeze(te);
1706 it->item->nocache_once = EINA_FALSE;
1707 _decorate_item_unrealize(it);
1708 //FIXME: group raise
1710 if (it->item->group_item)
1711 evas_object_raise(it->item->VIEW(group_item));
1713 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1714 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1715 evas_event_thaw(te);
1716 evas_event_thaw_eval(te);
1720 _item_cache_clean(Widget_Data *wd)
1722 evas_event_freeze(evas_object_evas_get(wd->obj));
1723 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1727 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1728 wd->item_cache = eina_inlist_remove(wd->item_cache,
1729 wd->item_cache->last);
1730 wd->item_cache_count--;
1731 if (itc->spacer) evas_object_del(itc->spacer);
1732 if (itc->base_view) evas_object_del(itc->base_view);
1733 eina_stringshare_del(itc->item_style);
1736 evas_event_thaw(evas_object_evas_get(wd->obj));
1737 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1741 _item_cache_zero(Widget_Data *wd)
1743 int pmax = wd->item_cache_max;
1744 wd->item_cache_max = 0;
1745 _item_cache_clean(wd);
1746 wd->item_cache_max = pmax;
1750 _item_cache_add(Elm_Gen_Item *it)
1754 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1755 if (it->wd->item_cache_max <= 0)
1757 evas_object_del(VIEW(it));
1761 evas_object_del(it->spacer);
1764 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1765 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1769 it->wd->item_cache_count++;
1770 itc = calloc(1, sizeof(Item_Cache));
1773 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1774 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1777 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1778 EINA_INLIST_GET(itc));
1779 itc->spacer = it->spacer;
1781 itc->base_view = VIEW(it);
1783 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1784 evas_object_hide(itc->base_view);
1785 evas_object_move(itc->base_view, -9999, -9999);
1786 itc->item_style = eina_stringshare_add(it->itc->item_style);
1787 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1788 itc->selected = it->selected;
1789 itc->disabled = elm_widget_item_disabled_get(it);
1790 itc->expanded = it->item->expanded;
1793 ecore_timer_del(it->long_timer);
1794 it->long_timer = NULL;
1796 if (it->item->swipe_timer)
1798 ecore_timer_del(it->item->swipe_timer);
1799 it->item->swipe_timer = NULL;
1801 // FIXME: other callbacks?
1802 edje_object_signal_callback_del_full(itc->base_view,
1803 "elm,action,expand,toggle",
1804 "elm", _signal_expand_toggle, it);
1805 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1807 _signal_expand, it);
1808 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1809 "elm", _signal_contract, it);
1810 _item_mouse_callbacks_del(it, itc->base_view);
1811 _item_cache_clean(it->wd);
1812 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1813 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1817 _item_cache_find(Elm_Gen_Item *it)
1822 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1823 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1825 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1827 if ((itc->tree == tree) &&
1828 (((!it->itc->item_style) && (!itc->item_style)) ||
1829 (it->itc->item_style && itc->item_style &&
1830 (!strcmp(it->itc->item_style, itc->item_style)))))
1832 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1833 EINA_INLIST_GET(itc));
1834 it->wd->item_cache_count--;
1842 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1844 if (it->position_update || it->item->block->position_update)
1846 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1847 it->position_update = EINA_FALSE;
1852 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1854 if (!it->item->nostacking)
1856 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1858 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1859 else evas_object_lower(VIEW(it));
1863 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1864 else evas_object_raise(VIEW(it));
1868 if (it->item->order_num_in & 0x1)
1870 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1871 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1875 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1876 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1881 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1885 if (it->selected != itc->selected)
1889 edje_object_signal_emit(VIEW(it),
1890 "elm,state,selected", "elm");
1891 if (it->deco_all_view)
1892 edje_object_signal_emit(it->deco_all_view,
1893 "elm,state,selected", "elm");
1896 if (elm_widget_item_disabled_get(it) != itc->disabled)
1898 if (elm_widget_item_disabled_get(it))
1899 edje_object_signal_emit(VIEW(it),
1900 "elm,state,disabled", "elm");
1901 if (it->deco_all_view)
1902 edje_object_signal_emit(it->deco_all_view,
1903 "elm,state,disabled", "elm");
1905 if (it->item->expanded != itc->expanded)
1907 if (it->item->expanded)
1908 edje_object_signal_emit(VIEW(it),
1909 "elm,state,expanded", "elm");
1910 if (it->deco_all_view)
1911 edje_object_signal_emit(it->deco_all_view,
1912 "elm,state,expanded", "elm");
1919 edje_object_signal_emit(VIEW(it),
1920 "elm,state,selected", "elm");
1921 if (it->deco_all_view)
1922 edje_object_signal_emit(it->deco_all_view,
1923 "elm,state,selected", "elm");
1925 if (elm_widget_item_disabled_get(it))
1927 edje_object_signal_emit(VIEW(it),
1928 "elm,state,disabled", "elm");
1929 if (it->deco_all_view)
1930 edje_object_signal_emit(it->deco_all_view,
1931 "elm,state,disabled", "elm");
1933 if (it->item->expanded)
1935 edje_object_signal_emit(VIEW(it),
1936 "elm,state,expanded", "elm");
1937 if (it->deco_all_view)
1938 edje_object_signal_emit(it->deco_all_view,
1939 "elm,state,expanded", "elm");
1945 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1947 Elm_Gen_Item *it = data;
1948 if (it) it->defer_unrealize = EINA_TRUE;
1952 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1954 Elm_Gen_Item *it = data;
1955 if (it) it->defer_unrealize = EINA_FALSE;
1960 _item_mode_content_realize(Elm_Gen_Item *it,
1961 Evas_Object *target,
1964 Eina_List **contents_list)
1966 Eina_List *res = *contents_list;
1968 if (it->itc->func.content_get)
1974 EINA_LIST_FOREACH(*source, l, key)
1976 if (parts && fnmatch(parts, key, FNM_PERIOD))
1979 ic = it->itc->func.content_get
1980 ((void *)it->base.data, WIDGET(it), key);
1984 res = eina_list_append(res, ic);
1985 edje_object_part_swallow(target, key, ic);
1986 evas_object_show(ic);
1987 elm_widget_sub_object_add(WIDGET(it), ic);
1990 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1991 // genlist does not need to handle this focus thing.
1992 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1993 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1995 if (elm_widget_item_disabled_get(it))
1996 elm_widget_disabled_set(ic, EINA_TRUE);
2005 _item_mode_content_unrealize(Elm_Gen_Item *it,
2006 Evas_Object *target,
2009 Eina_List **contents_list)
2011 Eina_List *res = *contents_list;
2013 if (it->itc->func.content_get)
2017 Evas_Object *ic = NULL;
2019 EINA_LIST_FOREACH(*source, l, key)
2021 if (parts && fnmatch(parts, key, FNM_PERIOD))
2024 ic = edje_object_part_swallow_get(target, key);
2027 res = eina_list_remove(res, ic);
2028 edje_object_part_unswallow(target, ic);
2029 evas_object_del(ic);
2038 _item_cache_free(Item_Cache *itc)
2040 if (itc->spacer) evas_object_del(itc->spacer);
2041 if (itc->base_view) evas_object_del(itc->base_view);
2042 eina_stringshare_del(itc->item_style);
2047 _item_text_realize(Elm_Gen_Item *it,
2048 Evas_Object *target,
2052 if (it->itc->func.text_get)
2058 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
2059 EINA_LIST_FOREACH(*source, l, key)
2061 if (parts && fnmatch(parts, key, FNM_PERIOD))
2064 char *s = it->itc->func.text_get
2065 ((void *)it->base.data, WIDGET(it), key);
2069 edje_object_part_text_escaped_set(target, key, s);
2074 edje_object_part_text_set(target, key, "");
2081 _item_content_unrealize(Elm_Gen_Item *it,
2082 Evas_Object *target,
2086 Eina_List *res = it->content_objs;
2088 if (it->itc->func.content_get)
2092 Evas_Object *ic = NULL;
2094 EINA_LIST_FOREACH(*source, l, key)
2096 if (parts && fnmatch(parts, key, FNM_PERIOD))
2099 ic = edje_object_part_swallow_get(target, key);
2102 res = eina_list_remove(res, ic);
2103 edje_object_part_unswallow(target, ic);
2104 evas_object_del(ic);
2113 _item_content_realize(Elm_Gen_Item *it,
2114 Evas_Object *target,
2118 Eina_List *res = it->content_objs;
2120 if (it->itc->func.content_get)
2124 Evas_Object *ic = NULL;
2127 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
2129 EINA_LIST_FOREACH(*source, l, key)
2131 if (parts && fnmatch(parts, key, FNM_PERIOD))
2134 if (it->itc->func.content_get)
2135 ic = it->itc->func.content_get
2136 ((void *)it->base.data, WIDGET(it), key);
2139 res = eina_list_append(res, ic);
2140 edje_object_part_swallow(target, key, ic);
2141 evas_object_show(ic);
2142 elm_widget_sub_object_add(WIDGET(it), ic);
2143 evas_object_event_callback_add(ic,
2144 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2145 _changed_size_hints, it);
2148 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2149 // genlist does not need to handle this focus thing.
2150 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2151 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2154 if (elm_widget_item_disabled_get(it))
2155 elm_widget_disabled_set(ic, EINA_TRUE);
2164 _item_state_realize(Elm_Gen_Item *it,
2165 Evas_Object *target,
2169 if (it->itc->func.state_get)
2176 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2177 EINA_LIST_FOREACH(*source, l, key)
2179 if (parts && fnmatch(parts, key, FNM_PERIOD))
2182 Eina_Bool on = it->itc->func.state_get
2183 ((void *)it->base.data, WIDGET(it), key);
2187 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2188 edje_object_signal_emit(target, buf, "elm");
2192 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2193 edje_object_signal_emit(target, buf, "elm");
2200 _item_order_update(const Eina_Inlist *l, int start)
2202 Elm_Gen_Item *it, *it2;
2204 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next, it = ELM_GEN_ITEM_FROM_INLIST(l))
2206 it->item->order_num_in = start++;
2207 _elm_genlist_item_odd_even_update(it);
2208 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
2209 if (it2 && (it->item->order_num_in != it2->item->order_num_in)) return;
2214 _item_realize(Elm_Gen_Item *it,
2218 const char *treesize;
2221 Item_Cache *itc = NULL;
2223 if (it->generation < it->wd->generation) return;
2224 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2227 if (it->item->order_num_in != in)
2229 _item_order_update(EINA_INLIST_GET(it), in);
2230 _elm_genlist_item_state_update(it, NULL);
2231 _elm_genlist_item_index_update(it);
2233 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2234 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2237 it->item->order_num_in = in;
2239 if ((it->item->nocache_once) && (!it->flipped))
2240 it->item->nocache_once = EINA_FALSE;
2241 else if (!it->item->nocache)
2242 itc = _item_cache_find(it);
2243 if (itc && (!it->wd->tree_effect_enabled))
2245 VIEW(it) = itc->base_view;
2246 itc->base_view = NULL;
2247 it->spacer = itc->spacer;
2252 const char *stacking_even;
2253 const char *stacking;
2255 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2256 edje_object_scale_set(VIEW(it),
2257 elm_widget_scale_get(WIDGET(it)) *
2258 _elm_config->scale);
2259 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2260 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2262 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2263 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2265 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2267 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2268 elm_widget_style_get(WIDGET(it)));
2270 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2271 if (!stacking_even) stacking_even = "above";
2272 it->item->stacking_even = !!strcmp("above", stacking_even);
2274 stacking = edje_object_data_get(VIEW(it), "stacking");
2275 if (!stacking) stacking = "yes";
2276 it->item->nostacking = !!strcmp("yes", stacking);
2278 edje_object_mirrored_set(VIEW(it),
2279 elm_widget_mirrored_get(WIDGET(it)));
2282 _item_order_update(EINA_INLIST_GET(it), in);
2284 treesize = edje_object_data_get(VIEW(it), "treesize");
2285 if (treesize) tsize = atoi(treesize);
2286 if (!it->spacer && treesize)
2289 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2290 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2291 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2295 evas_object_size_hint_min_set(it->spacer,
2296 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2297 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2301 edje_object_signal_callback_add(VIEW(it),
2302 "elm,action,expand,toggle",
2303 "elm", _signal_expand_toggle, it);
2304 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2305 "elm", _signal_expand, it);
2306 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2307 "elm", _signal_contract, it);
2308 _item_mouse_callbacks_add(it, VIEW(it));
2310 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2311 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2312 _decorate_all_item_realize(it, EINA_FALSE);
2314 _elm_genlist_item_state_update(it, itc);
2315 _elm_genlist_item_index_update(it);
2318 if ((calc) && (it->wd->homogeneous) &&
2319 ((it->wd->item_width) ||
2320 ((it->wd->item_width) && (it->wd->group_item_width))))
2322 /* homogenous genlist shortcut */
2323 if (!it->item->mincalcd)
2327 it->item->w = it->item->minw = it->wd->group_item_width;
2328 it->item->h = it->item->minh = it->wd->group_item_height;
2332 it->item->w = it->item->minw = it->wd->item_width;
2333 it->item->h = it->item->minh = it->wd->item_height;
2335 it->item->mincalcd = EINA_TRUE;
2340 /* FIXME: If you see that assert, please notify us and we
2341 will clean our mess */
2342 assert(eina_list_count(it->content_objs) == 0);
2344 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2345 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2346 _item_state_realize(it, VIEW(it), &it->states, NULL);
2349 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2350 if (!(it->item->flip_contents))
2351 it->item->flip_contents =
2352 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2353 it->item->flip_content_objs =
2354 _item_mode_content_realize(it, VIEW(it),
2355 &it->item->flip_contents, NULL,
2356 &it->item->flip_content_objs);
2359 if (!it->item->mincalcd || ((it->wd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
2361 Evas_Coord mw = -1, mh = -1;
2363 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2364 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2365 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2366 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2368 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2369 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2370 it->item->w = it->item->minw = mw;
2371 it->item->h = it->item->minh = mh;
2372 it->item->mincalcd = EINA_TRUE;
2374 if ((!it->wd->group_item_width) && (it->group))
2376 it->wd->group_item_width = mw;
2377 it->wd->group_item_height = mh;
2379 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2381 it->wd->item_width = mw;
2382 it->wd->item_height = mh;
2385 if (!calc) evas_object_show(VIEW(it));
2388 if (it->tooltip.content_cb)
2390 elm_widget_item_tooltip_content_cb_set(it,
2391 it->tooltip.content_cb,
2392 it->tooltip.data, NULL);
2393 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2394 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2397 if (it->mouse_cursor)
2398 elm_widget_item_cursor_set(it, it->mouse_cursor);
2400 it->realized = EINA_TRUE;
2401 it->want_unrealize = EINA_FALSE;
2403 if (itc) _item_cache_free(itc);
2404 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2405 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2408 if (it->item->tree_effect_hideme)
2410 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2411 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2412 it->item->tree_effect_hideme = EINA_FALSE;
2414 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2417 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2419 if (it->itc->decorate_all_item_style)
2421 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2422 edje_object_message_signal_process(it->deco_all_view);
2425 edje_object_message_signal_process(VIEW(it));
2429 _item_unrealize_cb(Elm_Gen_Item *it)
2431 Evas_Object *content;
2432 elm_widget_stringlist_free(it->item->flip_contents);
2433 it->item->flip_contents = NULL;
2434 EINA_LIST_FREE(it->item->flip_content_objs, content)
2435 evas_object_del(content);
2437 if (it->item->nocache_once || it->item->nocache)
2439 evas_object_del(VIEW(it));
2443 evas_object_del(it->spacer);
2449 edje_object_mirrored_set(VIEW(it),
2450 elm_widget_mirrored_get(WIDGET(it)));
2451 edje_object_scale_set(VIEW(it),
2452 elm_widget_scale_get(WIDGET(it))
2453 * _elm_config->scale);
2454 _item_cache_add(it);
2457 _decorate_item_unrealize(it);
2459 it->realized = EINA_FALSE;
2460 it->want_unrealize = EINA_FALSE;
2461 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2465 _item_block_recalc(Item_Block *itb,
2471 Evas_Coord minw = 0, minh = 0;
2472 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2475 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2477 EINA_LIST_FOREACH(itb->items, l, it)
2479 if (it->generation < it->wd->generation) continue;
2480 showme |= it->item->showme;
2485 if (!it->item->mincalcd) changed = EINA_TRUE;
2488 _item_realize(it, in, EINA_TRUE);
2489 _elm_genlist_item_unrealize(it, EINA_TRUE);
2494 if ((itb->wd->homogeneous) &&
2495 (itb->wd->mode == ELM_LIST_COMPRESS))
2499 it->item->w = it->item->minw = it->wd->group_item_width;
2500 it->item->h = it->item->minh = it->wd->group_item_height;
2504 it->item->w = it->item->minw = it->wd->item_width;
2505 it->item->h = it->item->minh = it->wd->item_height;
2510 _item_realize(it, in, EINA_TRUE);
2511 _elm_genlist_item_unrealize(it, EINA_TRUE);
2517 if (!it->item->mincalcd) changed = EINA_TRUE;
2518 _item_realize(it, in, EINA_FALSE);
2520 minh += it->item->minh;
2521 if (minw < it->item->minw) minw = it->item->minw;
2527 if (changed) itb->wd->pan_changed = changed;
2530 itb->changed = EINA_FALSE;
2531 itb->position_update = EINA_FALSE;
2532 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2533 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2538 _item_block_realize(Item_Block *itb)
2540 if (itb->realized) return;
2541 itb->realized = EINA_TRUE;
2542 itb->want_unrealize = EINA_FALSE;
2546 _item_block_unrealize(Item_Block *itb)
2550 Eina_Bool dragging = EINA_FALSE;
2552 if (!itb->realized) return;
2553 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2554 EINA_LIST_FOREACH(itb->items, l, it)
2556 if (itb->must_recalc || !it->group)
2560 dragging = EINA_TRUE;
2561 it->want_unrealize = EINA_TRUE;
2564 _elm_genlist_item_unrealize(it, EINA_FALSE);
2569 itb->realized = EINA_FALSE;
2570 itb->want_unrealize = EINA_TRUE;
2573 itb->want_unrealize = EINA_FALSE;
2574 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2575 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2579 _get_space_for_reorder_item(Elm_Gen_Item *it)
2581 Evas_Coord rox, roy, row, roh, oy, oh;
2582 Eina_Bool top = EINA_FALSE;
2583 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2584 if (!reorder_it) return 0;
2586 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2587 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2589 if ((it->wd->reorder_start_y < it->item->block->y) &&
2590 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2592 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2593 if (it->item->block->count == 1)
2594 it->wd->reorder_rel = it;
2596 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2597 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2599 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2602 it->item->block->reorder_offset = 0;
2604 it->item->scrl_y += it->item->block->reorder_offset;
2606 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2607 rox, roy + (roh / 2), row, 1));
2610 it->wd->reorder_rel = it;
2611 it->item->scrl_y += it->wd->reorder_it->item->h;
2612 return it->wd->reorder_it->item->h;
2619 _reorder_move_animator_cb(void *data)
2621 Elm_Gen_Item *it = data;
2622 Eina_Bool down = EINA_FALSE;
2624 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2626 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2628 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2631 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2632 if (diff > it->item->h) y = diff / 2;
2634 if (it->item->old_scrl_y < it->item->scrl_y)
2636 it->item->old_scrl_y += y;
2639 else if (it->item->old_scrl_y > it->item->scrl_y)
2641 it->item->old_scrl_y -= y;
2645 if (it->deco_all_view)
2646 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2648 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2649 //FIXME : group raise
2651 _group_items_recalc(it->wd);
2654 if ((it->wd->reorder_pan_move) ||
2655 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2656 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2658 it->item->old_scrl_y = it->item->scrl_y;
2659 it->item->move_effect_enabled = EINA_FALSE;
2660 it->wd->reorder_move_animator = NULL;
2661 return ECORE_CALLBACK_CANCEL;
2663 return ECORE_CALLBACK_RENEW;
2667 _item_position(Elm_Gen_Item *it,
2675 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2676 evas_object_resize(view, it->item->w, it->item->h);
2677 evas_object_move(view, it_x, it_y);
2678 evas_object_show(view);
2679 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2680 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2684 _item_block_position(Item_Block *itb,
2689 //FIXME : group raise
2693 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2694 Eina_Bool vis = EINA_FALSE;
2695 Evas_Coord minh = 0;
2697 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2698 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2699 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2701 EINA_LIST_FOREACH(itb->items, l, it)
2703 if (it->generation < it->wd->generation) continue;
2704 else if (it->wd->reorder_it == it) continue;
2707 it->item->w = itb->w;
2708 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2709 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2711 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2712 cvx, cvy, cvw, cvh));
2713 //FIXME : group raise
2718 if ((itb->realized) && (!it->realized))
2720 if (vis) _item_realize(it, in, EINA_FALSE);
2724 if (vis || it->dragging)
2726 if (it->wd->reorder_mode)
2727 y += _get_space_for_reorder_item(it);
2728 //FIXME : group raise
2730 git = it->item->group_item;
2733 if (git->item->scrl_y < oy)
2734 git->item->scrl_y = oy;
2735 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2736 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2737 git->item->want_realize = EINA_TRUE;
2740 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2742 if (!it->item->move_effect_enabled)
2744 it->item->move_effect_enabled = EINA_TRUE;
2745 it->wd->reorder_move_animator =
2747 _reorder_move_animator_cb, it);
2750 if (!it->item->move_effect_enabled)
2752 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2753 _decorate_all_item_position(it, it->item->scrl_x,
2757 if (!it->wd->tree_effect_enabled ||
2758 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2759 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2760 (it->item->old_scrl_y == it->item->scrl_y)))
2762 if (it->item->deco_it_view)
2763 _item_position(it, it->item->deco_it_view,
2767 _item_position(it, VIEW(it), it->item->scrl_x,
2771 it->item->old_scrl_y = it->item->scrl_y;
2776 if (!it->wd->tree_effect_animator)
2778 it->want_unrealize = EINA_TRUE;
2779 _elm_genlist_item_unrealize(it, EINA_FALSE);
2785 //FIXME : group raise
2789 if (vis) it->item->want_realize = EINA_TRUE;
2793 minh += it->item->minh;
2795 if (!itb->wd->reorder_it) itb->minh = minh;
2796 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2797 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2800 //FIXME: group raise
2803 _group_items_recalc(void *data)
2805 Widget_Data *wd = data;
2809 evas_event_freeze(evas_object_evas_get(wd->obj));
2810 EINA_LIST_FOREACH(wd->group_items, l, git)
2812 if (git->item->want_realize)
2815 _item_realize(git, 0, EINA_FALSE);
2816 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2817 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2818 evas_object_show(VIEW(git));
2819 evas_object_raise(VIEW(git));
2821 else if (!git->item->want_realize && git->realized)
2824 _elm_genlist_item_unrealize(git, EINA_FALSE);
2827 evas_event_thaw(evas_object_evas_get(wd->obj));
2828 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2833 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2835 Elm_Gen_Item *it = data;
2837 if (it->want_unrealize) return;
2838 it->item->mincalcd = EINA_FALSE;
2839 it->item->block->changeme = EINA_TRUE;
2840 if (it->wd->changed_job) ecore_job_del(it->wd->changed_job);
2841 it->wd->changed_job = ecore_job_add(_changed_job, it->wd);
2845 _must_recalc_idler(void *data)
2847 Widget_Data *wd = data;
2848 if (wd->calc_job) ecore_job_del(wd->calc_job);
2849 wd->calc_job = ecore_job_add(_calc_job, wd);
2850 wd->must_recalc_idler = NULL;
2851 return ECORE_CALLBACK_CANCEL;
2855 _scroll_item(Widget_Data *wd)
2857 Elm_Gen_Item *it = NULL;
2858 //FIXME: group raise
2860 Evas_Coord gith = 0;
2862 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2863 if (!wd->show_item) return;
2865 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2867 dx = it->x + it->item->block->x;
2868 dy = it->y + it->item->block->y;
2869 dw = it->item->block->w;
2871 switch (wd->scrollto_type)
2873 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2874 //FIXME: group raise
2876 if (it->item->group_item) gith = it->item->group_item->item->h;
2880 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2881 dy += ((it->item->h / 2) - (oh / 2));
2883 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2885 if ((wd->expanded_item) &&
2886 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2887 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2889 it = wd->expanded_item;
2890 dx = it->x + it->item->block->x;
2891 dy = it->y + it->item->block->y;
2892 //FIXME: group raise
2894 if (it->item->group_item) gith = it->item->group_item->item->h;
2895 dx = it->x + it->item->block->x;
2896 dy = it->y + it->item->block->y - gith;
2898 dw = it->item->block->w;
2902 //FIXME: group raise
2904 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2905 gith = it->item->group_item->item->h;
2913 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2915 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2917 it->item->showme = EINA_FALSE;
2918 wd->show_item = NULL;
2919 wd->auto_scroll_enabled = EINA_FALSE;
2920 wd->check_scroll = EINA_FALSE;
2924 _calc_job(void *data)
2926 Widget_Data *wd = data;
2927 Item_Block *itb, *chb = NULL;
2928 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2929 Evas_Coord pan_w = 0, pan_h = 0;
2931 Eina_Bool minw_change = EINA_FALSE;
2932 Eina_Bool did_must_recalc = EINA_FALSE;
2935 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2936 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2941 evas_event_freeze(evas_object_evas_get(wd->obj));
2942 EINA_INLIST_FOREACH(wd->blocks, itb)
2944 Eina_Bool showme = EINA_FALSE;
2947 showme = itb->showme;
2948 itb->showme = EINA_FALSE;
2951 if (itb->realized) _item_block_unrealize(itb);
2953 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2955 if (itb->must_recalc)
2959 EINA_LIST_FOREACH(itb->items, l, it)
2960 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2961 itb->changed = EINA_TRUE;
2962 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2963 if (itb->realized) _item_block_unrealize(itb);
2964 itb->must_recalc = EINA_FALSE;
2966 showme = _item_block_recalc(itb, in, EINA_FALSE);
2972 if (minw == -1) minw = itb->minw;
2973 else if ((!itb->must_recalc) && (minw < itb->minw))
2976 minw_change = EINA_TRUE;
2981 minw_change = EINA_TRUE;
2987 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2988 wd->check_scroll = EINA_TRUE;
2992 EINA_INLIST_FOREACH(wd->blocks, itb)
2998 if ((chb) && (EINA_INLIST_GET(chb)->next))
3000 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
3002 if (itb->realized) _item_block_unrealize(itb);
3005 wd->realminw = minw;
3006 if (minw < wd->w) minw = wd->w;
3007 if ((minw != wd->minw) || (minh != wd->minh))
3011 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3012 _sizing_eval(wd->obj);
3013 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
3018 it = wd->anchor_item;
3019 it_y = wd->anchor_y;
3020 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
3021 it->item->block->y + it->y + it_y);
3022 wd->anchor_item = it;
3023 wd->anchor_y = it_y;
3026 if (did_must_recalc)
3028 if (!wd->must_recalc_idler)
3029 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
3031 if (wd->check_scroll)
3033 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
3034 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
3035 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3036 switch (wd->scrollto_type)
3038 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
3041 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
3044 case ELM_GENLIST_ITEM_SCROLLTO_IN:
3049 if ((wd->show_item) && (wd->show_item->item->block))
3051 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
3052 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
3058 wd->calc_job = NULL;
3059 evas_object_smart_changed(wd->pan_smart);
3060 evas_event_thaw(evas_object_evas_get(wd->obj));
3061 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3065 _update_job(void *data)
3067 Widget_Data *wd = data;
3071 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
3073 wd->update_job = NULL;
3076 evas_event_freeze(evas_object_evas_get(wd->obj));
3077 EINA_INLIST_FOREACH(wd->blocks, itb)
3079 Evas_Coord itminw, itminh;
3086 _item_block_position(itb, num);
3090 recalc = EINA_FALSE;
3091 EINA_LIST_FOREACH(itb->items, l2, it)
3093 if (it->item->updateme)
3095 itminw = it->item->minw;
3096 itminh = it->item->minh;
3100 _elm_genlist_item_unrealize(it, EINA_FALSE);
3101 _item_realize(it, num, EINA_FALSE);
3102 position = EINA_TRUE;
3106 _item_realize(it, num, EINA_TRUE);
3107 _elm_genlist_item_unrealize(it, EINA_TRUE);
3109 if ((it->item->minw != itminw) || (it->item->minh != itminh))
3111 it->item->updateme = EINA_FALSE;
3115 itb->updateme = EINA_FALSE;
3118 position = EINA_TRUE;
3119 itb->changed = EINA_TRUE;
3120 _item_block_recalc(itb, num0, EINA_FALSE);
3121 _item_block_position(itb, num0);
3126 if (wd->calc_job) ecore_job_del(wd->calc_job);
3127 wd->calc_job = ecore_job_add(_calc_job, wd);
3129 evas_event_thaw(evas_object_evas_get(wd->obj));
3130 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3134 _changed_job(void *data)
3136 Widget_Data *wd = data; Eina_List *l2;
3138 int num, num0, position = 0;
3139 Eina_Bool width_changed = EINA_FALSE, height_changed = EINA_FALSE;
3141 wd->changed_job = NULL;
3143 EINA_INLIST_FOREACH(wd->blocks, itb)
3145 Evas_Coord itminw, itminh;
3152 _item_block_position(itb, num);
3156 width_changed = height_changed = EINA_FALSE;
3157 EINA_LIST_FOREACH(itb->items, l2, it)
3159 if ((!it->item->mincalcd) && (it->realized))
3161 Evas_Coord mw = -1, mh = -1;
3162 itminw = it->item->minw;
3163 itminh = it->item->minh;
3165 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->w;
3166 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3167 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3168 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
3169 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
3170 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3171 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3173 width_changed = EINA_TRUE;
3176 it->item->w = it->item->minw = mw;
3177 it->item->h = it->item->minh = mh;
3178 it->item->mincalcd = EINA_TRUE;
3180 //if ((it->item->minw != itminw) || (it->item->minh != itminh))
3181 //if ((it->item->minh != itminh))
3183 if ((it->item->minw != itminw))
3184 width_changed = EINA_TRUE;
3185 if ((it->item->minh != itminh))
3186 height_changed = EINA_TRUE;
3188 if ((!it->wd->group_item_width) && (it->group))
3190 it->wd->group_item_width = mw;
3191 it->wd->group_item_height = mh;
3193 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
3195 it->wd->item_width = mw;
3196 it->wd->item_height = mh;
3201 itb->changeme = EINA_FALSE;
3202 // TODO: why this is separated.
3206 itb->changed = EINA_TRUE;
3207 _item_block_recalc(itb, num0, 0);
3208 _item_block_position(itb, num0);
3210 else if (width_changed)
3212 _item_block_position(itb, num0);
3217 if (wd->calc_job) ecore_job_del(wd->calc_job);
3218 wd->calc_job = ecore_job_add(_calc_job, wd);
3223 _pan_set(Evas_Object *obj,
3227 Pan *sd = evas_object_smart_data_get(obj);
3231 // Evas_Coord ow, oh;
3232 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3233 // ow = sd->wd->minw - ow;
3234 // if (ow < 0) ow = 0;
3235 // oh = sd->wd->minh - oh;
3236 // if (oh < 0) oh = 0;
3237 // if (x < 0) x = 0;
3238 // if (y < 0) y = 0;
3239 // if (x > ow) x = ow;
3240 // if (y > oh) y = oh;
3241 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
3245 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3247 if ((itb->y + itb->h) > y)
3252 EINA_LIST_FOREACH(itb->items, l2, it)
3254 if ((itb->y + it->y) >= y)
3256 sd->wd->anchor_item = it;
3257 sd->wd->anchor_y = -(itb->y + it->y - y);
3264 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
3268 _pan_get(Evas_Object *obj,
3272 Pan *sd = evas_object_smart_data_get(obj);
3275 if (x) *x = sd->wd->pan_x;
3276 if (y) *y = sd->wd->pan_y;
3280 _pan_max_get(Evas_Object *obj,
3284 Pan *sd = evas_object_smart_data_get(obj);
3288 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3289 ow = sd->wd->minw - ow;
3291 oh = sd->wd->minh - oh;
3298 _pan_min_get(Evas_Object *obj __UNUSED__,
3307 _pan_child_size_get(Evas_Object *obj,
3311 Pan *sd = evas_object_smart_data_get(obj);
3314 if (w) *w = sd->wd->minw;
3315 if (h) *h = sd->wd->minh;
3319 _pan_add(Evas_Object *obj)
3322 Evas_Object_Smart_Clipped_Data *cd;
3325 cd = evas_object_smart_data_get(obj);
3328 sd->__clipped_data = *cd;
3330 evas_object_smart_data_set(obj, sd);
3334 _pan_del(Evas_Object *obj)
3336 Pan *sd = evas_object_smart_data_get(obj);
3341 ecore_job_del(sd->resize_job);
3342 sd->resize_job = NULL;
3348 _pan_resize_job(void *data)
3352 _sizing_eval(sd->wd->obj);
3353 sd->resize_job = NULL;
3357 _pan_resize(Evas_Object *obj,
3361 Pan *sd = evas_object_smart_data_get(obj);
3365 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3366 if ((ow == w) && (oh == h)) return;
3367 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3370 if (sd->resize_job) ecore_job_del(sd->resize_job);
3371 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3373 sd->wd->pan_changed = EINA_TRUE;
3374 evas_object_smart_changed(obj);
3375 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3376 sd->wd->calc_job = NULL;
3380 _pan_calculate(Evas_Object *obj)
3382 Pan *sd = evas_object_smart_data_get(obj);
3384 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3386 //FIXME: group raise
3393 evas_event_freeze(evas_object_evas_get(obj));
3395 if (sd->wd->pan_changed)
3398 sd->wd->pan_changed = EINA_FALSE;
3401 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3402 sd->wd->prev_viewport_w = ow;
3403 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3404 //FIXME: group raise
3406 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3408 git->item->want_realize = EINA_FALSE;
3412 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3414 if (!sd->wd->tree_effect_animator)
3416 _item_tree_effect_before(sd->wd->expanded_item);
3417 evas_object_raise(sd->wd->alpha_bg);
3418 evas_object_show(sd->wd->alpha_bg);
3419 sd->wd->start_time = ecore_time_get();
3420 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3424 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3426 itb->w = sd->wd->minw;
3427 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3428 itb->y - sd->wd->pan_y + oy,
3430 cvx, cvy, cvw, cvh))
3432 if ((!itb->realized) || (itb->changed))
3434 _item_block_realize(itb);
3436 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3437 sd->wd->calc_job = NULL;
3440 _item_block_position(itb, in);
3444 if (itb->realized) _item_block_unrealize(itb);
3448 //FIXME: group raise
3450 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3451 _group_items_recalc(sd->wd);
3453 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3455 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3456 sd->wd->reorder_pan_move = EINA_TRUE;
3457 else sd->wd->reorder_pan_move = EINA_FALSE;
3458 evas_object_raise(sd->wd->VIEW(reorder_it));
3459 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3460 sd->wd->start_time = ecore_loop_time_get();
3463 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3464 _item_auto_scroll(sd->wd);
3466 evas_event_thaw(evas_object_evas_get(obj));
3467 evas_event_thaw_eval(evas_object_evas_get(obj));
3471 _pan_move(Evas_Object *obj,
3472 Evas_Coord x __UNUSED__,
3473 Evas_Coord y __UNUSED__)
3475 Pan *sd = evas_object_smart_data_get(obj);
3479 sd->wd->pan_changed = EINA_TRUE;
3480 evas_object_smart_changed(obj);
3481 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3482 sd->wd->calc_job = NULL;
3486 _hold_on(void *data __UNUSED__,
3488 void *event_info __UNUSED__)
3490 Widget_Data *wd = elm_widget_data_get(obj);
3492 elm_smart_scroller_hold_set(wd->scr, 1);
3496 _hold_off(void *data __UNUSED__,
3498 void *event_info __UNUSED__)
3500 Widget_Data *wd = elm_widget_data_get(obj);
3502 elm_smart_scroller_hold_set(wd->scr, 0);
3506 _freeze_on(void *data __UNUSED__,
3508 void *event_info __UNUSED__)
3510 Widget_Data *wd = elm_widget_data_get(obj);
3512 elm_smart_scroller_freeze_set(wd->scr, 1);
3516 _freeze_off(void *data __UNUSED__,
3518 void *event_info __UNUSED__)
3520 Widget_Data *wd = elm_widget_data_get(obj);
3522 elm_smart_scroller_freeze_set(wd->scr, 0);
3526 _scr_anim_start(void *data,
3527 Evas_Object *obj __UNUSED__,
3528 void *event_info __UNUSED__)
3530 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3534 _scr_anim_stop(void *data,
3535 Evas_Object *obj __UNUSED__,
3536 void *event_info __UNUSED__)
3538 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3542 _scr_drag_start(void *data,
3543 Evas_Object *obj __UNUSED__,
3544 void *event_info __UNUSED__)
3546 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3550 _scr_drag_stop(void *data,
3551 Evas_Object *obj __UNUSED__,
3552 void *event_info __UNUSED__)
3554 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3558 _edge_left(void *data,
3559 Evas_Object *scr __UNUSED__,
3560 void *event_info __UNUSED__)
3562 Evas_Object *obj = data;
3563 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3567 _edge_right(void *data,
3568 Evas_Object *scr __UNUSED__,
3569 void *event_info __UNUSED__)
3571 Evas_Object *obj = data;
3572 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3576 _edge_top(void *data,
3577 Evas_Object *scr __UNUSED__,
3578 void *event_info __UNUSED__)
3580 Evas_Object *obj = data;
3581 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3585 _edge_bottom(void *data,
3586 Evas_Object *scr __UNUSED__,
3587 void *event_info __UNUSED__)
3589 Evas_Object *obj = data;
3590 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3594 _decorate_item_realize(Elm_Gen_Item *it)
3598 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3600 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3601 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3602 edje_object_scale_set(it->item->deco_it_view,
3603 elm_widget_scale_get(WIDGET(it)) *
3604 _elm_config->scale);
3605 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3606 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3608 strncpy(buf, "item", sizeof(buf));
3609 if (it->wd->mode == ELM_LIST_COMPRESS)
3610 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3612 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3613 strncat(buf, "/", sizeof(buf) - strlen(buf));
3614 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3616 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3617 elm_widget_style_get(WIDGET(it)));
3618 edje_object_mirrored_set(it->item->deco_it_view,
3619 elm_widget_mirrored_get(WIDGET(it)));
3621 /* signal callback add */
3622 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3624 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3626 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3629 /* text_get, content_get, state_get */
3630 /* FIXME: If you see that assert, please notify us and we
3631 will clean our mess */
3632 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3634 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3635 if (!it->item->deco_it_contents)
3636 it->item->deco_it_contents =
3637 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3638 it->item->deco_it_content_objs =
3639 _item_mode_content_realize(it, it->item->deco_it_view,
3640 &it->item->deco_it_contents, NULL,
3641 &it->item->deco_it_content_objs);
3642 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3643 edje_object_part_swallow(it->item->deco_it_view,
3644 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3647 it->want_unrealize = EINA_FALSE;
3648 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3649 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3653 _decorate_item_unrealize(Elm_Gen_Item *it)
3655 Widget_Data *wd = it->wd;
3656 Evas_Object *content;
3657 if (!it->item->deco_it_view) return;
3659 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3660 elm_widget_stringlist_free(it->item->deco_it_texts);
3661 it->item->deco_it_texts = NULL;
3662 elm_widget_stringlist_free(it->item->deco_it_contents);
3663 it->item->deco_it_contents = NULL;
3664 elm_widget_stringlist_free(it->item->deco_it_states);
3666 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3667 evas_object_del(content);
3669 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3670 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3671 evas_object_del(it->item->deco_it_view);
3672 it->item->deco_it_view = NULL;
3674 if (wd->mode_item == it)
3675 wd->mode_item = NULL;
3676 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3677 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3681 _decorate_item_set(Elm_Gen_Item *it)
3684 Widget_Data *wd = it->wd;
3689 it->item->nocache_once = EINA_TRUE;
3691 if (wd->scr_hold_timer)
3693 ecore_timer_del(wd->scr_hold_timer);
3694 wd->scr_hold_timer = NULL;
3696 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3697 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3699 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3700 _decorate_item_realize(it);
3701 if (it->item->group_item)
3702 evas_object_raise(it->item->VIEW(group_item));
3703 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3704 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3705 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3707 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3708 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3712 _decorate_item_unset(Widget_Data *wd)
3715 if (!wd->mode_item) return;
3716 char buf[1024], buf2[1024];
3720 it->item->nocache_once = EINA_TRUE;
3722 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3723 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3725 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3726 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3728 wd->mode_item = NULL;
3732 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3734 if ((!it) || (!it->wd->decorate_all_mode)) return;
3735 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3736 evas_object_move(it->deco_all_view, itx, ity);
3740 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3743 const char *stacking_even;
3744 const char *stacking;
3746 if ((!it) || (it->item->decorate_all_item_realized) ||
3747 (it->generation < it->wd->generation))
3750 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3751 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3752 _elm_config->scale);
3753 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3754 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3756 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3757 strncpy(buf, "tree", sizeof(buf));
3758 else strncpy(buf, "item", sizeof(buf));
3759 if (it->wd->mode == ELM_LIST_COMPRESS)
3760 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3762 strncat(buf, "/", sizeof(buf) - strlen(buf));
3763 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3765 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3766 elm_widget_style_get(WIDGET(it)));
3768 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3769 if (!stacking_even) stacking_even = "above";
3770 it->item->stacking_even = !!strcmp("above", stacking_even);
3772 stacking = edje_object_data_get(VIEW(it), "stacking");
3773 if (!stacking) stacking = "yes";
3774 it->item->nostacking = !!strcmp("yes", stacking);
3776 edje_object_mirrored_set(it->deco_all_view,
3777 elm_widget_mirrored_get(WIDGET(it)));
3779 _elm_genlist_item_odd_even_update(it);
3780 _elm_genlist_item_state_update(it, NULL);
3782 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3783 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3785 _item_mouse_callbacks_del(it, VIEW(it));
3786 _item_mouse_callbacks_add(it, it->deco_all_view);
3788 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3789 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3790 if (!it->item->deco_all_contents)
3791 it->item->deco_all_contents =
3792 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "decorate_contents"));
3793 it->item->deco_all_content_objs =
3794 _item_mode_content_realize(it, it->deco_all_view,
3795 &it->item->deco_all_contents, NULL,
3796 &it->item->deco_all_content_objs);
3797 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3798 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3800 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3801 evas_object_show(it->deco_all_view);
3803 if (it->selected) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
3805 it->item->decorate_all_item_realized = EINA_TRUE;
3806 it->want_unrealize = EINA_FALSE;
3810 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3813 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3815 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3816 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3817 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3818 _elm_genlist_item_odd_even_update(it);
3819 _elm_genlist_item_state_update(it, NULL);
3821 evas_object_del(it->deco_all_view);
3822 it->deco_all_view = NULL;
3823 elm_widget_stringlist_free(it->item->deco_all_texts);
3824 it->item->deco_all_texts = NULL;
3825 elm_widget_stringlist_free(it->item->deco_all_contents);
3826 it->item->deco_all_contents = NULL;
3827 elm_widget_stringlist_free(it->item->deco_all_states);
3828 it->item->deco_all_states = NULL;
3829 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3830 evas_object_del(icon);
3831 edje_object_message_signal_process(it->deco_all_view);
3832 _item_mouse_callbacks_del(it, it->deco_all_view);
3833 _item_mouse_callbacks_add(it, VIEW(it));
3835 it->item->decorate_all_item_realized = EINA_FALSE;
3839 _item_auto_scroll(Widget_Data *wd)
3842 Elm_Gen_Item *tmp_item = NULL;
3844 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3846 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3847 if (!tmp_item) return;
3848 wd->show_item = tmp_item;
3849 wd->bring_in = EINA_TRUE;
3850 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3851 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3853 wd->show_item->item->showme = EINA_TRUE;
3854 wd->auto_scroll_enabled = EINA_FALSE;
3862 elm_genlist_add(Evas_Object *parent)
3867 Evas_Coord minw, minh;
3868 static Evas_Smart *smart = NULL;
3872 static Evas_Smart_Class sc;
3874 evas_object_smart_clipped_smart_set(&_pan_sc);
3876 sc.name = "elm_genlist_pan";
3877 sc.version = EVAS_SMART_CLASS_VERSION;
3880 sc.resize = _pan_resize;
3881 sc.move = _pan_move;
3882 sc.calculate = _pan_calculate;
3883 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3886 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3888 ELM_SET_WIDTYPE(widtype, "genlist");
3890 elm_widget_type_set(obj, "genlist");
3891 elm_widget_sub_object_add(parent, obj);
3892 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3893 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3894 elm_widget_data_set(obj, wd);
3895 elm_widget_del_hook_set(obj, _del_hook);
3896 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3897 elm_widget_theme_hook_set(obj, _theme_hook);
3898 elm_widget_can_focus_set(obj, EINA_TRUE);
3899 elm_widget_event_hook_set(obj, _event_hook);
3900 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3901 elm_widget_translate_hook_set(obj, _translate_hook);
3904 wd->scr = elm_smart_scroller_add(e);
3905 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_DOWN,
3906 _mouse_down_scroller, obj);
3907 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_UP,
3908 _mouse_up_scroller, obj);
3909 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_MOVE,
3910 _mouse_move_scroller, obj);
3911 elm_smart_scroller_widget_set(wd->scr, obj);
3912 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3913 elm_widget_style_get(obj));
3914 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3915 _elm_config->thumbscroll_bounce_enable);
3916 elm_widget_resize_object_set(obj, wd->scr);
3918 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3919 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3920 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3921 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3922 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3923 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3924 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3925 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3928 wd->mode = ELM_LIST_SCROLL;
3929 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3930 wd->item_cache_max = wd->max_items_per_block * 2;
3931 wd->longpress_timeout = _elm_config->longpress_timeout;
3932 wd->highlight = EINA_TRUE;
3933 wd->tree_effect_enabled = _elm_config->effect_enable;
3935 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3936 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3937 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3938 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3940 wd->pan_smart = evas_object_smart_add(e, smart);
3941 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3944 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3945 _pan_set, _pan_get, _pan_max_get,
3946 _pan_min_get, _pan_child_size_get);
3948 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3950 evas_object_size_hint_min_set(obj, minw, minh);
3952 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3954 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3960 _item_select(Elm_Gen_Item *it)
3963 Evas_Object *obj = WIDGET(it);
3964 Evas_Object *item_obj;
3966 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3967 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3968 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3972 it->selected = EINA_TRUE;
3973 it->wd->selected = eina_list_append(it->wd->selected, it);
3975 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3977 evas_object_ref(obj);
3980 if (it->wd->last_selected_item &&
3981 (it != (Elm_Gen_Item *) it->wd->last_selected_item))
3983 Elm_Gen_Item *_lsit = (Elm_Gen_Item *)it->wd->last_selected_item;
3985 EINA_LIST_FOREACH(_lsit->content_objs, l, item_obj)
3987 elm_widget_focused_object_clear(item_obj);
3988 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3990 if (elm_widget_type_get(obj) == _genlist)
3992 EINA_LIST_FOREACH(_lsit->item->flip_content_objs, l, item_obj)
3994 elm_widget_focused_object_clear(item_obj);
3995 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3997 EINA_LIST_FOREACH(_lsit->item->deco_all_content_objs, l, item_obj)
3999 elm_widget_focused_object_clear(item_obj);
4000 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
4003 _lsit->can_focus = EINA_FALSE;
4005 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
4006 if (it->generation == it->wd->generation)
4007 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
4010 if ((it->wd->clear_me) && (!it->wd->walking))
4011 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
4014 if ((!it->walking) && (it->generation < it->wd->generation))
4019 elm_widget_item_free(it);
4023 it->wd->last_selected_item = (Elm_Object_Item *)it;
4025 evas_object_unref(obj);
4028 static Evas_Object *
4029 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
4031 return edje_object_part_swallow_get(VIEW(it), part);
4035 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
4037 if (content && part)
4039 it->content_objs = eina_list_append(it->content_objs, content);
4040 edje_object_part_swallow(VIEW(it), part, content);
4044 static Evas_Object *
4045 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
4048 obj = edje_object_part_swallow_get(VIEW(it), part);
4049 if (!obj) return NULL;
4050 it->content_objs = eina_list_remove(it->content_objs, obj);
4051 edje_object_part_unswallow(VIEW(it), obj);
4056 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
4058 if (!it->itc->func.text_get) return NULL;
4059 return edje_object_part_text_get(VIEW(it), part);
4063 _item_disable_hook(Elm_Object_Item *it)
4067 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4069 if (_it->generation < _it->wd->generation) return;
4072 elm_genlist_item_selected_set(it, EINA_FALSE);
4076 if (elm_widget_item_disabled_get(it))
4078 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
4079 if (_it->deco_all_view)
4080 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
4084 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
4085 if (_it->deco_all_view)
4086 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
4088 EINA_LIST_FOREACH(_it->content_objs, l, obj)
4089 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
4094 _item_del_pre_hook(Elm_Object_Item *it)
4096 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4098 if ((_it->relcount > 0) || (_it->walking > 0))
4100 elm_genlist_item_subitems_clear(it);
4101 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
4102 _elm_genlist_item_del_notserious(_it);
4103 if (_it->item->block)
4105 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
4106 _it->item->block->changed = EINA_TRUE;
4107 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
4108 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
4112 _it->parent->item->items =
4113 eina_list_remove(_it->parent->item->items, it);
4123 _item_signal_emit_hook(Elm_Object_Item *it,
4124 const char *emission,
4127 edje_object_signal_emit(VIEW(it), emission, source);
4131 _elm_genlist_item_new(Widget_Data *wd,
4132 const Elm_Gen_Item_Class *itc,
4134 Elm_Gen_Item *parent,
4136 const void *func_data)
4140 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
4141 if (!it) return NULL;
4143 it->generation = wd->generation;
4145 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
4146 it->base.data = data;
4147 it->parent = parent;
4148 it->func.func = func;
4149 it->func.data = func_data;
4150 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
4151 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
4152 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
4153 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
4154 elm_widget_item_disable_hook_set(it, _item_disable_hook);
4155 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
4156 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
4159 it->sel_cb = (Ecore_Cb)_item_select;
4164 static Elm_Gen_Item *
4165 _item_new(Widget_Data *wd,
4166 const Elm_Genlist_Item_Class *itc,
4168 Elm_Gen_Item *parent,
4169 Elm_Genlist_Item_Type type,
4171 const void *func_data)
4173 Elm_Gen_Item *it, *it2;
4176 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
4177 if (!it) return NULL;
4178 it->item = ELM_NEW(Elm_Gen_Item_Type);
4179 it->item->type = type;
4180 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
4181 it->item->expanded_depth = 0;
4182 ELM_GEN_ITEM_SETUP(it);
4183 it->mouse_cursor = NULL;
4184 it->can_focus = EINA_TRUE;
4187 if (it->parent->group)
4188 it->item->group_item = parent;
4189 else if (it->parent->item->group_item)
4190 it->item->group_item = it->parent->item->group_item;
4192 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
4194 if (!it2->parent->group) depth += 1;
4196 it->item->expanded_depth = depth;
4202 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
4206 itb = calloc(1, sizeof(Item_Block));
4207 if (!itb) return NULL;
4211 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
4212 _item_block_position_update(wd->blocks, 0);
4216 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4217 itb->position_update = EINA_TRUE;
4218 if (wd->blocks != EINA_INLIST_GET(itb))
4220 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4231 _item_block_add(Widget_Data *wd,
4234 Item_Block *itb = NULL;
4241 itb = calloc(1, sizeof(Item_Block));
4242 if (!itb) return EINA_FALSE;
4244 if (!it->item->rel->item->block)
4247 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4248 itb->items = eina_list_append(itb->items, it);
4249 itb->position_update = EINA_TRUE;
4250 it->position = eina_list_count(itb->items);
4251 it->position_update = EINA_TRUE;
4253 if (wd->blocks != EINA_INLIST_GET(itb))
4255 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4266 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4267 if (it->item->before)
4269 wd->blocks = eina_inlist_prepend_relative
4270 (wd->blocks, EINA_INLIST_GET(itb),
4271 EINA_INLIST_GET(it->item->rel->item->block));
4273 eina_list_prepend_relative_list(itb->items, it, tmp);
4275 /* Update index from where we prepended */
4276 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4277 _item_block_position_update(EINA_INLIST_GET(itb),
4278 it->item->rel->item->block->position);
4282 wd->blocks = eina_inlist_append_relative
4283 (wd->blocks, EINA_INLIST_GET(itb),
4284 EINA_INLIST_GET(it->item->rel->item->block));
4286 eina_list_append_relative_list(itb->items, it, tmp);
4288 /* Update block index from where we appended */
4289 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4290 _item_block_position_update(EINA_INLIST_GET(itb),
4291 it->item->rel->item->block->position + 1);
4297 if (it->item->before)
4301 itb = (Item_Block *)(wd->blocks);
4302 if (itb->count >= wd->max_items_per_block)
4304 itb = _item_block_new(wd, EINA_TRUE);
4305 if (!itb) return EINA_FALSE;
4310 itb = _item_block_new(wd, EINA_TRUE);
4311 if (!itb) return EINA_FALSE;
4313 itb->items = eina_list_prepend(itb->items, it);
4315 _item_position_update(itb->items, 0);
4321 itb = (Item_Block *)(wd->blocks->last);
4322 if (itb->count >= wd->max_items_per_block)
4324 itb = _item_block_new(wd, EINA_FALSE);
4325 if (!itb) return EINA_FALSE;
4330 itb = _item_block_new(wd, EINA_FALSE);
4331 if (!itb) return EINA_FALSE;
4333 itb->items = eina_list_append(itb->items, it);
4334 it->position = eina_list_count(itb->items);
4342 if (it->item->rel->item->queued)
4344 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
4345 on sorted insertion order, so the queue is not always ordered like the item list.
4346 This lead to issue where we depend on an item that is not yet created. As a quick
4347 work around, we reschedule the calc of the item and stop reordering the list to
4348 prevent any nasty issue to show up here.
4350 wd->queue = eina_list_append(wd->queue, it);
4351 wd->requeued = EINA_TRUE;
4352 it->item->queued = EINA_TRUE;
4355 itb = it->item->rel->item->block;
4356 if (!itb) goto newblock;
4357 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4358 if (it->item->before)
4360 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4361 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4365 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4366 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4370 itb->changed = EINA_TRUE;
4371 it->item->block = itb;
4372 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
4373 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
4376 it->item->rel->relcount--;
4377 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
4379 _item_del(it->item->rel);
4380 elm_widget_item_free(it->item->rel);
4382 it->item->rel = NULL;
4384 if (itb->count > itb->wd->max_items_per_block)
4389 Eina_Bool done = EINA_FALSE;
4391 newc = itb->count / 2;
4393 if (EINA_INLIST_GET(itb)->prev)
4395 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4397 if (itbp->count + newc < wd->max_items_per_block / 2)
4399 /* moving items to previous block */
4400 while ((itb->count > newc) && (itb->items))
4402 it2 = eina_list_data_get(itb->items);
4403 itb->items = eina_list_remove_list(itb->items, itb->items);
4406 itbp->items = eina_list_append(itbp->items, it2);
4407 it2->item->block = itbp;
4415 if (!done && EINA_INLIST_GET(itb)->next)
4417 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4419 if (itbn->count + newc < wd->max_items_per_block / 2)
4421 /* moving items to next block */
4422 while ((itb->count > newc) && (itb->items))
4426 l = eina_list_last(itb->items);
4427 it2 = eina_list_data_get(l);
4428 itb->items = eina_list_remove_list(itb->items, l);
4431 itbn->items = eina_list_prepend(itbn->items, it2);
4432 it2->item->block = itbn;
4442 /* moving items to new block */
4443 itb2 = calloc(1, sizeof(Item_Block));
4444 if (!itb2) return EINA_FALSE;
4447 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4448 EINA_INLIST_GET(itb));
4449 itb2->changed = EINA_TRUE;
4450 while ((itb->count > newc) && (itb->items))
4454 l = eina_list_last(itb->items);
4456 itb->items = eina_list_remove_list(itb->items, l);
4459 itb2->items = eina_list_prepend(itb2->items, it2);
4460 it2->item->block = itb2;
4470 _item_process(Widget_Data *wd, Elm_Gen_Item *it)
4472 if (!_item_block_add(wd, it)) return 1;
4474 _item_block_realize(it->item->block);
4479 _item_process_post(Widget_Data *wd, Elm_Gen_Item *it, Eina_Bool qadd)
4481 Eina_Bool showme = EINA_FALSE;
4483 if (it->item->block->changed)
4485 showme = _item_block_recalc(it->item->block, it->item->block->num, qadd);
4486 it->item->block->changed = 0;
4487 if (wd->pan_changed)
4489 if (wd->calc_job) ecore_job_del(wd->calc_job);
4490 wd->calc_job = NULL;
4492 wd->pan_changed = EINA_FALSE;
4495 if (showme) it->item->block->showme = EINA_TRUE;
4496 /* when prepending, move the scroller along with the first selected item to
4497 * create the illusion that we're watching the selected item
4498 * this prevents the selected item being scrolled off the viewport
4500 if (wd->selected && it->item->before)
4503 it = wd->selected->data;
4504 elm_smart_scroller_child_pos_get(wd->scr, NULL, &y);
4505 evas_object_geometry_get(wd->pan_smart, NULL, NULL, NULL, &h);
4506 elm_smart_scroller_child_region_show(wd->scr, it->x + it->item->block->x, y + it->item->h, it->item->block->w, h);
4511 _queue_process(Widget_Data *wd)
4516 t0 = ecore_loop_time_get();
4517 //evas_event_freeze(evas_object_evas_get(wd->obj));
4518 for (n = 0; (wd->queue) && (n < 128); n++)
4522 it = eina_list_data_get(wd->queue);
4523 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4524 it->item->queued = EINA_FALSE;
4525 if (_item_process(wd, it)) continue;
4526 t = ecore_time_get();
4527 _item_process_post(wd, it, EINA_TRUE);
4528 /* same as eina_inlist_count > 1 */
4529 if (wd->blocks && wd->blocks->next)
4531 if ((t - t0) > (ecore_animator_frametime_get())) break;
4534 //evas_event_thaw(evas_object_evas_get(wd->obj));
4535 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4540 _idle_process(void *data, Eina_Bool *wakeup)
4542 Widget_Data *wd = data;
4545 //static double q_start = 0.0;
4546 //if (q_start == 0.0) q_start = ecore_time_get();
4548 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4552 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4554 return ECORE_CALLBACK_CANCEL;
4556 return ECORE_CALLBACK_RENEW;
4560 _item_idle_enterer(void *data)
4562 Widget_Data *wd = data;
4563 Eina_Bool wakeup = EINA_FALSE;
4564 Eina_Bool ok = _idle_process(data, &wakeup);
4569 if (wd->calc_job) ecore_job_del(wd->calc_job);
4570 wd->calc_job = ecore_job_add(_calc_job, wd);
4572 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4577 _item_queue(Widget_Data *wd,
4581 if (it->item->queued) return;
4582 if ((wd->blocks) && (wd->homogeneous) && (wd->mode == ELM_LIST_COMPRESS))
4584 if (!_item_process(wd, it))
4585 _item_process_post(wd, it, EINA_FALSE);
4588 it->item->queued = EINA_TRUE;
4589 if (cb && !wd->requeued)
4590 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4592 wd->queue = eina_list_append(wd->queue, it);
4593 // FIXME: why does a freeze then thaw here cause some genlist
4594 // elm_genlist_item_append() to be much much slower?
4595 // evas_event_freeze(evas_object_evas_get(wd->obj));
4596 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4598 if (wd->queue_idle_enterer)
4600 ecore_idle_enterer_del(wd->queue_idle_enterer);
4601 wd->queue_idle_enterer = NULL;
4605 // evas_event_thaw(evas_object_evas_get(wd->obj));
4606 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4607 if (!wd->queue_idle_enterer)
4608 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4612 _elm_genlist_item_compare(const void *data, const void *data1)
4614 const Elm_Gen_Item *it, *item1;
4615 it = ELM_GEN_ITEM_FROM_INLIST(data);
4616 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4617 return it->wd->item_compare_cb(it, item1);
4621 _elm_genlist_item_list_compare(const void *data, const void *data1)
4623 const Elm_Gen_Item *it = data;
4624 const Elm_Gen_Item *item1 = data1;
4625 return it->wd->item_compare_cb(it, item1);
4628 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4630 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4635 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4636 _item_block_del(it);
4638 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4639 it->item->rel = after;
4640 it->item->rel->relcount++;
4641 it->item->before = EINA_FALSE;
4642 if (after->item->group_item) it->item->group_item = after->item->group_item;
4643 _item_queue(it->wd, it, NULL);
4645 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4648 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4650 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4653 if (!before) return;
4655 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4656 _item_block_del(it);
4657 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4658 it->item->rel = before;
4659 it->item->rel->relcount++;
4660 it->item->before = EINA_TRUE;
4661 if (before->item->group_item) it->item->group_item = before->item->group_item;
4662 _item_queue(it->wd, it, NULL);
4664 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4668 elm_genlist_items_count(const Evas_Object *obj)
4670 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4671 Widget_Data *wd = elm_widget_data_get(obj);
4673 return wd->item_count;
4676 EAPI Elm_Object_Item *
4677 elm_genlist_item_append(Evas_Object *obj,
4678 const Elm_Genlist_Item_Class *itc,
4680 Elm_Object_Item *parent,
4681 Elm_Genlist_Item_Type type,
4683 const void *func_data)
4685 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4686 Widget_Data *wd = elm_widget_data_get(obj);
4687 if (!wd) return NULL;
4688 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4690 if (!it) return NULL;
4694 wd->group_items = eina_list_append(wd->group_items, it);
4695 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4696 it->item->rel = NULL;
4700 Elm_Gen_Item *it2 = NULL;
4701 Eina_List *ll = eina_list_last(it->parent->item->items);
4702 if (ll) it2 = ll->data;
4703 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4704 if (!it2) it2 = it->parent;
4706 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4707 EINA_INLIST_GET(it2));
4708 it->item->rel = it2;
4709 it->item->rel->relcount++;
4711 it->item->before = EINA_FALSE;
4712 _item_queue(wd, it, NULL);
4713 return (Elm_Object_Item *)it;
4716 EAPI Elm_Object_Item *
4717 elm_genlist_item_prepend(Evas_Object *obj,
4718 const Elm_Genlist_Item_Class *itc,
4720 Elm_Object_Item *parent,
4721 Elm_Genlist_Item_Type type,
4723 const void *func_data)
4725 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4726 Widget_Data *wd = elm_widget_data_get(obj);
4727 if (!wd) return NULL;
4728 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4730 if (!it) return NULL;
4734 wd->group_items = eina_list_prepend(wd->group_items, it);
4735 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4736 it->item->rel = NULL;
4740 Elm_Gen_Item *it2 = NULL;
4741 Eina_List *ll = it->parent->item->items;
4742 if (ll) it2 = ll->data;
4743 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4744 if (!it2) it2 = it->parent;
4746 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4747 EINA_INLIST_GET(it2));
4748 it->item->rel = it2;
4749 it->item->rel->relcount++;
4751 it->item->before = EINA_TRUE;
4752 _item_queue(wd, it, NULL);
4753 return (Elm_Object_Item *)it;
4756 EAPI Elm_Object_Item *
4757 elm_genlist_item_insert_after(Evas_Object *obj,
4758 const Elm_Genlist_Item_Class *itc,
4760 Elm_Object_Item *parent,
4761 Elm_Object_Item *after,
4762 Elm_Genlist_Item_Type type,
4764 const void *func_data)
4766 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4767 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4768 Widget_Data *wd = elm_widget_data_get(obj);
4769 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4770 if (!wd) return NULL;
4771 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4772 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4774 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4776 if (!it) return NULL;
4779 if ((it->group) && (_after->group))
4780 wd->group_items = eina_list_append_relative(wd->group_items, it,
4785 it->parent->item->items =
4786 eina_list_append_relative(it->parent->item->items, it, _after);
4788 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4789 EINA_INLIST_GET(_after));
4790 it->item->rel = _after;
4791 it->item->rel->relcount++;
4792 it->item->before = EINA_FALSE;
4793 _item_queue(wd, it, NULL);
4794 return (Elm_Object_Item *)it;
4797 EAPI Elm_Object_Item *
4798 elm_genlist_item_insert_before(Evas_Object *obj,
4799 const Elm_Genlist_Item_Class *itc,
4801 Elm_Object_Item *parent,
4802 Elm_Object_Item *before,
4803 Elm_Genlist_Item_Type type,
4805 const void *func_data)
4807 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4808 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4809 Widget_Data *wd = elm_widget_data_get(obj);
4810 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4811 if (!wd) return NULL;
4812 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4813 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4815 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4817 if (!it) return NULL;
4820 if (it->group && _before->group)
4821 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4826 it->parent->item->items =
4827 eina_list_prepend_relative(it->parent->item->items, it, _before);
4829 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4830 EINA_INLIST_GET(_before));
4831 it->item->rel = _before;
4832 it->item->rel->relcount++;
4833 it->item->before = EINA_TRUE;
4834 _item_queue(wd, it, NULL);
4835 return (Elm_Object_Item *)it;
4838 EAPI Elm_Object_Item *
4839 elm_genlist_item_sorted_insert(Evas_Object *obj,
4840 const Elm_Genlist_Item_Class *itc,
4842 Elm_Object_Item *parent,
4843 Elm_Genlist_Item_Type type,
4844 Eina_Compare_Cb comp,
4846 const void *func_data)
4848 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4849 Widget_Data *wd = elm_widget_data_get(obj);
4850 if (!wd) return NULL;
4851 Elm_Gen_Item *rel = NULL;
4852 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4854 if (!it) return NULL;
4856 wd->item_compare_cb = comp;
4863 l = eina_list_search_sorted_near_list(it->parent->item->items,
4864 _elm_genlist_item_list_compare,
4868 rel = eina_list_data_get(l);
4872 if (cmp_result >= 0)
4874 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4875 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4876 it->item->before = EINA_FALSE;
4878 else if (cmp_result < 0)
4880 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4881 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4882 it->item->before = EINA_TRUE;
4889 wd->state = eina_inlist_sorted_state_new();
4890 eina_inlist_sorted_state_init(wd->state, wd->items);
4891 wd->requeued = EINA_FALSE;
4895 wd->group_items = eina_list_append(wd->group_items, it);
4897 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4898 _elm_genlist_item_compare, wd->state);
4900 if (EINA_INLIST_GET(it)->next)
4902 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4903 it->item->before = EINA_TRUE;
4905 else if (EINA_INLIST_GET(it)->prev)
4907 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4908 it->item->before = EINA_FALSE;
4914 it->item->rel = rel;
4915 it->item->rel->relcount++;
4918 _item_queue(wd, it, _elm_genlist_item_list_compare);
4920 return (Elm_Object_Item *)it;
4924 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4926 Eina_Inlist *next, *l;
4927 Widget_Data *wd = elm_widget_data_get(obj);
4930 if (!standby) wd->generation++;
4934 eina_inlist_sorted_state_free(wd->state);
4938 if (wd->walking > 0)
4940 wd->clear_me = EINA_TRUE;
4943 evas_event_freeze(evas_object_evas_get(wd->obj));
4944 for (l = wd->items, next = l ? l->next : NULL;
4946 l = next, next = next ? next->next : NULL)
4948 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4950 if (it->generation < wd->generation)
4952 Elm_Gen_Item *itn = NULL;
4954 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4955 if (itn) itn->walking++; /* prevent early death of subitem */
4957 elm_widget_item_free(it);
4958 if (itn) itn->walking--;
4961 wd->clear_me = EINA_FALSE;
4962 wd->pan_changed = EINA_TRUE;
4965 ecore_job_del(wd->calc_job);
4966 wd->calc_job = NULL;
4968 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4969 if (wd->clear_cb) wd->clear_cb(wd);
4975 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4976 wd->alpha_bg = NULL;
4980 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4981 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4983 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4984 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4985 evas_event_thaw(evas_object_evas_get(wd->obj));
4986 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4990 elm_genlist_clear(Evas_Object *obj)
4992 ELM_CHECK_WIDTYPE(obj, widtype);
4993 _elm_genlist_clear(obj, EINA_FALSE);
4997 elm_genlist_multi_select_set(Evas_Object *obj,
5000 ELM_CHECK_WIDTYPE(obj, widtype);
5001 Widget_Data *wd = elm_widget_data_get(obj);
5003 wd->multi = !!multi;
5007 elm_genlist_multi_select_get(const Evas_Object *obj)
5009 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5010 Widget_Data *wd = elm_widget_data_get(obj);
5011 if (!wd) return EINA_FALSE;
5015 EAPI Elm_Object_Item *
5016 elm_genlist_selected_item_get(const Evas_Object *obj)
5018 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5019 Widget_Data *wd = elm_widget_data_get(obj);
5020 if (!wd) return NULL;
5021 if (wd->selected) return wd->selected->data;
5025 EAPI const Eina_List *
5026 elm_genlist_selected_items_get(const Evas_Object *obj)
5028 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5029 Widget_Data *wd = elm_widget_data_get(obj);
5030 if (!wd) return NULL;
5031 return wd->selected;
5035 elm_genlist_realized_items_get(const Evas_Object *obj)
5037 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5038 Widget_Data *wd = elm_widget_data_get(obj);
5039 Eina_List *list = NULL;
5041 Eina_Bool done = EINA_FALSE;
5042 if (!wd) return NULL;
5043 EINA_INLIST_FOREACH(wd->blocks, itb)
5051 EINA_LIST_FOREACH(itb->items, l, it)
5053 if (it->realized) list = eina_list_append(list, it);
5064 EAPI Elm_Object_Item *
5065 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5070 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5071 Widget_Data *wd = elm_widget_data_get(obj);
5072 Evas_Coord ox, oy, ow, oh;
5075 if (!wd) return NULL;
5076 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5078 EINA_INLIST_FOREACH(wd->blocks, itb)
5083 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
5084 oy + itb->y - itb->wd->pan_y,
5085 itb->w, itb->h, x, y, 1, 1))
5087 EINA_LIST_FOREACH(itb->items, l, it)
5089 Evas_Coord itx, ity;
5091 itx = ox + itb->x + it->x - itb->wd->pan_x;
5092 ity = oy + itb->y + it->y - itb->wd->pan_y;
5093 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5097 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5098 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5102 return (Elm_Object_Item *)it;
5104 lasty = ity + it->item->h;
5109 if (y > lasty) *posret = 1;
5115 EAPI Elm_Object_Item *
5116 elm_genlist_first_item_get(const Evas_Object *obj)
5118 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5119 Widget_Data *wd = elm_widget_data_get(obj);
5120 if (!wd) return NULL;
5121 if (!wd->items) return NULL;
5122 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
5123 while ((it) && (it->generation < wd->generation))
5124 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5125 return (Elm_Object_Item *)it;
5128 EAPI Elm_Object_Item *
5129 elm_genlist_last_item_get(const Evas_Object *obj)
5131 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5132 Widget_Data *wd = elm_widget_data_get(obj);
5133 if (!wd) return NULL;
5134 if (!wd->items) return NULL;
5135 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
5136 while ((it) && (it->generation < wd->generation))
5137 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5138 return (Elm_Object_Item *)it;
5141 EAPI Elm_Object_Item *
5142 elm_genlist_item_next_get(const Elm_Object_Item *it)
5144 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5145 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5148 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
5149 if ((_it) && (_it->generation == _it->wd->generation)) break;
5151 return (Elm_Object_Item *) _it;
5154 EAPI Elm_Object_Item *
5155 elm_genlist_item_prev_get(const Elm_Object_Item *it)
5157 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5158 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5161 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
5162 if ((_it) && (_it->generation == _it->wd->generation)) break;
5164 return (Elm_Object_Item *) _it;
5167 EAPI Elm_Object_Item *
5168 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5170 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5171 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
5175 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
5177 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5178 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
5180 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5182 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
5183 _item_subitems_clear(_it);
5186 if (!wd->tree_effect_animator)
5188 wd->expanded_item = _it;
5189 _item_tree_effect_before(_it);
5190 evas_object_raise(wd->alpha_bg);
5191 evas_object_show(wd->alpha_bg);
5192 wd->start_time = ecore_time_get();
5193 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
5196 _item_subitems_clear(_it);
5201 elm_genlist_item_selected_set(Elm_Object_Item *it,
5204 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5205 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5206 Widget_Data *wd = _it->wd;
5208 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
5210 selected = !!selected;
5211 if (_it->selected == selected) return;
5217 while (wd->selected)
5219 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
5220 _it->unsel_cb(wd->selected->data);
5223 _it->highlight_cb(_it);
5227 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
5232 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5234 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5235 return ((Elm_Gen_Item *)it)->selected;
5239 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5242 if (it->item->expanded)
5244 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5248 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5251 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5252 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5259 _elm_genlist_move_items_set(Elm_Gen_Item *it)
5262 Elm_Gen_Item *it2 = NULL;
5263 Evas_Coord ox, oy, ow, oh, dh = 0;
5265 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
5267 if (it->item->expanded)
5269 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
5270 EINA_LIST_FOREACH_SAFE(it->wd->move_items, l, ll, it2)
5272 if (it2 == it->wd->expanded_next_item) break;
5273 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
5278 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
5279 it2 = it->wd->expanded_next_item;
5280 while (it2 && (dh < oy + oh))
5283 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
5284 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5290 elm_genlist_item_expanded_set(Elm_Object_Item *it,
5293 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5294 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5295 expanded = !!expanded;
5296 if (_it->item->expanded == expanded) return;
5297 if (_it->item->type != ELM_GENLIST_ITEM_TREE) return;
5298 _it->item->expanded = expanded;
5299 _it->wd->expanded_item = _it;
5300 _elm_genlist_move_items_set(_it);
5302 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
5303 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
5305 if (_it->item->expanded)
5307 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
5309 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
5310 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
5311 _it->wd->auto_scroll_enabled = EINA_TRUE;
5315 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
5317 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
5318 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
5319 _it->wd->auto_scroll_enabled = EINA_FALSE;
5324 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5326 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5327 return ((Elm_Gen_Item *)it)->item->expanded;
5331 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5333 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
5334 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5337 EINA_DEPRECATED EAPI void
5338 elm_genlist_item_display_only_set(Elm_Object_Item *it,
5339 Eina_Bool display_only)
5341 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5342 display_only = !!display_only;
5345 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
5348 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5349 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5350 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
5354 EINA_DEPRECATED EAPI Eina_Bool
5355 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
5357 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5358 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5359 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5360 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5361 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5367 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
5368 Elm_Genlist_Item_Scrollto_Type type,
5375 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5376 Evas_Coord gith = 0;
5377 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5378 if ((_it->wd->homogeneous) &&
5379 (_it->wd->mode == ELM_LIST_COMPRESS))
5380 goto hm_shortcut; /* homogenous genlist shortcut */
5381 if ((_it->item->queued) || (!_it->item->mincalcd))
5383 _it->wd->show_item = _it;
5384 _it->wd->bring_in = bring_in;
5385 _it->wd->scrollto_type = type;
5386 _it->item->showme = EINA_TRUE;
5390 if (_it->wd->show_item)
5392 _it->wd->show_item->item->showme = EINA_FALSE;
5393 _it->wd->show_item = NULL;
5396 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
5399 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5400 if ((_it->item->group_item) &&
5401 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
5402 gith = _it->item->group_item->item->h;
5404 *y = _it->y + _it->item->block->y - gith;
5406 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5407 if (_it->item->group_item) gith = _it->item->group_item->item->h;
5408 *y = _it->y + _it->item->block->y - gith;
5410 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5411 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
5417 *x = _it->x + _it->item->block->x;
5418 *w = _it->item->block->w;
5423 elm_genlist_item_promote(Elm_Object_Item *it)
5425 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5426 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5427 if (_it->generation < _it->wd->generation) return;
5428 _item_move_before(_it,
5429 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
5433 elm_genlist_item_demote(Elm_Object_Item *it)
5435 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5436 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5437 if (_it->generation < _it->wd->generation) return;
5438 _item_move_after(_it,
5439 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
5443 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5445 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5446 Evas_Coord x, y, w, h;
5447 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5449 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
5450 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
5454 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5457 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5458 Evas_Coord x, y, w, h;
5459 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5461 elm_smart_scroller_child_viewport_size_get(_it->wd->scr, &x, &y);
5463 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
5464 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
5468 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5470 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5472 Evas_Object *content;
5473 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5475 elm_widget_sub_object_del(WIDGET(it), content);
5476 evas_object_smart_member_del(content);
5477 evas_object_hide(content);
5478 if (l) *l = eina_list_append(*l, content);
5483 elm_genlist_item_update(Elm_Object_Item *it)
5485 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5486 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5488 if (!_it->item->block) return;
5489 if (_it->generation < _it->wd->generation) return;
5490 _it->item->mincalcd = EINA_FALSE;
5491 _it->item->updateme = EINA_TRUE;
5492 _it->item->block->updateme = EINA_TRUE;
5493 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5494 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5498 elm_genlist_item_fields_update(Elm_Object_Item *it,
5500 Elm_Genlist_Item_Field_Type itf)
5502 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5503 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5505 if (!_it->item->block) return;
5506 if (_it->generation < _it->wd->generation) return;
5508 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5509 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5510 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5512 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5513 &_it->contents, parts);
5514 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5515 &_it->contents, parts);
5519 _it->item->flip_content_objs =
5520 _item_mode_content_unrealize(_it, VIEW(_it),
5521 &_it->item->flip_contents, parts,
5522 &_it->item->flip_content_objs);
5523 _it->item->flip_content_objs =
5524 _item_mode_content_realize(_it, VIEW(_it),
5525 &_it->item->flip_contents, parts,
5526 &_it->item->flip_content_objs);
5528 if (_it->item->deco_it_view)
5530 _it->item->deco_it_content_objs =
5531 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5532 &_it->item->deco_it_contents, parts,
5533 &_it->item->deco_it_content_objs);
5534 _it->item->deco_it_content_objs =
5535 _item_mode_content_realize(_it, _it->item->deco_it_view,
5536 &_it->item->deco_it_contents, parts,
5537 &_it->item->deco_it_content_objs);
5539 if (_it->wd->decorate_all_mode)
5541 _it->item->deco_all_content_objs =
5542 _item_mode_content_unrealize(_it, _it->deco_all_view,
5543 &_it->item->deco_all_contents, parts,
5544 &_it->item->deco_all_content_objs);
5545 _it->item->deco_all_content_objs =
5546 _item_mode_content_realize(_it, _it->deco_all_view,
5547 &_it->item->deco_all_contents, parts,
5548 &_it->item->deco_all_content_objs);
5551 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5552 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5556 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5557 const Elm_Genlist_Item_Class *itc)
5559 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5560 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5562 if (!_it->item->block) return;
5563 EINA_SAFETY_ON_NULL_RETURN(itc);
5564 if (_it->generation < _it->wd->generation) return;
5566 _it->item->nocache_once = EINA_TRUE;
5568 elm_widget_stringlist_free(_it->texts);
5570 elm_widget_stringlist_free(_it->contents);
5571 _it->contents = NULL;
5572 elm_widget_stringlist_free(_it->states);
5577 elm_widget_stringlist_free(_it->item->flip_contents);
5578 _it->item->flip_contents = NULL;
5580 if (_it->item->deco_it_view)
5582 elm_widget_stringlist_free(_it->item->deco_it_texts);
5583 _it->item->deco_it_texts = NULL;
5584 elm_widget_stringlist_free(_it->item->deco_it_contents);
5585 _it->item->deco_it_contents = NULL;
5587 if (_it->wd->decorate_all_mode)
5589 elm_widget_stringlist_free(_it->item->deco_all_texts);
5590 _it->item->deco_all_texts = NULL;
5591 elm_widget_stringlist_free(_it->item->deco_all_contents);
5592 _it->item->deco_all_contents = NULL;
5595 elm_genlist_item_update(it);
5598 EAPI const Elm_Genlist_Item_Class *
5599 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5601 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5602 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5603 if (_it->generation < _it->wd->generation) return NULL;
5607 static Evas_Object *
5608 _elm_genlist_item_label_create(void *data,
5609 Evas_Object *obj __UNUSED__,
5610 Evas_Object *tooltip,
5611 void *it __UNUSED__)
5613 Evas_Object *label = elm_label_add(tooltip);
5616 elm_object_style_set(label, "tooltip");
5617 elm_object_text_set(label, data);
5622 _elm_genlist_item_label_del_cb(void *data,
5623 Evas_Object *obj __UNUSED__,
5624 void *event_info __UNUSED__)
5626 eina_stringshare_del(data);
5630 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5633 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5634 text = eina_stringshare_add(text);
5635 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5637 _elm_genlist_item_label_del_cb);
5641 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5642 Elm_Tooltip_Item_Content_Cb func,
5644 Evas_Smart_Cb del_cb)
5646 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5647 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5649 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5652 if (_it->tooltip.del_cb)
5653 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5655 _it->tooltip.content_cb = func;
5656 _it->tooltip.data = data;
5657 _it->tooltip.del_cb = del_cb;
5661 elm_widget_item_tooltip_content_cb_set(_it,
5662 _it->tooltip.content_cb,
5663 _it->tooltip.data, NULL);
5664 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5665 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5671 if (del_cb) del_cb((void *)data, NULL, NULL);
5675 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5677 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5678 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5680 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5681 elm_widget_item_tooltip_unset(_it);
5683 if (_it->tooltip.del_cb)
5684 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5685 _it->tooltip.del_cb = NULL;
5686 _it->tooltip.content_cb = NULL;
5687 _it->tooltip.data = NULL;
5688 _it->tooltip.free_size = EINA_FALSE;
5689 if (_it->tooltip.style)
5690 elm_genlist_item_tooltip_style_set(it, NULL);
5694 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5697 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5698 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5700 eina_stringshare_replace(&_it->tooltip.style, style);
5701 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5705 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5707 return elm_object_item_tooltip_style_get(it);
5711 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5714 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5715 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5717 _it->tooltip.free_size = disable;
5718 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5723 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5725 return elm_object_tooltip_window_mode_get(VIEW(it));
5729 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5732 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5733 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5734 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5735 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5739 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5741 return elm_widget_item_cursor_get(it);
5745 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5747 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5748 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5750 if (!_it->mouse_cursor) return;
5752 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5754 eina_stringshare_del(_it->mouse_cursor);
5755 _it->mouse_cursor = NULL;
5759 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5762 elm_widget_item_cursor_style_set(it, style);
5766 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5768 return elm_widget_item_cursor_style_get(it);
5772 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5773 Eina_Bool engine_only)
5775 elm_widget_item_cursor_engine_only_set(it, engine_only);
5779 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5781 return elm_widget_item_cursor_engine_only_get(it);
5785 elm_genlist_item_index_get(const Elm_Object_Item *it)
5787 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5788 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5790 if (_it->item->block)
5791 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5796 elm_genlist_mode_set(Evas_Object *obj,
5799 ELM_CHECK_WIDTYPE(obj, widtype);
5800 Widget_Data *wd = elm_widget_data_get(obj);
5802 if (wd->mode == mode) return;
5809 elm_genlist_mode_get(const Evas_Object *obj)
5811 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5812 Widget_Data *wd = elm_widget_data_get(obj);
5813 if (!wd) return ELM_LIST_LAST;
5818 elm_genlist_bounce_set(Evas_Object *obj,
5822 ELM_CHECK_WIDTYPE(obj, widtype);
5823 Widget_Data *wd = elm_widget_data_get(obj);
5825 wd->h_bounce = !!h_bounce;
5826 wd->v_bounce = !!v_bounce;
5827 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5831 elm_genlist_bounce_get(const Evas_Object *obj,
5832 Eina_Bool *h_bounce,
5833 Eina_Bool *v_bounce)
5835 ELM_CHECK_WIDTYPE(obj, widtype);
5836 Widget_Data *wd = elm_widget_data_get(obj);
5838 if (h_bounce) *h_bounce = wd->h_bounce;
5839 if (v_bounce) *v_bounce = wd->v_bounce;
5843 elm_genlist_homogeneous_set(Evas_Object *obj,
5844 Eina_Bool homogeneous)
5846 ELM_CHECK_WIDTYPE(obj, widtype);
5847 Widget_Data *wd = elm_widget_data_get(obj);
5849 wd->homogeneous = !!homogeneous;
5853 elm_genlist_homogeneous_get(const Evas_Object *obj)
5855 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5856 Widget_Data *wd = elm_widget_data_get(obj);
5857 if (!wd) return EINA_FALSE;
5858 return wd->homogeneous;
5862 elm_genlist_block_count_set(Evas_Object *obj,
5865 ELM_CHECK_WIDTYPE(obj, widtype);
5866 Widget_Data *wd = elm_widget_data_get(obj);
5868 wd->max_items_per_block = count;
5869 wd->item_cache_max = wd->max_items_per_block * 2;
5870 _item_cache_clean(wd);
5874 elm_genlist_block_count_get(const Evas_Object *obj)
5876 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5877 Widget_Data *wd = elm_widget_data_get(obj);
5879 return wd->max_items_per_block;
5883 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5886 ELM_CHECK_WIDTYPE(obj, widtype);
5887 Widget_Data *wd = elm_widget_data_get(obj);
5889 wd->longpress_timeout = timeout;
5893 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5895 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5896 Widget_Data *wd = elm_widget_data_get(obj);
5898 return wd->longpress_timeout;
5902 elm_genlist_scroller_policy_set(Evas_Object *obj,
5903 Elm_Scroller_Policy policy_h,
5904 Elm_Scroller_Policy policy_v)
5906 ELM_CHECK_WIDTYPE(obj, widtype);
5907 Widget_Data *wd = elm_widget_data_get(obj);
5908 if ((!wd) || (!wd->scr)) return;
5909 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5910 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5912 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5916 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5917 Elm_Scroller_Policy *policy_h,
5918 Elm_Scroller_Policy *policy_v)
5920 ELM_CHECK_WIDTYPE(obj, widtype);
5921 Widget_Data *wd = elm_widget_data_get(obj);
5922 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5923 if ((!wd) || (!wd->scr)) return;
5924 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5925 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5926 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5930 elm_genlist_realized_items_update(Evas_Object *obj)
5932 ELM_CHECK_WIDTYPE(obj, widtype);
5934 Eina_List *list, *l;
5935 Elm_Object_Item *it;
5937 list = elm_genlist_realized_items_get(obj);
5938 EINA_LIST_FOREACH(list, l, it)
5939 elm_genlist_item_update(it);
5943 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5944 const char *decorate_it_type,
5945 Eina_Bool decorate_it_set)
5947 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5948 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5950 Widget_Data *wd = _it->wd;
5952 Elm_Object_Item *it2;
5955 if (!decorate_it_type) return;
5956 if ((_it->generation < _it->wd->generation) ||
5957 elm_widget_item_disabled_get(_it)) return;
5958 if (wd->decorate_all_mode) return;
5960 if ((wd->mode_item == _it) &&
5961 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5964 if (!_it->itc->decorate_item_style) return;
5965 _it->decorate_it_set = decorate_it_set;
5969 EINA_LIST_FOREACH(wd->selected, l, it2)
5970 if (((Elm_Gen_Item *)it2)->realized)
5971 elm_genlist_item_selected_set(it2, EINA_FALSE);
5975 it2 = elm_genlist_selected_item_get(wd->obj);
5976 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5977 elm_genlist_item_selected_set(it2, EINA_FALSE);
5980 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5981 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5982 _decorate_item_unset(wd);
5984 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5985 if (decorate_it_set) _decorate_item_set(_it);
5989 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5991 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5992 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5993 return _it->wd->decorate_it_type;
5996 EAPI const Elm_Object_Item *
5997 elm_genlist_decorated_item_get(const Evas_Object *obj)
5999 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6000 Widget_Data *wd = elm_widget_data_get(obj);
6001 if (!wd) return NULL;
6002 return (Elm_Object_Item *) wd->mode_item;
6006 elm_genlist_decorate_mode_get(const Evas_Object *obj)
6008 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6009 Widget_Data *wd = elm_widget_data_get(obj);
6010 if (!wd) return EINA_FALSE;
6012 return wd->decorate_all_mode;
6016 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
6018 ELM_CHECK_WIDTYPE(obj, widtype);
6019 Eina_List *list, *l;
6022 Widget_Data *wd = elm_widget_data_get(obj);
6024 decorated = !!decorated;
6025 if (wd->decorate_all_mode == decorated) return;
6026 wd->decorate_all_mode = decorated;
6028 if (wd->tree_effect_animator)
6030 ecore_animator_del(wd->tree_effect_animator);
6031 wd->tree_effect_animator = NULL;
6033 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6035 list = elm_genlist_realized_items_get(obj);
6036 if (!wd->decorate_all_mode)
6038 EINA_LIST_FOREACH(list, l, it)
6040 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6041 _decorate_all_item_unrealize(it);
6043 _item_cache_zero(wd);
6047 EINA_LIST_FOREACH(list, l, it)
6049 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
6051 if (it->itc->decorate_all_item_style)
6052 _decorate_all_item_realize(it, EINA_TRUE);
6056 if (wd->calc_job) ecore_job_del(wd->calc_job);
6057 wd->calc_job = ecore_job_add(_calc_job, wd);
6061 elm_genlist_reorder_mode_set(Evas_Object *obj,
6062 Eina_Bool reorder_mode)
6064 ELM_CHECK_WIDTYPE(obj, widtype);
6065 Widget_Data *wd = elm_widget_data_get(obj);
6067 wd->reorder_mode = !!reorder_mode;
6071 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6073 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6074 Widget_Data *wd = elm_widget_data_get(obj);
6075 if (!wd) return EINA_FALSE;
6076 return wd->reorder_mode;
6079 EAPI Elm_Genlist_Item_Type
6080 elm_genlist_item_type_get(const Elm_Object_Item *it)
6082 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
6083 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6084 return _it->item->type;
6087 EAPI Elm_Genlist_Item_Class *
6088 elm_genlist_item_class_new(void)
6090 Elm_Genlist_Item_Class *itc;
6092 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
6095 itc->version = CLASS_ALLOCATED;
6097 itc->delete_me = EINA_FALSE;
6103 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6105 if (itc && (itc->version == CLASS_ALLOCATED))
6107 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6108 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6118 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6120 if (itc && (itc->version == CLASS_ALLOCATED))
6123 if (itc->refcount == 0) itc->refcount--;
6128 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6130 if (itc && (itc->version == CLASS_ALLOCATED))
6132 if (itc->refcount > 0) itc->refcount--;
6133 if (itc->delete_me && (!itc->refcount))
6134 elm_genlist_item_class_free(itc);
6138 void _flip_job(void *data)
6140 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
6141 _item_unhighlight(it);
6143 _elm_genlist_item_unrealize(it, EINA_FALSE);
6144 it->flipped = EINA_TRUE;
6145 it->item->nocache = EINA_TRUE;
6146 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6147 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
6151 elm_genlist_item_flip_set(Elm_Object_Item *it,
6154 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6155 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6158 if (_it->flipped == flip) return;
6162 ecore_job_add(_flip_job, _it);
6166 _it->flipped = flip;
6167 _item_cache_zero(_it->wd);
6168 elm_genlist_item_update(it);
6169 _it->item->nocache = EINA_FALSE;
6174 elm_genlist_item_flip_get(const Elm_Object_Item *it)
6176 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6177 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6178 return _it->flipped;
6182 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
6184 ELM_CHECK_WIDTYPE(obj, widtype);
6185 Widget_Data *wd = elm_widget_data_get(obj);
6187 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6189 if (wd->select_mode != mode)
6190 wd->select_mode = mode;
6193 EAPI Elm_Object_Select_Mode
6194 elm_genlist_select_mode_get(const Evas_Object *obj)
6196 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
6197 Widget_Data *wd = elm_widget_data_get(obj);
6198 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
6199 return wd->select_mode;
6203 elm_genlist_highlight_mode_set(Evas_Object *obj,
6204 Eina_Bool highlight)
6206 ELM_CHECK_WIDTYPE(obj, widtype);
6207 Widget_Data *wd = elm_widget_data_get(obj);
6209 wd->highlight = !!highlight;
6213 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6215 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6216 Widget_Data *wd = elm_widget_data_get(obj);
6217 if (!wd) return EINA_FALSE;
6218 return wd->highlight;
6222 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
6223 Elm_Object_Select_Mode mode)
6225 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6226 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6228 if (_it->generation < _it->wd->generation) return;
6229 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6231 if (_it->select_mode != mode)
6232 _it->select_mode = mode;
6234 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6236 _it->item->mincalcd = EINA_FALSE;
6237 _it->item->updateme = EINA_TRUE;
6238 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
6239 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
6240 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
6244 EAPI Elm_Object_Select_Mode
6245 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
6247 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
6248 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6249 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
6250 return _it->select_mode;
6253 /* for gengrid as of now */
6255 _elm_genlist_page_relative_set(Evas_Object *obj,
6259 Evas_Coord pagesize_h;
6260 Evas_Coord pagesize_v;
6262 ELM_CHECK_WIDTYPE(obj, widtype);
6263 Widget_Data *wd = elm_widget_data_get(obj);
6266 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
6267 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
6271 /* for gengrid as of now */
6273 _elm_genlist_page_relative_get(const Evas_Object *obj,
6277 ELM_CHECK_WIDTYPE(obj, widtype);
6278 Widget_Data *wd = elm_widget_data_get(obj);
6281 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
6284 /* for gengrid as of now */
6286 _elm_genlist_page_size_set(Evas_Object *obj,
6287 Evas_Coord h_pagesize,
6288 Evas_Coord v_pagesize)
6293 ELM_CHECK_WIDTYPE(obj, widtype);
6294 Widget_Data *wd = elm_widget_data_get(obj);
6296 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
6297 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
6301 /* for gengrid as of now */
6303 _elm_genlist_current_page_get(const Evas_Object *obj,
6307 ELM_CHECK_WIDTYPE(obj, widtype);
6308 Widget_Data *wd = elm_widget_data_get(obj);
6310 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
6313 /* for gengrid as of now */
6315 _elm_genlist_last_page_get(const Evas_Object *obj,
6319 ELM_CHECK_WIDTYPE(obj, widtype);
6320 Widget_Data *wd = elm_widget_data_get(obj);
6322 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
6325 /* for gengrid as of now */
6327 _elm_genlist_page_show(const Evas_Object *obj,
6331 ELM_CHECK_WIDTYPE(obj, widtype);
6332 Widget_Data *wd = elm_widget_data_get(obj);
6334 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
6337 /* for gengrid as of now */
6339 _elm_genlist_page_bring_in(const Evas_Object *obj,
6343 ELM_CHECK_WIDTYPE(obj, widtype);
6344 Widget_Data *wd = elm_widget_data_get(obj);
6346 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
6350 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
6353 Evas_Object *content;
6355 if (!it->realized) return;
6356 if (it->wd->reorder_it == it) return;
6357 if (it->defer_unrealize && !it->item->updateme) return;
6359 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
6361 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
6364 ecore_timer_del(it->long_timer);
6365 it->long_timer = NULL;
6368 elm_widget_stringlist_free(it->texts);
6370 elm_widget_stringlist_free(it->contents);
6371 it->contents = NULL;
6372 elm_widget_stringlist_free(it->states);
6374 EINA_LIST_FREE(it->content_objs, content)
6375 evas_object_del(content);
6377 it->unrealize_cb(it);
6379 it->realized = EINA_FALSE;
6380 it->want_unrealize = EINA_FALSE;
6381 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
6382 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
6386 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
6388 elm_widget_item_pre_notify_del(it);
6389 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
6391 if ((it->relcount > 0) || (it->walking > 0)) return;
6393 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6395 if (it->itc->func.del)
6396 it->itc->func.del((void *)it->base.data, WIDGET(it));
6400 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
6402 _elm_genlist_item_del_notserious(it);
6403 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6404 if (it->tooltip.del_cb)
6405 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6406 it->wd->walking -= it->walking;
6409 ecore_timer_del(it->long_timer);
6410 it->long_timer = NULL;
6413 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
6417 eina_inlist_sorted_state_free(it->wd->state);
6418 it->wd->state = NULL;
6420 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6421 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
6425 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
6426 it->wd->last_selected_item = NULL;
6427 it->wd->item_count--;
6431 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
6433 ELM_CHECK_WIDTYPE(obj, widtype);
6434 Widget_Data *wd = elm_widget_data_get(obj);
6436 wd->tree_effect_enabled = !!enabled;
6440 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
6442 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6443 Widget_Data *wd = elm_widget_data_get(obj);
6444 if (!wd) return EINA_FALSE;
6445 return wd->tree_effect_enabled;
6449 _create_tray_alpha_bg(const Evas_Object *obj)
6451 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6452 Widget_Data *wd = elm_widget_data_get(obj);
6453 if (!wd) return NULL;
6455 Evas_Object *bg = NULL;
6456 Evas_Coord ox, oy, ow, oh;
6458 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6459 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6460 evas_object_color_set(bg,0,0,0,0);
6461 evas_object_resize(bg , ow, oh);
6462 evas_object_move(bg , ox, oy);
6467 _item_contract_emit(Elm_Gen_Item *it)
6472 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6473 it->item->tree_effect_finished = EINA_FALSE;
6475 EINA_LIST_FOREACH(it->item->items, l, it2)
6476 if (it2) _item_contract_emit(it2);
6480 _item_tree_effect_before(Elm_Gen_Item *it)
6485 EINA_LIST_FOREACH(it->item->items, l, it2)
6487 if (it2->parent && (it == it2->parent))
6490 it2->item->tree_effect_hideme = EINA_TRUE;
6491 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6492 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6493 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6494 _item_contract_emit(it2);
6497 return ECORE_CALLBACK_CANCEL;
6501 _item_tree_effect(Widget_Data *wd, int y)
6503 Elm_Gen_Item *it = NULL, *expanded_next_it;
6505 expanded_next_it = wd->expanded_next_item;
6507 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6509 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6512 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6513 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6514 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6516 if (!it->item->tree_effect_finished)
6518 edje_object_signal_emit(VIEW(it), "flip_item", "");
6519 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6520 it->item->tree_effect_finished = EINA_TRUE;
6523 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6526 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6528 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6531 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6532 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6534 if (!it->item->tree_effect_finished)
6536 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6537 it->item->tree_effect_finished = EINA_TRUE;
6542 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6548 _item_tree_effect_finish(Widget_Data *wd)
6550 Elm_Gen_Item *it = NULL;
6553 if (wd->tree_effect_animator)
6555 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6556 _item_subitems_clear(wd->expanded_item);
6557 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6559 it->item->tree_effect_finished = EINA_TRUE;
6560 it->item->old_scrl_y = it->item->scrl_y;
6561 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6562 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6565 _item_auto_scroll(wd);
6566 evas_object_lower(wd->alpha_bg);
6567 evas_object_hide(wd->alpha_bg);
6568 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6569 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6571 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6572 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6573 evas_object_smart_changed(wd->pan_smart);
6575 wd->tree_effect_animator = NULL;
6579 _tree_effect_animator_cb(void *data)
6581 Widget_Data *wd = data;
6582 if (!wd) return ECORE_CALLBACK_CANCEL;
6583 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6584 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6586 double effect_duration = 0.3, t;
6587 int y = 0, dy = 0, dh = 0;
6588 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6591 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6592 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6593 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6594 if (t > effect_duration) end = EINA_TRUE;
6596 // Below while statement is needed, when the genlist is resized.
6597 it2 = wd->expanded_item;
6600 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6601 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6602 cvx, cvy, cvw, cvh));
6603 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6606 if (wd->expanded_next_item)
6608 expanded_next_it = wd->expanded_next_item;
6611 EINA_LIST_FOREACH(wd->move_items, l, it)
6613 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6615 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6616 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6617 expanded_next_it->item->scrl_y = cvy + cvh;
6619 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6620 cvy + cvh : expanded_next_it->item->scrl_y) -
6621 expanded_next_it->item->old_scrl_y;
6623 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6625 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6626 expanded_next_it->item->old_scrl_y = cvy + cvh;
6628 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6630 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6632 expanded_next_it->item->old_scrl_y = cvy + cvh;
6636 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6637 expanded_next_it->item->old_scrl_y;
6641 if (t <= effect_duration)
6643 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6651 if (!it->realized && !it->item->queued)
6652 _item_realize(it, in, 0);
6655 if (it != expanded_next_it)
6657 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6661 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6662 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6665 _item_tree_effect(wd, y);
6669 int expanded_item_num = 0;
6672 if (wd->expanded_item)
6673 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6678 expanded_item_num++;
6679 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6685 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6686 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6688 if (!it->item->tree_effect_finished)
6690 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6692 edje_object_signal_emit(VIEW(it), "flip_item", "");
6693 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6694 it->item->tree_effect_finished = EINA_TRUE;
6698 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6704 _item_tree_effect_finish(wd);
6705 return ECORE_CALLBACK_CANCEL;
6707 return ECORE_CALLBACK_RENEW;