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 *mode_texts, *mode_contents, *mode_states, *mode_content_objs;
56 Eina_List *edit_texts, *edit_contents, *edit_states, *edit_content_objs;
57 Ecore_Timer *swipe_timer;
58 Evas_Coord scrl_x, scrl_y, old_scrl_y;
61 Evas_Object *mode_view;
67 Eina_Bool want_realize : 1;
68 Eina_Bool expanded : 1;
69 Eina_Bool mincalcd : 1;
72 Eina_Bool updateme : 1;
73 Eina_Bool nocache : 1; /* do not use cache for this item */
74 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
75 Eina_Bool stacking_even : 1;
76 Eina_Bool nostacking : 1;
77 Eina_Bool move_effect_enabled : 1;
78 Eina_Bool decorate_mode_item_realized : 1;
79 Eina_Bool tree_effect_finished : 1; /* tree effect */
90 Evas_Coord x, y, w, h, minw, minh;
92 int item_position_stamp;
94 Eina_Bool position_update : 1;
95 Eina_Bool want_unrealize : 1;
96 Eina_Bool realized : 1;
97 Eina_Bool changed : 1;
98 Eina_Bool updateme : 1;
99 Eina_Bool changeme : 1;
100 Eina_Bool showme : 1;
101 Eina_Bool must_recalc : 1;
108 Evas_Object *base_view, *spacer;
110 const char *item_style; // it->itc->item_style
111 Eina_Bool tree : 1; // it->group
113 Eina_Bool selected : 1; // it->selected
114 Eina_Bool disabled : 1; // it->disabled
115 Eina_Bool expanded : 1; // it->item->expanded
118 static const char *widtype = NULL;
119 static void _item_cache_zero(Widget_Data *wd);
120 static void _del_hook(Evas_Object *obj);
121 static void _mirrored_set(Evas_Object *obj,
123 static void _theme_hook(Evas_Object *obj);
124 static void _show_region_hook(void *data,
126 static void _sizing_eval(Evas_Object *obj);
127 static void _item_realize(Elm_Gen_Item *it,
130 static void _item_unrealize_cb(Elm_Gen_Item *it);
131 static void _item_block_unrealize(Item_Block *itb);
132 static void _calc_job(void *data);
133 static void _on_focus_hook(void *data,
135 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
136 static void _changed_job(void *data);
137 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
138 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
139 static Eina_Bool _item_single_select_up(Widget_Data *wd);
140 static Eina_Bool _item_single_select_down(Widget_Data *wd);
141 static Eina_Bool _event_hook(Evas_Object *obj,
143 Evas_Callback_Type type,
145 static void _signal_emit_hook(Evas_Object *obj,
146 const char *emission,
148 static Eina_Bool _deselect_all_items(Widget_Data *wd);
149 static void _pan_calculate(Evas_Object *obj);
150 static void _pan_max_get(Evas_Object *obj,
153 static void _item_position(Elm_Gen_Item *it,
157 static void _mode_item_realize(Elm_Gen_Item *it);
158 static void _mode_item_unrealize(Elm_Gen_Item *it);
159 static void _item_mode_set(Elm_Gen_Item *it);
160 static void _item_mode_unset(Widget_Data *wd);
161 static void _decorate_mode_item_position(Elm_Gen_Item *it, int itx, int ity);
162 static void _decorate_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
163 static void _decorate_mode_item_unrealize(Elm_Gen_Item *it);
166 static void _group_items_recalc(void *data);
168 static void _item_move_after(Elm_Gen_Item *it,
169 Elm_Gen_Item *after);
170 static void _item_move_before(Elm_Gen_Item *it,
171 Elm_Gen_Item *before);
172 static void _item_auto_scroll(Widget_Data *wd);
173 static void _elm_genlist_clear(Evas_Object *obj,
175 static void _pan_child_size_get(Evas_Object *obj,
178 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
179 static void _item_contract_emit(Elm_Gen_Item *it);
180 static int _item_tree_effect_before(Elm_Gen_Item *it);
181 static void _item_tree_effect(Widget_Data *wd, int y);
182 static void _item_tree_effect_finish(Widget_Data *wd);
183 static Eina_Bool _item_moving_effect_timer_cb(void *data);
185 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
187 static const char SIG_ACTIVATED[] = "activated";
188 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
189 static const char SIG_SELECTED[] = "selected";
190 static const char SIG_UNSELECTED[] = "unselected";
191 static const char SIG_EXPANDED[] = "expanded";
192 static const char SIG_CONTRACTED[] = "contracted";
193 static const char SIG_EXPAND_REQUEST[] = "expand,request";
194 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
195 static const char SIG_REALIZED[] = "realized";
196 static const char SIG_UNREALIZED[] = "unrealized";
197 static const char SIG_DRAG_START_UP[] = "drag,start,up";
198 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
199 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
200 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
201 static const char SIG_DRAG_STOP[] = "drag,stop";
202 static const char SIG_DRAG[] = "drag";
203 static const char SIG_LONGPRESSED[] = "longpressed";
204 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
205 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
206 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
207 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
208 static const char SIG_EDGE_TOP[] = "edge,top";
209 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
210 static const char SIG_EDGE_LEFT[] = "edge,left";
211 static const char SIG_EDGE_RIGHT[] = "edge,right";
212 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
213 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
214 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
215 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
216 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
217 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
218 static const char SIG_SWIPE[] = "swipe";
219 static const char SIG_MOVED[] = "moved";
220 static const char SIG_INDEX_UPDATE[] = "index,update";
221 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
223 static const Evas_Smart_Cb_Description _signals[] = {
224 {SIG_CLICKED_DOUBLE, ""},
227 {SIG_UNSELECTED, ""},
229 {SIG_CONTRACTED, ""},
230 {SIG_EXPAND_REQUEST, ""},
231 {SIG_CONTRACT_REQUEST, ""},
233 {SIG_UNREALIZED, ""},
234 {SIG_DRAG_START_UP, ""},
235 {SIG_DRAG_START_DOWN, ""},
236 {SIG_DRAG_START_LEFT, ""},
237 {SIG_DRAG_START_RIGHT, ""},
240 {SIG_LONGPRESSED, ""},
241 {SIG_SCROLL_ANIM_START, ""},
242 {SIG_SCROLL_ANIM_STOP, ""},
243 {SIG_SCROLL_DRAG_START, ""},
244 {SIG_SCROLL_DRAG_STOP, ""},
246 {SIG_EDGE_BOTTOM, ""},
248 {SIG_EDGE_RIGHT, ""},
249 {SIG_MULTI_SWIPE_LEFT, ""},
250 {SIG_MULTI_SWIPE_RIGHT, ""},
251 {SIG_MULTI_SWIPE_UP, ""},
252 {SIG_MULTI_SWIPE_DOWN, ""},
253 {SIG_MULTI_PINCH_OUT, ""},
254 {SIG_MULTI_PINCH_IN, ""},
257 {SIG_TREE_EFFECT_FINISHED, ""},
262 #undef ELM_CHECK_WIDTYPE
263 #define ELM_CHECK_WIDTYPE(obj, widtype) \
264 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
265 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
266 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
267 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
268 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
270 static const char *_gengrid = NULL;
271 static const char *_genlist = NULL;
273 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
275 elm_genlist_type_check(const Evas_Object *obj,
278 const char *provided, *expected = "(unknown)";
279 static int abort_on_warn = -1;
280 provided = elm_widget_type_get(obj);
281 if (!_genlist) _genlist = eina_stringshare_add("genlist");
282 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
283 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
285 if ((!provided) || (!provided[0]))
287 provided = evas_object_type_get(obj);
288 if ((!provided) || (!provided[0]))
289 provided = "(unknown)";
291 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
292 if (abort_on_warn == -1)
294 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
295 else abort_on_warn = 0;
297 if (abort_on_warn == 1) abort();
302 _event_hook(Evas_Object *obj,
303 Evas_Object *src __UNUSED__,
304 Evas_Callback_Type type,
307 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
308 Evas_Event_Key_Down *ev = event_info;
309 Widget_Data *wd = elm_widget_data_get(obj);
310 Evas_Coord pan_max_x = 0, pan_max_y = 0;
311 if (!wd) return EINA_FALSE;
312 if (!wd->items) return EINA_FALSE;
313 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
314 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
316 Elm_Object_Item *it = NULL;
319 Evas_Coord step_x = 0;
320 Evas_Coord step_y = 0;
323 Evas_Coord page_x = 0;
324 Evas_Coord page_y = 0;
326 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
327 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
328 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
329 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
331 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
335 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
339 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
341 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
342 (_item_multi_select_up(wd)))
343 || (_item_single_select_up(wd)))
345 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
351 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
353 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
354 (_item_multi_select_down(wd)))
355 || (_item_single_select_down(wd)))
357 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
363 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
365 it = elm_genlist_first_item_get(obj);
366 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
367 elm_genlist_item_selected_set(it, EINA_TRUE);
368 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
371 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
373 it = elm_genlist_last_item_get(obj);
374 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
375 elm_genlist_item_selected_set(it, EINA_TRUE);
376 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
379 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
382 y -= -(page_y * v_h) / 100;
386 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
389 y += -(page_y * v_h) / 100;
393 else if (!strcmp(ev->keyname, "Escape"))
395 if (!_deselect_all_items(wd)) return EINA_FALSE;
396 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
399 else if (((!strcmp(ev->keyname, "Return")) ||
400 (!strcmp(ev->keyname, "KP_Enter")) ||
401 (!strcmp(ev->keyname, "space")))
402 && (!wd->multi) && (wd->selected))
404 it = elm_genlist_selected_item_get(obj);
405 elm_genlist_item_expanded_set(it,
406 !elm_genlist_item_expanded_get(it));
407 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
409 else return EINA_FALSE;
411 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
412 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
414 if (x > pan_max_x) x = pan_max_x;
416 if (y > pan_max_y) y = pan_max_y;
417 elm_smart_scroller_child_pos_set(wd->scr, x, y);
422 _deselect_all_items(Widget_Data *wd)
424 if (!wd->selected) return EINA_FALSE;
426 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
432 _item_multi_select_up(Widget_Data *wd)
434 if (!wd->selected) return EINA_FALSE;
435 if (!wd->multi) return EINA_FALSE;
437 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
438 if (!prev) return EINA_TRUE;
440 if (elm_genlist_item_selected_get(prev))
442 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
443 wd->last_selected_item = prev;
444 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
448 elm_genlist_item_selected_set(prev, EINA_TRUE);
449 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
455 _item_multi_select_down(Widget_Data *wd)
457 if (!wd->selected) return EINA_FALSE;
458 if (!wd->multi) return EINA_FALSE;
460 Elm_Object_Item *next;
461 next = elm_genlist_item_next_get(wd->last_selected_item);
462 if (!next) return EINA_TRUE;
464 if (elm_genlist_item_selected_get(next))
466 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
467 wd->last_selected_item = next;
468 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
472 elm_genlist_item_selected_set(next, EINA_TRUE);
473 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
479 _item_single_select_up(Widget_Data *wd)
484 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
485 while ((prev) && (prev->generation < wd->generation))
486 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
488 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
490 if (!prev) return EINA_FALSE;
492 _deselect_all_items(wd);
494 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
495 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
500 _item_single_select_down(Widget_Data *wd)
505 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
506 while ((next) && (next->generation < wd->generation))
507 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
509 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
511 if (!next) return EINA_FALSE;
513 _deselect_all_items(wd);
515 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
516 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
521 _on_focus_hook(void *data __UNUSED__,
524 Widget_Data *wd = elm_widget_data_get(obj);
526 if (elm_widget_focus_get(obj))
528 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
529 evas_object_focus_set(wd->obj, EINA_TRUE);
530 if ((wd->items) && (wd->selected) && (!wd->last_selected_item))
531 wd->last_selected_item = eina_list_data_get(wd->selected);
535 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
536 evas_object_focus_set(wd->obj, EINA_FALSE);
541 _del_hook(Evas_Object *obj)
543 Widget_Data *wd = elm_widget_data_get(obj);
545 _item_cache_zero(wd);
546 if (wd->calc_job) ecore_job_del(wd->calc_job);
547 if (wd->update_job) ecore_job_del(wd->update_job);
548 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
549 if (wd->changed_job) ecore_job_del(wd->changed_job);
550 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
551 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
552 if (wd->decorate_type) eina_stringshare_del(wd->decorate_type);
553 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
558 _del_pre_hook(Evas_Object *obj)
560 Widget_Data *wd = elm_widget_data_get(obj);
562 if (wd->decorate_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
563 elm_genlist_clear(obj);
564 evas_object_del(wd->pan_smart);
565 wd->pan_smart = NULL;
569 _mirrored_set(Evas_Object *obj,
572 Widget_Data *wd = elm_widget_data_get(obj);
574 _item_cache_zero(wd);
575 elm_smart_scroller_mirrored_set(wd->scr, rtl);
579 _theme_hook(Evas_Object *obj)
581 Widget_Data *wd = elm_widget_data_get(obj);
584 evas_event_freeze(evas_object_evas_get(wd->obj));
585 _item_cache_zero(wd);
586 _elm_widget_mirrored_reload(obj);
587 _mirrored_set(obj, elm_widget_mirrored_get(obj));
588 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
589 elm_widget_style_get(obj));
590 //edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
591 wd->item_width = wd->item_height = 0;
592 wd->group_item_width = wd->group_item_height = 0;
593 wd->minw = wd->minh = wd->realminw = 0;
594 EINA_INLIST_FOREACH(wd->blocks, itb)
599 if (itb->realized) _item_block_unrealize(itb);
600 EINA_LIST_FOREACH(itb->items, l, it)
601 it->item->mincalcd = EINA_FALSE;
603 itb->changed = EINA_TRUE;
605 if (wd->calc_job) ecore_job_del(wd->calc_job);
606 wd->calc_job = ecore_job_add(_calc_job, wd);
608 evas_event_thaw(evas_object_evas_get(wd->obj));
609 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
613 _show_region_hook(void *data,
616 Widget_Data *wd = elm_widget_data_get(data);
617 Evas_Coord x, y, w, h;
619 elm_widget_show_region_get(obj, &x, &y, &w, &h);
620 //x & y are screen coordinates, Add with pan coordinates
623 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
627 _translate_hook(Evas_Object *obj)
629 evas_object_smart_callback_call(obj, "language,changed", NULL);
633 _sizing_eval(Evas_Object *obj)
635 Widget_Data *wd = elm_widget_data_get(obj);
636 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
637 Evas_Coord vmw = 0, vmh = 0;
640 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
641 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
643 edje_object_size_min_calc
644 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
646 if (wd->mode == ELM_LIST_COMPRESS)
650 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
651 if ((vw != 0) && (vw != wd->prev_viewport_w))
655 wd->prev_viewport_w = vw;
656 EINA_INLIST_FOREACH(wd->blocks, itb)
658 itb->must_recalc = EINA_TRUE;
660 if (wd->calc_job) ecore_job_del(wd->calc_job);
661 wd->calc_job = ecore_job_add(_calc_job, wd);
663 edje_object_size_min_calc
664 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
668 else if (wd->mode == ELM_LIST_LIMIT)
679 evas_object_size_hint_min_set(obj, minw, minh);
680 evas_object_size_hint_max_set(obj, maxw, maxh);
684 _signal_emit_hook(Evas_Object *obj,
685 const char *emission,
688 Widget_Data *wd = elm_widget_data_get(obj);
689 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
694 _item_highlight(Elm_Gen_Item *it)
696 const char *selectraise;
697 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
698 (!it->wd->highlight) ||
699 (it->generation < it->wd->generation) ||
700 (it->highlighted) || elm_widget_item_disabled_get(it) ||
701 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->mode_view) ||
702 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
704 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
705 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,selected", "elm");
706 selectraise = edje_object_data_get(VIEW(it), "selectraise");
707 if ((selectraise) && (!strcmp(selectraise, "on")))
709 if (it->edit_obj) evas_object_raise(it->edit_obj);
710 else evas_object_raise(VIEW(it));
713 if ((it->item->group_item) && (it->item->group_item->realized))
714 evas_object_raise(it->item->VIEW(group_item));
717 it->highlighted = EINA_TRUE;
721 _item_unhighlight(Elm_Gen_Item *it)
723 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
724 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
725 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,unselected", "elm");
726 if (!it->item->nostacking)
728 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
730 if (it->edit_obj) evas_object_lower(it->edit_obj);
731 else evas_object_lower(VIEW(it));
735 if (it->edit_obj) evas_object_raise(it->edit_obj);
736 else evas_object_raise(VIEW(it));
739 it->highlighted = EINA_FALSE;
743 _item_block_position_update(Eina_Inlist *list, int idx)
747 EINA_INLIST_FOREACH(list, tmp)
749 tmp->position = idx++;
750 tmp->position_update = EINA_TRUE;
755 _item_position_update(Eina_List *list, int idx)
760 EINA_LIST_FOREACH(list, l, it)
762 it->position = idx++;
763 it->position_update = EINA_TRUE;
768 _item_block_del(Elm_Gen_Item *it)
771 Item_Block *itb = it->item->block;
772 Eina_Bool block_changed;
774 itb->items = eina_list_remove(itb->items, it);
776 itb->changed = EINA_TRUE;
777 if (!it->wd->reorder_deleted)
779 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
780 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
784 il = EINA_INLIST_GET(itb);
785 Item_Block *itbn = (Item_Block *)(il->next);
787 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
790 _item_block_position_update(il->next, itb->position);
791 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
794 if (itbn) itbn->changed = EINA_TRUE;
798 if (itb->count < itb->wd->max_items_per_block/2)
800 il = EINA_INLIST_GET(itb);
801 Item_Block *itbp = (Item_Block *)(il->prev);
802 Item_Block *itbn = (Item_Block *)(il->next);
803 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
807 EINA_LIST_FREE(itb->items, it2)
809 it2->item->block = itbp;
810 itbp->items = eina_list_append(itbp->items, it2);
812 itbp->changed = EINA_TRUE;
814 _item_block_position_update(EINA_INLIST_GET(itb)->next,
816 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
817 EINA_INLIST_GET(itb));
819 block_changed = EINA_TRUE;
821 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
825 Eina_List *last = eina_list_last(itb->items);
826 Elm_Gen_Item *it2 = last->data;
828 it2->item->block = itbn;
829 itb->items = eina_list_remove_list(itb->items, last);
830 itbn->items = eina_list_prepend(itbn->items, it2);
832 itbn->changed = EINA_TRUE;
834 _item_block_position_update(EINA_INLIST_GET(itb)->next,
837 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
839 block_changed = EINA_TRUE;
845 it->wd->pan_changed = EINA_TRUE;
846 evas_object_smart_changed(it->wd->pan_smart);
847 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
848 it->wd->calc_job = NULL;
853 _item_subitems_clear(Elm_Gen_Item *it)
855 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
856 Eina_List *tl = NULL, *l;
857 Elm_Object_Item *it2;
859 EINA_LIST_FOREACH(it->item->items, l, it2)
860 tl = eina_list_append(tl, it2);
861 EINA_LIST_FREE(tl, it2)
862 elm_object_item_del(it2);
866 _item_del(Elm_Gen_Item *it)
868 Evas_Object *obj = WIDGET(it);
870 evas_event_freeze(evas_object_evas_get(obj));
871 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
872 if (it->wd->show_item == it) it->wd->show_item = NULL;
873 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
874 if (it->item->decorate_mode_item_realized) _decorate_mode_item_unrealize(it);
875 if (it->item->block) _item_block_del(it);
876 if (it->item->queued)
877 it->wd->queue = eina_list_remove(it->wd->queue, it);
878 if (it->wd->anchor_item == it)
880 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
881 if (!it->wd->anchor_item)
882 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
884 if (it->wd->expanded_item == it) it->wd->expanded_item = NULL;
886 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
887 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
888 _elm_genlist_item_del_serious(it);
889 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
890 evas_event_thaw(evas_object_evas_get(obj));
891 evas_event_thaw_eval(evas_object_evas_get(obj));
895 _clear_cb(Widget_Data *wd)
897 wd->anchor_item = NULL;
900 Item_Block *itb = (Item_Block *)(wd->blocks);
902 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
903 if (itb->items) eina_list_free(itb->items);
906 if (wd->queue_idle_enterer)
908 ecore_idle_enterer_del(wd->queue_idle_enterer);
909 wd->queue_idle_enterer = NULL;
911 if (wd->must_recalc_idler)
913 ecore_idler_del(wd->must_recalc_idler);
914 wd->must_recalc_idler = NULL;
916 if (wd->queue) wd->queue = eina_list_free(wd->queue);
917 if (wd->reorder_move_animator)
919 ecore_animator_del(wd->reorder_move_animator);
920 wd->reorder_move_animator = NULL;
922 wd->show_item = NULL;
923 wd->reorder_old_pan_y = 0;
927 _item_unselect(Elm_Gen_Item *it)
929 if ((it->generation < it->wd->generation) || (!it->selected)) return;
930 it->selected = EINA_FALSE;
931 it->wd->selected = eina_list_remove(it->wd->selected, it);
932 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
936 _mouse_move(void *data,
937 Evas *evas __UNUSED__,
941 Elm_Gen_Item *it = data;
942 Evas_Event_Mouse_Move *ev = event_info;
943 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
944 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
946 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
948 if (!it->wd->on_hold)
950 it->wd->on_hold = EINA_TRUE;
951 if ((!it->wd->wasselected) && (!it->flipped))
953 _item_unhighlight(it);
958 if (it->wd->multitouched)
960 it->wd->cur_x = ev->cur.canvas.x;
961 it->wd->cur_y = ev->cur.canvas.y;
964 if ((it->dragging) && (it->down))
966 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
969 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
970 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
971 if (abs((it->wd->history[it->wd->movements].x -
972 it->wd->history[0].x)) > 40)
973 it->wd->swipe = EINA_TRUE;
979 ecore_timer_del(it->long_timer);
980 it->long_timer = NULL;
982 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
985 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
989 ecore_timer_del(it->long_timer);
990 it->long_timer = NULL;
992 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
994 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
995 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
997 if (!it->wd->reorder_start_y)
998 it->wd->reorder_start_y = it->item->block->y + it->y;
1002 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
1003 y_pos = oy + oh - it->wd->reorder_it->item->h;
1008 _item_position(it, it->edit_obj, it->item->scrl_x, y_pos);
1010 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1012 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1013 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1017 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1018 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1019 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1020 x = ev->cur.canvas.x - x;
1021 y = ev->cur.canvas.y - y;
1024 if (adx < 0) adx = -dx;
1027 if (ady < 0) ady = -dy;
1030 if ((adx > minw) || (ady > minh))
1032 it->dragging = EINA_TRUE;
1035 ecore_timer_del(it->long_timer);
1036 it->long_timer = NULL;
1038 if ((!it->wd->wasselected) && (!it->flipped))
1040 _item_unhighlight(it);
1045 if ((ady > adx) && (!it->wd->drag_started))
1046 evas_object_smart_callback_call(WIDGET(it),
1047 SIG_DRAG_START_UP, it);
1051 evas_object_smart_callback_call(WIDGET(it),
1052 SIG_DRAG_START_LEFT, it);
1054 evas_object_smart_callback_call(WIDGET(it),
1055 SIG_DRAG_START_RIGHT, it);
1060 if ((ady > adx) && (!it->wd->drag_started))
1061 evas_object_smart_callback_call(WIDGET(it),
1062 SIG_DRAG_START_DOWN, it);
1066 evas_object_smart_callback_call(WIDGET(it),
1067 SIG_DRAG_START_LEFT, it);
1069 evas_object_smart_callback_call(WIDGET(it),
1070 SIG_DRAG_START_RIGHT, it);
1077 _long_press(void *data)
1079 Elm_Gen_Item *it = data, *it_tmp;
1080 Eina_List *list, *l;
1082 it->long_timer = NULL;
1083 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1084 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1085 return ECORE_CALLBACK_CANCEL;
1086 it->wd->longpressed = EINA_TRUE;
1087 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1088 if ((it->wd->reorder_mode) && (!it->group))
1090 it->wd->reorder_it = it;
1091 it->wd->reorder_start_y = 0;
1093 evas_object_raise(it->edit_obj);
1095 evas_object_raise(VIEW(it));
1097 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1098 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1100 list = elm_genlist_realized_items_get(it->wd->obj);
1101 EINA_LIST_FOREACH(list, l, it_tmp)
1103 if (it != it_tmp) _item_unselect(it_tmp);
1105 if (it->item->items)
1107 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
1109 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
1111 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
1113 return ECORE_CALLBACK_RENEW;
1117 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1119 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1120 return ECORE_CALLBACK_RENEW;
1123 if (!it->wd->decorate_mode)
1124 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1126 return ECORE_CALLBACK_CANCEL;
1130 _swipe(Elm_Gen_Item *it)
1135 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1136 elm_widget_item_disabled_get(it)) return;
1137 it->wd->swipe = EINA_FALSE;
1138 for (i = 0; i < it->wd->movements; i++)
1140 sum += it->wd->history[i].x;
1141 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1144 sum /= it->wd->movements;
1145 if (abs(sum - it->wd->history[0].x) <= 10) return;
1146 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1150 _swipe_cancel(void *data)
1152 Elm_Gen_Item *it = data;
1154 if (!it) return ECORE_CALLBACK_CANCEL;
1155 it->wd->swipe = EINA_FALSE;
1156 it->wd->movements = 0;
1157 return ECORE_CALLBACK_RENEW;
1161 _multi_cancel(void *data)
1163 Widget_Data *wd = data;
1165 if (!wd) return ECORE_CALLBACK_CANCEL;
1166 wd->multi_timeout = EINA_TRUE;
1167 return ECORE_CALLBACK_RENEW;
1171 _multi_touch_gesture_eval(void *data)
1173 Elm_Gen_Item *it = data;
1175 it->wd->multitouched = EINA_FALSE;
1176 if (it->wd->multi_timer)
1178 ecore_timer_del(it->wd->multi_timer);
1179 it->wd->multi_timer = NULL;
1181 if (it->wd->multi_timeout)
1183 it->wd->multi_timeout = EINA_FALSE;
1187 Evas_Coord minw = 0, minh = 0;
1188 Evas_Coord off_x, off_y, off_mx, off_my;
1190 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1191 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1192 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1193 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1194 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1196 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1198 if ((off_x + off_mx) > (off_y + off_my))
1200 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1201 evas_object_smart_callback_call(WIDGET(it),
1202 SIG_MULTI_SWIPE_RIGHT, it);
1203 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1204 evas_object_smart_callback_call(WIDGET(it),
1205 SIG_MULTI_SWIPE_LEFT, it);
1206 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1207 evas_object_smart_callback_call(WIDGET(it),
1208 SIG_MULTI_PINCH_OUT, it);
1210 evas_object_smart_callback_call(WIDGET(it),
1211 SIG_MULTI_PINCH_IN, it);
1215 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1216 evas_object_smart_callback_call(WIDGET(it),
1217 SIG_MULTI_SWIPE_DOWN, it);
1218 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1219 evas_object_smart_callback_call(WIDGET(it),
1220 SIG_MULTI_SWIPE_UP, it);
1221 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1222 evas_object_smart_callback_call(WIDGET(it),
1223 SIG_MULTI_PINCH_OUT, it);
1225 evas_object_smart_callback_call(WIDGET(it),
1226 SIG_MULTI_PINCH_IN, it);
1229 it->wd->multi_timeout = EINA_FALSE;
1233 _multi_down(void *data,
1234 Evas *evas __UNUSED__,
1235 Evas_Object *obj __UNUSED__,
1238 Elm_Gen_Item *it = data;
1239 Evas_Event_Multi_Down *ev = event_info;
1241 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1242 it->wd->multi_device = ev->device;
1243 it->wd->multi_down = EINA_TRUE;
1244 it->wd->multitouched = EINA_TRUE;
1245 it->wd->prev_mx = ev->canvas.x;
1246 it->wd->prev_my = ev->canvas.y;
1247 if (!it->wd->wasselected)
1249 _item_unhighlight(it);
1252 it->wd->wasselected = EINA_FALSE;
1253 it->wd->longpressed = EINA_FALSE;
1256 ecore_timer_del(it->long_timer);
1257 it->long_timer = NULL;
1261 it->dragging = EINA_FALSE;
1262 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1264 if (it->item->swipe_timer)
1266 ecore_timer_del(it->item->swipe_timer);
1267 it->item->swipe_timer = NULL;
1269 if (it->wd->on_hold)
1271 it->wd->swipe = EINA_FALSE;
1272 it->wd->movements = 0;
1273 it->wd->on_hold = EINA_FALSE;
1278 _multi_up(void *data,
1279 Evas *evas __UNUSED__,
1280 Evas_Object *obj __UNUSED__,
1283 Elm_Gen_Item *it = data;
1284 Evas_Event_Multi_Up *ev = event_info;
1286 if (it->wd->multi_device != ev->device) return;
1287 it->wd->multi_device = 0;
1288 it->wd->multi_down = EINA_FALSE;
1289 if (it->wd->mouse_down) return;
1290 _multi_touch_gesture_eval(data);
1294 _multi_move(void *data,
1295 Evas *evas __UNUSED__,
1296 Evas_Object *obj __UNUSED__,
1299 Elm_Gen_Item *it = data;
1300 Evas_Event_Multi_Move *ev = event_info;
1302 if (it->wd->multi_device != ev->device) return;
1303 it->wd->cur_mx = ev->cur.canvas.x;
1304 it->wd->cur_my = ev->cur.canvas.y;
1308 _mouse_down(void *data,
1309 Evas *evas __UNUSED__,
1313 Elm_Gen_Item *it = data;
1314 Evas_Event_Mouse_Down *ev = event_info;
1319 if (ev->button != 1) return;
1322 EINA_LIST_FOREACH(it->content_objs, l, iobj)
1324 elm_widget_tree_unfocusable_set(iobj, EINA_FALSE);
1326 it->can_focus = EINA_TRUE;
1328 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1330 it->wd->on_hold = EINA_TRUE;
1333 it->down = EINA_TRUE;
1334 it->dragging = EINA_FALSE;
1335 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1336 it->dx = ev->canvas.x - x;
1337 it->dy = ev->canvas.y - y;
1338 it->wd->mouse_down = EINA_TRUE;
1339 if (!it->wd->multitouched)
1341 it->wd->prev_x = ev->canvas.x;
1342 it->wd->prev_y = ev->canvas.y;
1343 it->wd->multi_timeout = EINA_FALSE;
1344 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1345 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1347 it->wd->longpressed = EINA_FALSE;
1348 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1349 else it->wd->on_hold = EINA_FALSE;
1350 if (it->wd->on_hold) return;
1351 it->wd->wasselected = it->selected;
1352 _item_highlight(it);
1353 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1354 if ((!elm_widget_item_disabled_get(it)) &&
1355 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1357 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1358 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1360 if (it->long_timer) ecore_timer_del(it->long_timer);
1361 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1362 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1364 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1367 it->long_timer = NULL;
1368 it->wd->swipe = EINA_FALSE;
1369 it->wd->movements = 0;
1373 _mouse_up(void *data,
1374 Evas *evas __UNUSED__,
1375 Evas_Object *obj __UNUSED__,
1378 Elm_Gen_Item *it = data;
1379 Evas_Event_Mouse_Up *ev = event_info;
1380 Eina_Bool dragged = EINA_FALSE;
1382 if (ev->button != 1) return;
1383 it->down = EINA_FALSE;
1384 it->wd->mouse_down = EINA_FALSE;
1385 if (it->wd->multitouched)
1387 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1388 if (it->wd->multi_down) return;
1389 _multi_touch_gesture_eval(data);
1392 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1393 else it->wd->on_hold = EINA_FALSE;
1396 ecore_timer_del(it->long_timer);
1397 it->long_timer = NULL;
1401 it->dragging = EINA_FALSE;
1402 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1405 if (it->item->swipe_timer)
1407 ecore_timer_del(it->item->swipe_timer);
1408 it->item->swipe_timer = NULL;
1410 if (it->wd->multi_timer)
1412 ecore_timer_del(it->wd->multi_timer);
1413 it->wd->multi_timer = NULL;
1414 it->wd->multi_timeout = EINA_FALSE;
1416 if (it->wd->on_hold)
1418 if (it->wd->swipe) _swipe(data);
1419 it->wd->longpressed = EINA_FALSE;
1420 it->wd->on_hold = EINA_FALSE;
1423 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1425 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1427 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1429 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1430 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1432 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1436 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1437 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1439 it->wd->reorder_deleted = EINA_FALSE;
1440 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1441 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1442 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1443 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1445 if (it->wd->longpressed)
1447 it->wd->longpressed = EINA_FALSE;
1448 if ((!it->wd->wasselected) && (!it->flipped))
1450 _item_unhighlight(it);
1453 it->wd->wasselected = EINA_FALSE;
1458 if (it->want_unrealize)
1460 _elm_genlist_item_unrealize(it, EINA_FALSE);
1461 if (it->item->block->want_unrealize)
1462 _item_block_unrealize(it->item->block);
1465 if (elm_widget_item_disabled_get(it) || (dragged) ||
1466 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1468 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1473 _item_highlight(it);
1478 _item_unhighlight(it);
1486 Widget_Data *wd = it->wd;
1489 while (wd->selected)
1491 _item_unhighlight(wd->selected->data);
1492 _item_unselect(wd->selected->data);
1498 const Eina_List *l, *l_next;
1501 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1504 _item_unhighlight(it2);
1505 _item_unselect(it2);
1507 //_item_highlight(it);
1510 _item_highlight(it);
1516 _mouse_down_scroller(void *data,
1517 Evas *evas __UNUSED__,
1518 Evas_Object *obj __UNUSED__,
1519 void *event_info __UNUSED__)
1521 Widget_Data *wd = elm_widget_data_get(data);
1524 wd->drag_started = EINA_FALSE;
1528 _mouse_up_scroller(void *data,
1529 Evas *evas __UNUSED__,
1530 Evas_Object *obj __UNUSED__,
1531 void *event_info __UNUSED__)
1533 Widget_Data *wd = elm_widget_data_get(data);
1536 wd->drag_started = EINA_FALSE;
1540 _mouse_move_scroller(void *data,
1541 Evas *evas __UNUSED__,
1542 Evas_Object *obj __UNUSED__,
1545 Widget_Data *wd = elm_widget_data_get(data);
1546 Evas_Event_Mouse_Move *ev = event_info;
1547 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
1550 if (wd->drag_started) return;
1552 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1553 dx = ev->cur.canvas.x - ev->prev.canvas.x;
1554 dy = ev->cur.canvas.y - ev->prev.canvas.y;
1557 if (adx < 0) adx = -dx;
1558 if (ady < 0) ady = -dy;
1559 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
1563 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
1564 wd->drag_started = EINA_TRUE;
1568 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
1569 wd->drag_started = EINA_TRUE;
1575 _signal_expand_toggle(void *data,
1576 Evas_Object *obj __UNUSED__,
1577 const char *emission __UNUSED__,
1578 const char *source __UNUSED__)
1580 Elm_Gen_Item *it = data;
1582 if (it->item->expanded)
1583 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1585 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1589 _signal_expand(void *data,
1590 Evas_Object *obj __UNUSED__,
1591 const char *emission __UNUSED__,
1592 const char *source __UNUSED__)
1594 Elm_Gen_Item *it = data;
1596 if (!it->item->expanded)
1597 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1601 _signal_contract(void *data,
1602 Evas_Object *obj __UNUSED__,
1603 const char *emission __UNUSED__,
1604 const char *source __UNUSED__)
1606 Elm_Gen_Item *it = data;
1608 if (it->item->expanded)
1609 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1613 _scr_hold_timer_cb(void *data)
1615 if (!data) return ECORE_CALLBACK_CANCEL;
1616 Widget_Data *wd = data;
1617 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1618 wd->scr_hold_timer = NULL;
1619 return ECORE_CALLBACK_CANCEL;
1623 _mode_finished_signal_cb(void *data,
1625 const char *emission __UNUSED__,
1626 const char *source __UNUSED__)
1630 Elm_Gen_Item *it = data;
1631 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1633 Evas *te = evas_object_evas_get(obj);
1635 evas_event_freeze(te);
1636 it->item->nocache_once = EINA_FALSE;
1637 _mode_item_unrealize(it);
1638 //FIXME: group raise
1640 if (it->item->group_item)
1641 evas_object_raise(it->item->VIEW(group_item));
1643 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_type);
1644 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1645 evas_event_thaw(te);
1646 evas_event_thaw_eval(te);
1650 _item_cache_clean(Widget_Data *wd)
1652 evas_event_freeze(evas_object_evas_get(wd->obj));
1653 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1657 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1658 wd->item_cache = eina_inlist_remove(wd->item_cache,
1659 wd->item_cache->last);
1660 wd->item_cache_count--;
1661 if (itc->spacer) evas_object_del(itc->spacer);
1662 if (itc->base_view) evas_object_del(itc->base_view);
1663 eina_stringshare_del(itc->item_style);
1666 evas_event_thaw(evas_object_evas_get(wd->obj));
1667 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1671 _item_cache_zero(Widget_Data *wd)
1673 int pmax = wd->item_cache_max;
1674 wd->item_cache_max = 0;
1675 _item_cache_clean(wd);
1676 wd->item_cache_max = pmax;
1680 _item_cache_add(Elm_Gen_Item *it)
1684 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1685 if (it->wd->item_cache_max <= 0)
1687 evas_object_del(VIEW(it));
1689 evas_object_del(it->spacer);
1691 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1692 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1696 it->wd->item_cache_count++;
1697 itc = calloc(1, sizeof(Item_Cache));
1700 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1701 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1704 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1705 EINA_INLIST_GET(itc));
1706 itc->spacer = it->spacer;
1708 itc->base_view = VIEW(it);
1710 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1711 evas_object_hide(itc->base_view);
1712 evas_object_move(itc->base_view, -9999, -9999);
1713 itc->item_style = eina_stringshare_add(it->itc->item_style);
1714 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1715 itc->selected = it->selected;
1716 itc->disabled = elm_widget_item_disabled_get(it);
1717 itc->expanded = it->item->expanded;
1720 ecore_timer_del(it->long_timer);
1721 it->long_timer = NULL;
1723 if (it->item->swipe_timer)
1725 ecore_timer_del(it->item->swipe_timer);
1726 it->item->swipe_timer = NULL;
1728 // FIXME: other callbacks?
1729 edje_object_signal_callback_del_full(itc->base_view,
1730 "elm,action,expand,toggle",
1731 "elm", _signal_expand_toggle, it);
1732 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1734 _signal_expand, it);
1735 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1736 "elm", _signal_contract, it);
1737 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1739 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1741 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1743 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1745 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1747 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1749 _item_cache_clean(it->wd);
1750 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1751 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1755 _item_cache_find(Elm_Gen_Item *it)
1760 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1761 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1763 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1765 if ((itc->tree == tree) &&
1766 (((!it->itc->item_style) && (!itc->item_style)) ||
1767 (it->itc->item_style && itc->item_style &&
1768 (!strcmp(it->itc->item_style, itc->item_style)))))
1770 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1771 EINA_INLIST_GET(itc));
1772 it->wd->item_cache_count--;
1780 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1782 if (it->position_update || it->item->block->position_update)
1784 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1785 it->position_update = EINA_FALSE;
1790 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1792 if (!it->item->nostacking)
1794 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1796 if (it->edit_obj) evas_object_lower(it->edit_obj);
1797 else evas_object_lower(VIEW(it));
1801 if (it->edit_obj) evas_object_raise(it->edit_obj);
1802 else evas_object_raise(VIEW(it));
1806 if (it->item->order_num_in & 0x1)
1808 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1809 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,odd", "elm");
1813 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1814 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,even", "elm");
1819 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1823 if (it->selected != itc->selected)
1827 edje_object_signal_emit(VIEW(it),
1828 "elm,state,selected", "elm");
1831 edje_object_signal_emit(it->edit_obj,
1832 "elm,state,selected", "elm");
1835 if (elm_widget_item_disabled_get(it) != itc->disabled)
1837 if (elm_widget_item_disabled_get(it))
1838 edje_object_signal_emit(VIEW(it),
1839 "elm,state,disabled", "elm");
1841 edje_object_signal_emit(it->edit_obj,
1842 "elm,state,disabled", "elm");
1844 if (it->item->expanded != itc->expanded)
1846 if (it->item->expanded)
1847 edje_object_signal_emit(VIEW(it),
1848 "elm,state,expanded", "elm");
1850 edje_object_signal_emit(it->edit_obj,
1851 "elm,state,expanded", "elm");
1858 edje_object_signal_emit(VIEW(it),
1859 "elm,state,selected", "elm");
1861 edje_object_signal_emit(it->edit_obj,
1862 "elm,state,selected", "elm");
1864 if (elm_widget_item_disabled_get(it))
1866 edje_object_signal_emit(VIEW(it),
1867 "elm,state,disabled", "elm");
1869 edje_object_signal_emit(it->edit_obj,
1870 "elm,state,disabled", "elm");
1872 if (it->item->expanded)
1874 edje_object_signal_emit(VIEW(it),
1875 "elm,state,expanded", "elm");
1877 edje_object_signal_emit(it->edit_obj,
1878 "elm,state,expanded", "elm");
1884 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1886 Elm_Gen_Item *it = data;
1887 if (it) it->defer_unrealize = EINA_TRUE;
1891 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1893 Elm_Gen_Item *it = data;
1894 if (it) it->defer_unrealize = EINA_FALSE;
1899 _item_mode_content_realize(Elm_Gen_Item *it,
1900 Evas_Object *target,
1903 Eina_List **contents_list,
1904 const char *contents_part)
1907 Eina_List *res = NULL;
1909 if (it->itc->func.content_get)
1914 *source = elm_widget_stringlist_get(edje_object_data_get(target, contents_part));
1915 if (parts && (eina_list_count(*source) != eina_list_count(*contents_list)))
1916 res = *contents_list;
1917 EINA_LIST_FOREACH(*source, l, key)
1919 if (parts && fnmatch(parts, key, FNM_PERIOD))
1922 Evas_Object *ic = it->itc->func.content_get
1923 ((void *)it->base.data, WIDGET(it), l->data);
1927 res = eina_list_append(res, ic);
1928 edje_object_part_swallow(target, key, ic);
1929 evas_object_show(ic);
1930 elm_widget_sub_object_add(WIDGET(it), ic);
1931 if (it->item->mode_view || it->wd->decorate_mode)
1933 if (elm_widget_item_disabled_get(it))
1934 elm_widget_disabled_set(ic, EINA_TRUE);
1936 else if (it->flipped)
1938 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1939 // genlist does not need to handle this focus thing.
1940 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1941 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1951 _item_mode_content_unrealize(Elm_Gen_Item *it,
1952 Evas_Object *target,
1955 Eina_List **contents_list,
1956 const char *contents_part)
1958 Eina_List *res = *contents_list;
1960 if (it->itc->func.content_get)
1964 Evas_Object *ic = NULL;
1966 *source = elm_widget_stringlist_get(edje_object_data_get(target, contents_part));
1967 EINA_LIST_FOREACH(*source, l, key)
1969 if (parts && fnmatch(parts, key, FNM_PERIOD))
1972 ic = edje_object_part_swallow_get(target, key);
1975 res = eina_list_remove(res, ic);
1976 edje_object_part_unswallow(target, ic);
1977 evas_object_del(ic);
1986 _item_cache_free(Item_Cache *itc)
1988 if (itc->spacer) evas_object_del(itc->spacer);
1989 if (itc->base_view) evas_object_del(itc->base_view);
1990 eina_stringshare_del(itc->item_style);
1995 _item_text_realize(Elm_Gen_Item *it,
1996 Evas_Object *target,
2000 if (it->itc->func.text_get)
2005 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
2006 EINA_LIST_FOREACH(*source, l, key)
2008 if (parts && fnmatch(parts, key, FNM_PERIOD))
2011 char *s = it->itc->func.text_get
2012 ((void *)it->base.data, WIDGET(it), key);
2016 edje_object_part_text_set(target, key, s);
2021 edje_object_part_text_set(target, key, "");
2028 _item_content_unrealize(Elm_Gen_Item *it,
2029 Evas_Object *target,
2033 Eina_List *res = it->content_objs;
2035 if (it->itc->func.content_get)
2039 Evas_Object *ic = NULL;
2041 EINA_LIST_FOREACH(*source, l, key)
2043 if (parts && fnmatch(parts, key, FNM_PERIOD))
2046 ic = edje_object_part_swallow_get(target, key);
2049 res = eina_list_remove(res, ic);
2050 edje_object_part_unswallow(target, ic);
2051 evas_object_del(ic);
2060 _item_content_realize(Elm_Gen_Item *it,
2061 Evas_Object *target,
2065 Eina_List *res = NULL;
2067 if (it->itc->func.content_get)
2071 Evas_Object *ic = NULL;
2073 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
2075 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
2076 res = it->content_objs;
2078 EINA_LIST_FOREACH(*source, l, key)
2080 if (parts && fnmatch(parts, key, FNM_PERIOD))
2083 if (it->itc->func.content_get)
2084 ic = it->itc->func.content_get
2085 ((void *)it->base.data, WIDGET(it), key);
2088 res = eina_list_append(res, ic);
2089 edje_object_part_swallow(target, key, ic);
2090 evas_object_show(ic);
2091 elm_widget_sub_object_add(WIDGET(it), ic);
2092 evas_object_event_callback_add(ic,
2093 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2094 _changed_size_hints, it);
2097 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2098 // genlist does not need to handle this focus thing.
2099 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2100 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2103 if (elm_widget_item_disabled_get(it))
2104 elm_widget_disabled_set(ic, EINA_TRUE);
2113 _item_state_realize(Elm_Gen_Item *it,
2114 Evas_Object *target,
2118 if (it->itc->func.state_get)
2124 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2125 EINA_LIST_FOREACH(*source, l, key)
2127 if (parts && fnmatch(parts, key, FNM_PERIOD))
2130 Eina_Bool on = it->itc->func.state_get
2131 ((void *)it->base.data, WIDGET(it), key);
2135 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2136 edje_object_signal_emit(target, buf, "elm");
2140 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2141 edje_object_signal_emit(target, buf, "elm");
2148 _item_flips_realize(Elm_Gen_Item *it,
2149 Evas_Object *target,
2152 Eina_List *res = NULL;
2154 if (it->itc->func.content_get)
2158 Evas_Object *ic = NULL;
2160 *source = elm_widget_stringlist_get(edje_object_data_get(target, "flips"));
2162 EINA_LIST_FOREACH(*source, l, key)
2164 if (it->itc->func.content_get)
2165 ic = it->itc->func.content_get
2166 ((void *)it->base.data, WIDGET(it), key);
2169 res = eina_list_append(res, ic);
2170 edje_object_part_swallow(target, key, ic);
2171 evas_object_show(ic);
2172 elm_widget_sub_object_add(WIDGET(it), ic);
2173 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2174 // genlist does not need to handle this focus thing.
2175 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2176 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2177 if (elm_widget_item_disabled_get(it))
2178 elm_widget_disabled_set(ic, EINA_TRUE);
2187 _item_realize(Elm_Gen_Item *it,
2191 const char *treesize;
2194 Item_Cache *itc = NULL;
2196 if (it->generation < it->wd->generation) return;
2197 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2200 if (it->item->order_num_in != in)
2202 it->item->order_num_in = in;
2203 _elm_genlist_item_odd_even_update(it);
2204 _elm_genlist_item_state_update(it, NULL);
2205 _elm_genlist_item_index_update(it);
2207 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2208 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2211 it->item->order_num_in = in;
2213 if ((it->item->nocache_once) && (!it->flipped))
2214 it->item->nocache_once = EINA_FALSE;
2215 else if (!it->item->nocache)
2216 itc = _item_cache_find(it);
2217 if (itc && (!it->wd->tree_effect_enabled))
2219 VIEW(it) = itc->base_view;
2220 itc->base_view = NULL;
2221 it->spacer = itc->spacer;
2226 const char *stacking_even;
2227 const char *stacking;
2229 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2230 edje_object_scale_set(VIEW(it),
2231 elm_widget_scale_get(WIDGET(it)) *
2232 _elm_config->scale);
2233 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2234 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2236 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2237 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2239 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2241 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2242 elm_widget_style_get(WIDGET(it)));
2244 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2245 if (!stacking_even) stacking_even = "above";
2246 it->item->stacking_even = !!strcmp("above", stacking_even);
2248 stacking = edje_object_data_get(VIEW(it), "stacking");
2249 if (!stacking) stacking = "yes";
2250 it->item->nostacking = !!strcmp("yes", stacking);
2252 edje_object_mirrored_set(VIEW(it),
2253 elm_widget_mirrored_get(WIDGET(it)));
2255 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2256 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2257 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2260 _elm_genlist_item_odd_even_update(it);
2262 treesize = edje_object_data_get(VIEW(it), "treesize");
2263 if (treesize) tsize = atoi(treesize);
2264 evas_object_size_hint_min_set(it->spacer,
2265 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2266 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2269 edje_object_signal_callback_add(VIEW(it),
2270 "elm,action,expand,toggle",
2271 "elm", _signal_expand_toggle, it);
2272 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2273 "elm", _signal_expand, it);
2274 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2275 "elm", _signal_contract, it);
2276 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
2278 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
2280 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
2282 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
2284 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
2286 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
2289 if ((it->wd->decorate_mode) && (!it->edit_obj) &&
2290 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2291 _decorate_mode_item_realize(it, EINA_FALSE);
2293 _elm_genlist_item_state_update(it, itc);
2294 _elm_genlist_item_index_update(it);
2297 if ((calc) && (it->wd->homogeneous) &&
2298 ((it->wd->item_width) ||
2299 ((it->wd->item_width) && (it->wd->group_item_width))))
2301 /* homogenous genlist shortcut */
2302 if (!it->item->mincalcd)
2306 it->item->w = it->item->minw = it->wd->group_item_width;
2307 it->item->h = it->item->minh = it->wd->group_item_height;
2311 it->item->w = it->item->minw = it->wd->item_width;
2312 it->item->h = it->item->minh = it->wd->item_height;
2314 it->item->mincalcd = EINA_TRUE;
2319 /* FIXME: If you see that assert, please notify us and we
2320 will clean our mess */
2321 assert(eina_list_count(it->content_objs) == 0);
2323 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2324 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2325 _item_state_realize(it, VIEW(it), &it->states, NULL);
2328 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2329 it->content_objs = _item_flips_realize(it, VIEW(it), &it->contents);
2332 if (!it->item->mincalcd || ((it->wd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
2334 Evas_Coord mw = -1, mh = -1;
2336 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2337 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2338 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2339 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2341 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2342 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2343 it->item->w = it->item->minw = mw;
2344 it->item->h = it->item->minh = mh;
2345 it->item->mincalcd = EINA_TRUE;
2347 if ((!it->wd->group_item_width) && (it->group))
2349 it->wd->group_item_width = mw;
2350 it->wd->group_item_height = mh;
2352 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2354 it->wd->item_width = mw;
2355 it->wd->item_height = mh;
2358 if (!calc) evas_object_show(VIEW(it));
2361 if (it->tooltip.content_cb)
2363 elm_widget_item_tooltip_content_cb_set(it,
2364 it->tooltip.content_cb,
2365 it->tooltip.data, NULL);
2366 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2367 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2370 if (it->mouse_cursor)
2371 elm_widget_item_cursor_set(it, it->mouse_cursor);
2373 it->realized = EINA_TRUE;
2374 it->want_unrealize = EINA_FALSE;
2376 if (itc) _item_cache_free(itc);
2377 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2378 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2380 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2382 if ((!calc) && (it->wd->decorate_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2384 if (it->itc->decorate_all_item_style)
2386 if (!it->edit_obj) _decorate_mode_item_realize(it, EINA_FALSE);
2387 edje_object_message_signal_process(it->edit_obj);
2390 edje_object_message_signal_process(VIEW(it));
2394 _item_unrealize_cb(Elm_Gen_Item *it)
2396 if (it->item->nocache_once || it->item->nocache)
2398 evas_object_del(VIEW(it));
2400 evas_object_del(it->spacer);
2405 edje_object_mirrored_set(VIEW(it),
2406 elm_widget_mirrored_get(WIDGET(it)));
2407 edje_object_scale_set(VIEW(it),
2408 elm_widget_scale_get(WIDGET(it))
2409 * _elm_config->scale);
2410 _item_cache_add(it);
2413 _mode_item_unrealize(it);
2415 it->realized = EINA_FALSE;
2416 it->want_unrealize = EINA_FALSE;
2417 if (it->wd->decorate_mode) _decorate_mode_item_unrealize(it);
2421 _item_block_recalc(Item_Block *itb,
2427 Evas_Coord minw = 0, minh = 0;
2428 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2431 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2433 EINA_LIST_FOREACH(itb->items, l, it)
2435 if (it->generation < it->wd->generation) continue;
2436 showme |= it->item->showme;
2441 if (!it->item->mincalcd) changed = EINA_TRUE;
2444 _item_realize(it, in, EINA_TRUE);
2445 _elm_genlist_item_unrealize(it, EINA_TRUE);
2450 _item_realize(it, in, EINA_TRUE);
2451 _elm_genlist_item_unrealize(it, EINA_TRUE);
2455 _item_realize(it, in, EINA_FALSE);
2456 minh += it->item->minh;
2457 if (minw < it->item->minw) minw = it->item->minw;
2465 itb->changed = EINA_FALSE;
2466 itb->position_update = EINA_FALSE;
2467 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2468 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2473 _item_block_realize(Item_Block *itb)
2475 if (itb->realized) return;
2476 itb->realized = EINA_TRUE;
2477 itb->want_unrealize = EINA_FALSE;
2481 _item_block_unrealize(Item_Block *itb)
2485 Eina_Bool dragging = EINA_FALSE;
2487 if (!itb->realized) return;
2488 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2489 EINA_LIST_FOREACH(itb->items, l, it)
2491 if (itb->must_recalc || !it->group)
2495 dragging = EINA_TRUE;
2496 it->want_unrealize = EINA_TRUE;
2499 _elm_genlist_item_unrealize(it, EINA_FALSE);
2504 itb->realized = EINA_FALSE;
2505 itb->want_unrealize = EINA_TRUE;
2508 itb->want_unrealize = EINA_FALSE;
2509 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2510 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2514 _get_space_for_reorder_item(Elm_Gen_Item *it)
2516 Evas_Coord rox, roy, row, roh, oy, oh;
2517 Eina_Bool top = EINA_FALSE;
2518 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2519 if (!reorder_it) return 0;
2521 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2522 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2524 if ((it->wd->reorder_start_y < it->item->block->y) &&
2525 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2527 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2528 if (it->item->block->count == 1)
2529 it->wd->reorder_rel = it;
2531 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2532 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2534 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2537 it->item->block->reorder_offset = 0;
2539 it->item->scrl_y += it->item->block->reorder_offset;
2541 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2542 rox, roy + (roh / 2), row, 1));
2545 it->wd->reorder_rel = it;
2546 it->item->scrl_y += it->wd->reorder_it->item->h;
2547 return it->wd->reorder_it->item->h;
2554 _reorder_move_animator_cb(void *data)
2556 Elm_Gen_Item *it = data;
2557 Eina_Bool down = EINA_FALSE;
2559 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2561 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2563 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2566 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2567 if (diff > it->item->h) y = diff / 2;
2569 if (it->item->old_scrl_y < it->item->scrl_y)
2571 it->item->old_scrl_y += y;
2574 else if (it->item->old_scrl_y > it->item->scrl_y)
2576 it->item->old_scrl_y -= y;
2581 _item_position(it, it->edit_obj, it->item->scrl_x, it->item->old_scrl_y);
2583 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2584 //FIXME : group raise
2586 _group_items_recalc(it->wd);
2589 if ((it->wd->reorder_pan_move) ||
2590 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2591 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2593 it->item->old_scrl_y = it->item->scrl_y;
2594 it->item->move_effect_enabled = EINA_FALSE;
2595 it->wd->reorder_move_animator = NULL;
2596 return ECORE_CALLBACK_CANCEL;
2598 return ECORE_CALLBACK_RENEW;
2602 _item_position(Elm_Gen_Item *it,
2610 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2611 evas_object_resize(view, it->item->w, it->item->h);
2612 evas_object_move(view, it_x, it_y);
2613 evas_object_show(view);
2614 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2615 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2619 _item_block_position(Item_Block *itb,
2624 //FIXME : group raise
2628 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2629 Eina_Bool vis = EINA_FALSE;
2630 Evas_Coord minh = 0;
2632 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2633 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2634 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2636 EINA_LIST_FOREACH(itb->items, l, it)
2638 if (it->generation < it->wd->generation) continue;
2639 else if (it->wd->reorder_it == it) continue;
2642 it->item->w = itb->w;
2643 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2644 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2646 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2647 cvx, cvy, cvw, cvh));
2648 //FIXME : group raise
2653 if ((itb->realized) && (!it->realized))
2655 if (vis) _item_realize(it, in, EINA_FALSE);
2659 if (vis || it->dragging)
2661 if (it->wd->reorder_mode)
2662 y += _get_space_for_reorder_item(it);
2663 //FIXME : group raise
2665 git = it->item->group_item;
2668 if (git->item->scrl_y < oy)
2669 git->item->scrl_y = oy;
2670 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2671 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2672 git->item->want_realize = EINA_TRUE;
2675 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2677 if (!it->item->move_effect_enabled)
2679 it->item->move_effect_enabled = EINA_TRUE;
2680 it->wd->reorder_move_animator =
2682 _reorder_move_animator_cb, it);
2685 if (!it->item->move_effect_enabled)
2687 if ((it->wd->decorate_mode) && (it->itc->decorate_all_item_style))
2688 _decorate_mode_item_position(it, it->item->scrl_x,
2692 if (it->item->mode_view)
2693 _item_position(it, it->item->mode_view,
2697 _item_position(it, VIEW(it), it->item->scrl_x,
2700 it->item->old_scrl_y = it->item->scrl_y;
2705 if (!it->wd->item_moving_effect_timer)
2706 _elm_genlist_item_unrealize(it, EINA_FALSE);
2711 //FIXME : group raise
2715 if (vis) it->item->want_realize = EINA_TRUE;
2719 minh += it->item->minh;
2721 if (!itb->wd->reorder_it) itb->minh = minh;
2722 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2723 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2726 //FIXME: group raise
2729 _group_items_recalc(void *data)
2731 Widget_Data *wd = data;
2735 evas_event_freeze(evas_object_evas_get(wd->obj));
2736 EINA_LIST_FOREACH(wd->group_items, l, git)
2738 if (git->item->want_realize)
2741 _item_realize(git, 0, EINA_FALSE);
2742 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2743 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2744 evas_object_show(VIEW(git));
2745 evas_object_raise(VIEW(git));
2747 else if (!git->item->want_realize && git->realized)
2750 _elm_genlist_item_unrealize(git, EINA_FALSE);
2753 evas_event_thaw(evas_object_evas_get(wd->obj));
2754 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2759 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2761 Elm_Gen_Item *it = data;
2763 it->item->mincalcd = EINA_FALSE;
2764 it->item->block->changeme = EINA_TRUE;
2765 if (it->wd->changed_job) ecore_job_del(it->wd->changed_job);
2766 it->wd->changed_job = ecore_job_add(_changed_job, it->wd);
2770 _must_recalc_idler(void *data)
2772 Widget_Data *wd = data;
2773 if (wd->calc_job) ecore_job_del(wd->calc_job);
2774 wd->calc_job = ecore_job_add(_calc_job, wd);
2775 wd->must_recalc_idler = NULL;
2776 return ECORE_CALLBACK_CANCEL;
2780 _scroll_item(Widget_Data *wd)
2782 Elm_Gen_Item *it = NULL;
2783 //FIXME: group raise
2785 Evas_Coord gith = 0;
2787 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2788 if (!wd->show_item) return;
2790 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2792 dx = it->x + it->item->block->x;
2793 dy = it->y + it->item->block->y;
2794 dw = it->item->block->w;
2796 switch (wd->scrollto_type)
2798 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2799 //FIXME: group raise
2801 if (it->item->group_item) gith = it->item->group_item->item->h;
2805 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2806 dy += (it->item->h / 2 - oh / 2);
2808 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2810 if ((wd->expanded_item) &&
2811 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2812 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2814 it = wd->expanded_item;
2815 dx = it->x + it->item->block->x;
2816 dy = it->y + it->item->block->y;
2817 //FIXME: group raise
2819 if (it->item->group_item) gith = it->item->group_item->item->h;
2820 dx = it->x + it->item->block->x;
2821 dy = it->y + it->item->block->y - gith;
2823 dw = it->item->block->w;
2827 //FIXME: group raise
2829 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2830 gith = it->item->group_item->item->h;
2838 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2840 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2842 it->item->showme = EINA_FALSE;
2843 wd->show_item = NULL;
2844 wd->auto_scroll_enabled = EINA_FALSE;
2845 wd->check_scroll = EINA_FALSE;
2849 _calc_job(void *data)
2851 Widget_Data *wd = data;
2852 Item_Block *itb, *chb = NULL;
2853 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2854 Evas_Coord pan_w = 0, pan_h = 0;
2856 Eina_Bool minw_change = EINA_FALSE;
2857 Eina_Bool did_must_recalc = EINA_FALSE;
2860 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2861 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2866 evas_event_freeze(evas_object_evas_get(wd->obj));
2867 EINA_INLIST_FOREACH(wd->blocks, itb)
2869 Eina_Bool showme = EINA_FALSE;
2872 showme = itb->showme;
2873 itb->showme = EINA_FALSE;
2876 if (itb->realized) _item_block_unrealize(itb);
2878 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2880 if (itb->must_recalc)
2884 EINA_LIST_FOREACH(itb->items, l, it)
2885 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2886 itb->changed = EINA_TRUE;
2887 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2888 if (itb->realized) _item_block_unrealize(itb);
2889 itb->must_recalc = EINA_FALSE;
2891 showme = _item_block_recalc(itb, in, EINA_FALSE);
2897 if (minw == -1) minw = itb->minw;
2898 else if ((!itb->must_recalc) && (minw < itb->minw))
2901 minw_change = EINA_TRUE;
2906 minw_change = EINA_TRUE;
2912 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2913 wd->check_scroll = EINA_TRUE;
2917 EINA_INLIST_FOREACH(wd->blocks, itb)
2923 if ((chb) && (EINA_INLIST_GET(chb)->next))
2925 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2927 if (itb->realized) _item_block_unrealize(itb);
2930 wd->realminw = minw;
2931 if (minw < wd->w) minw = wd->w;
2932 if ((minw != wd->minw) || (minh != wd->minh))
2936 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2937 _sizing_eval(wd->obj);
2938 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2943 it = wd->anchor_item;
2944 it_y = wd->anchor_y;
2945 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2946 it->item->block->y + it->y + it_y);
2947 wd->anchor_item = it;
2948 wd->anchor_y = it_y;
2951 if (did_must_recalc)
2953 if (!wd->must_recalc_idler)
2954 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2956 if (wd->check_scroll)
2958 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2959 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2960 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2961 switch (wd->scrollto_type)
2963 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2966 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2969 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2976 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2977 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2983 wd->calc_job = NULL;
2984 evas_object_smart_changed(wd->pan_smart);
2985 evas_event_thaw(evas_object_evas_get(wd->obj));
2986 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2990 _update_job(void *data)
2992 Widget_Data *wd = data;
2996 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2998 wd->update_job = NULL;
3001 evas_event_freeze(evas_object_evas_get(wd->obj));
3002 EINA_INLIST_FOREACH(wd->blocks, itb)
3004 Evas_Coord itminw, itminh;
3011 _item_block_position(itb, num);
3015 recalc = EINA_FALSE;
3016 EINA_LIST_FOREACH(itb->items, l2, it)
3018 if (it->item->updateme)
3020 itminw = it->item->minw;
3021 itminh = it->item->minh;
3025 _elm_genlist_item_unrealize(it, EINA_FALSE);
3026 _item_realize(it, num, EINA_FALSE);
3027 position = EINA_TRUE;
3031 _item_realize(it, num, EINA_TRUE);
3032 _elm_genlist_item_unrealize(it, EINA_TRUE);
3034 if ((it->item->minw != itminw) || (it->item->minh != itminh))
3036 it->item->updateme = EINA_FALSE;
3040 itb->updateme = EINA_FALSE;
3043 position = EINA_TRUE;
3044 itb->changed = EINA_TRUE;
3045 _item_block_recalc(itb, num0, EINA_FALSE);
3046 _item_block_position(itb, num0);
3051 if (wd->calc_job) ecore_job_del(wd->calc_job);
3052 wd->calc_job = ecore_job_add(_calc_job, wd);
3054 evas_event_thaw(evas_object_evas_get(wd->obj));
3055 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3059 _changed_job(void *data)
3061 Widget_Data *wd = data; Eina_List *l2;
3063 int num, num0, position = 0;
3064 Eina_Bool width_changed = EINA_FALSE, height_changed = EINA_FALSE;
3066 wd->changed_job = NULL;
3068 EINA_INLIST_FOREACH(wd->blocks, itb)
3070 Evas_Coord itminw, itminh;
3077 _item_block_position(itb, num);
3081 width_changed = height_changed = EINA_FALSE;
3082 EINA_LIST_FOREACH(itb->items, l2, it)
3084 if ((!it->item->mincalcd) && (it->realized))
3086 Evas_Coord mw = -1, mh = -1;
3087 itminw = it->item->minw;
3088 itminh = it->item->minh;
3090 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->w;
3091 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3092 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3093 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
3094 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
3095 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3096 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3098 width_changed = EINA_TRUE;
3101 it->item->w = it->item->minw = mw;
3102 it->item->h = it->item->minh = mh;
3103 it->item->mincalcd = EINA_TRUE;
3105 //if ((it->item->minw != itminw) || (it->item->minh != itminh))
3106 //if ((it->item->minh != itminh))
3108 if ((it->item->minw != itminw))
3109 width_changed = EINA_TRUE;
3110 if ((it->item->minh != itminh))
3111 height_changed = EINA_TRUE;
3113 if ((!it->wd->group_item_width) && (it->group))
3115 it->wd->group_item_width = mw;
3116 it->wd->group_item_height = mh;
3118 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
3120 it->wd->item_width = mw;
3121 it->wd->item_height = mh;
3126 itb->changeme = EINA_FALSE;
3127 // TODO: why this is separated.
3131 itb->changed = EINA_TRUE;
3132 _item_block_recalc(itb, num0, 0);
3133 _item_block_position(itb, num0);
3135 else if (width_changed)
3137 _item_block_position(itb, num0);
3142 if (wd->calc_job) ecore_job_del(wd->calc_job);
3143 wd->calc_job = ecore_job_add(_calc_job, wd);
3148 _pan_set(Evas_Object *obj,
3152 Pan *sd = evas_object_smart_data_get(obj);
3156 // Evas_Coord ow, oh;
3157 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3158 // ow = sd->wd->minw - ow;
3159 // if (ow < 0) ow = 0;
3160 // oh = sd->wd->minh - oh;
3161 // if (oh < 0) oh = 0;
3162 // if (x < 0) x = 0;
3163 // if (y < 0) y = 0;
3164 // if (x > ow) x = ow;
3165 // if (y > oh) y = oh;
3166 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
3170 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3172 if ((itb->y + itb->h) > y)
3177 EINA_LIST_FOREACH(itb->items, l2, it)
3179 if ((itb->y + it->y) >= y)
3181 sd->wd->anchor_item = it;
3182 sd->wd->anchor_y = -(itb->y + it->y - y);
3189 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
3193 _pan_get(Evas_Object *obj,
3197 Pan *sd = evas_object_smart_data_get(obj);
3200 if (x) *x = sd->wd->pan_x;
3201 if (y) *y = sd->wd->pan_y;
3205 _pan_max_get(Evas_Object *obj,
3209 Pan *sd = evas_object_smart_data_get(obj);
3213 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3214 ow = sd->wd->minw - ow;
3216 oh = sd->wd->minh - oh;
3223 _pan_min_get(Evas_Object *obj __UNUSED__,
3232 _pan_child_size_get(Evas_Object *obj,
3236 Pan *sd = evas_object_smart_data_get(obj);
3239 if (w) *w = sd->wd->minw;
3240 if (h) *h = sd->wd->minh;
3244 _pan_add(Evas_Object *obj)
3247 Evas_Object_Smart_Clipped_Data *cd;
3250 cd = evas_object_smart_data_get(obj);
3253 sd->__clipped_data = *cd;
3255 evas_object_smart_data_set(obj, sd);
3259 _pan_del(Evas_Object *obj)
3261 Pan *sd = evas_object_smart_data_get(obj);
3266 ecore_job_del(sd->resize_job);
3267 sd->resize_job = NULL;
3273 _pan_resize_job(void *data)
3277 _sizing_eval(sd->wd->obj);
3278 sd->resize_job = NULL;
3282 _pan_resize(Evas_Object *obj,
3286 Pan *sd = evas_object_smart_data_get(obj);
3290 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3291 if ((ow == w) && (oh == h)) return;
3292 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3295 if (sd->resize_job) ecore_job_del(sd->resize_job);
3296 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3298 sd->wd->pan_changed = EINA_TRUE;
3299 evas_object_smart_changed(obj);
3300 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3301 sd->wd->calc_job = NULL;
3305 _pan_calculate(Evas_Object *obj)
3307 Pan *sd = evas_object_smart_data_get(obj);
3309 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3311 //FIXME: group raise
3318 evas_event_freeze(evas_object_evas_get(obj));
3320 if (sd->wd->pan_changed)
3323 sd->wd->pan_changed = EINA_FALSE;
3326 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3327 sd->wd->prev_viewport_w = ow;
3328 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3329 //FIXME: group raise
3331 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3333 git->item->want_realize = EINA_FALSE;
3336 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3338 itb->w = sd->wd->minw;
3339 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3340 itb->y - sd->wd->pan_y + oy,
3342 cvx, cvy, cvw, cvh))
3344 if ((!itb->realized) || (itb->changed))
3346 _item_block_realize(itb);
3348 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3349 sd->wd->calc_job = NULL;
3352 _item_block_position(itb, in);
3356 if (itb->realized) _item_block_unrealize(itb);
3360 //FIXME: group raise
3362 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3363 _group_items_recalc(sd->wd);
3365 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3367 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3368 sd->wd->reorder_pan_move = EINA_TRUE;
3369 else sd->wd->reorder_pan_move = EINA_FALSE;
3370 evas_object_raise(sd->wd->VIEW(reorder_it));
3371 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3372 sd->wd->start_time = ecore_loop_time_get();
3375 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3377 if (!sd->wd->item_moving_effect_timer)
3379 _item_tree_effect_before(sd->wd->expanded_item);
3380 evas_object_raise(sd->wd->alpha_bg);
3381 evas_object_show(sd->wd->alpha_bg);
3382 sd->wd->start_time = ecore_time_get();
3383 sd->wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, sd->wd);
3387 _item_auto_scroll(sd->wd);
3389 evas_event_thaw(evas_object_evas_get(obj));
3390 evas_event_thaw_eval(evas_object_evas_get(obj));
3394 _pan_move(Evas_Object *obj,
3395 Evas_Coord x __UNUSED__,
3396 Evas_Coord y __UNUSED__)
3398 Pan *sd = evas_object_smart_data_get(obj);
3402 sd->wd->pan_changed = EINA_TRUE;
3403 evas_object_smart_changed(obj);
3404 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3405 sd->wd->calc_job = NULL;
3409 _hold_on(void *data __UNUSED__,
3411 void *event_info __UNUSED__)
3413 Widget_Data *wd = elm_widget_data_get(obj);
3415 elm_smart_scroller_hold_set(wd->scr, 1);
3419 _hold_off(void *data __UNUSED__,
3421 void *event_info __UNUSED__)
3423 Widget_Data *wd = elm_widget_data_get(obj);
3425 elm_smart_scroller_hold_set(wd->scr, 0);
3429 _freeze_on(void *data __UNUSED__,
3431 void *event_info __UNUSED__)
3433 Widget_Data *wd = elm_widget_data_get(obj);
3435 elm_smart_scroller_freeze_set(wd->scr, 1);
3439 _freeze_off(void *data __UNUSED__,
3441 void *event_info __UNUSED__)
3443 Widget_Data *wd = elm_widget_data_get(obj);
3445 elm_smart_scroller_freeze_set(wd->scr, 0);
3449 _scr_anim_start(void *data,
3450 Evas_Object *obj __UNUSED__,
3451 void *event_info __UNUSED__)
3453 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3457 _scr_anim_stop(void *data,
3458 Evas_Object *obj __UNUSED__,
3459 void *event_info __UNUSED__)
3461 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3465 _scr_drag_start(void *data,
3466 Evas_Object *obj __UNUSED__,
3467 void *event_info __UNUSED__)
3469 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3473 _scr_drag_stop(void *data,
3474 Evas_Object *obj __UNUSED__,
3475 void *event_info __UNUSED__)
3477 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3481 _edge_left(void *data,
3482 Evas_Object *scr __UNUSED__,
3483 void *event_info __UNUSED__)
3485 Evas_Object *obj = data;
3486 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3490 _edge_right(void *data,
3491 Evas_Object *scr __UNUSED__,
3492 void *event_info __UNUSED__)
3494 Evas_Object *obj = data;
3495 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3499 _edge_top(void *data,
3500 Evas_Object *scr __UNUSED__,
3501 void *event_info __UNUSED__)
3503 Evas_Object *obj = data;
3504 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3508 _edge_bottom(void *data,
3509 Evas_Object *scr __UNUSED__,
3510 void *event_info __UNUSED__)
3512 Evas_Object *obj = data;
3513 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3517 _mode_item_realize(Elm_Gen_Item *it)
3521 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
3523 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3524 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3525 edje_object_scale_set(it->item->mode_view,
3526 elm_widget_scale_get(WIDGET(it)) *
3527 _elm_config->scale);
3528 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
3529 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
3531 strncpy(buf, "item", sizeof(buf));
3532 if (it->wd->mode == ELM_LIST_COMPRESS)
3533 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3535 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3536 strncat(buf, "/", sizeof(buf) - strlen(buf));
3537 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3539 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
3540 elm_widget_style_get(WIDGET(it)));
3541 edje_object_mirrored_set(it->item->mode_view,
3542 elm_widget_mirrored_get(WIDGET(it)));
3544 /* signal callback add */
3545 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
3547 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
3549 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
3552 /* text_get, content_get, state_get */
3553 /* FIXME: If you see that assert, please notify us and we
3554 will clean our mess */
3555 assert(eina_list_count(it->item->mode_content_objs) == 0);
3557 _item_text_realize(it, it->item->mode_view, &it->item->mode_texts, NULL);
3558 it->item->mode_content_objs =
3559 _item_content_realize(it, it->item->mode_view,
3560 &it->item->mode_contents, NULL);
3561 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
3563 edje_object_part_swallow(it->item->mode_view,
3564 edje_object_data_get(it->item->mode_view, "mode_part"),
3567 it->want_unrealize = EINA_FALSE;
3568 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3569 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3573 _mode_item_unrealize(Elm_Gen_Item *it)
3575 Widget_Data *wd = it->wd;
3576 Evas_Object *content;
3577 if (!it->item->mode_view) return;
3579 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3580 elm_widget_stringlist_free(it->item->mode_texts);
3581 it->item->mode_texts = NULL;
3582 elm_widget_stringlist_free(it->item->mode_contents);
3583 it->item->mode_contents = NULL;
3584 elm_widget_stringlist_free(it->item->mode_states);
3586 EINA_LIST_FREE(it->item->mode_content_objs, content)
3587 evas_object_del(content);
3589 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
3590 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3591 evas_object_del(it->item->mode_view);
3592 it->item->mode_view = NULL;
3594 if (wd->mode_item == it)
3595 wd->mode_item = NULL;
3596 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3597 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3601 _item_mode_set(Elm_Gen_Item *it)
3604 Widget_Data *wd = it->wd;
3609 it->item->nocache_once = EINA_TRUE;
3611 if (wd->scr_hold_timer)
3613 ecore_timer_del(wd->scr_hold_timer);
3614 wd->scr_hold_timer = NULL;
3616 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3617 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3619 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3620 _mode_item_realize(it);
3621 if (it->item->group_item)
3622 evas_object_raise(it->item->VIEW(group_item));
3623 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
3624 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3625 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3627 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_type);
3628 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3632 _item_mode_unset(Widget_Data *wd)
3635 if (!wd->mode_item) return;
3636 char buf[1024], buf2[1024];
3640 it->item->nocache_once = EINA_TRUE;
3642 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_type);
3643 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_type);
3645 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3646 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
3648 wd->mode_item = NULL;
3652 _decorate_mode_item_position(Elm_Gen_Item *it, int itx, int ity)
3654 if ((!it) || (!it->wd->decorate_mode)) return;
3655 evas_object_resize(it->edit_obj, it->item->w, it->item->h);
3656 evas_object_move(it->edit_obj, itx, ity);
3660 _decorate_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3663 const char *stacking_even;
3664 const char *stacking;
3666 if ((!it) || (it->item->decorate_mode_item_realized) ||
3667 (it->generation < it->wd->generation))
3670 it->edit_obj = edje_object_add(evas_object_evas_get(WIDGET(it)));
3671 edje_object_scale_set(it->edit_obj, elm_widget_scale_get(WIDGET(it)) *
3672 _elm_config->scale);
3673 evas_object_smart_member_add(it->edit_obj, it->wd->pan_smart);
3674 elm_widget_sub_object_add(WIDGET(it), it->edit_obj);
3676 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3677 strncpy(buf, "tree", sizeof(buf));
3678 else strncpy(buf, "item", sizeof(buf));
3679 if (it->wd->mode == ELM_LIST_COMPRESS)
3680 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3682 strncat(buf, "/", sizeof(buf) - strlen(buf));
3683 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3685 _elm_theme_object_set(WIDGET(it), it->edit_obj, "genlist", buf,
3686 elm_widget_style_get(WIDGET(it)));
3688 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3689 if (!stacking_even) stacking_even = "above";
3690 it->item->stacking_even = !!strcmp("above", stacking_even);
3692 stacking = edje_object_data_get(VIEW(it), "stacking");
3693 if (!stacking) stacking = "yes";
3694 it->item->nostacking = !!strcmp("yes", stacking);
3696 edje_object_mirrored_set(it->edit_obj,
3697 elm_widget_mirrored_get(WIDGET(it)));
3699 _elm_genlist_item_odd_even_update(it);
3700 _elm_genlist_item_state_update(it, NULL);
3702 if (effect_on) edje_object_signal_emit(it->edit_obj, "elm,state,decorate,enabled,effect", "elm");
3703 else edje_object_signal_emit(it->edit_obj, "elm,state,decorate,enabled", "elm");
3705 evas_object_event_callback_del_full(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
3707 evas_object_event_callback_del_full(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
3709 evas_object_event_callback_del_full(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
3711 evas_object_event_callback_del_full(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
3713 evas_object_event_callback_del_full(VIEW(it), EVAS_CALLBACK_MULTI_UP,
3715 evas_object_event_callback_del_full(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
3718 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
3720 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
3722 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
3724 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MULTI_DOWN,
3726 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MULTI_UP,
3728 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MULTI_MOVE,
3731 _item_text_realize(it, it->edit_obj, &it->item->edit_texts, NULL);
3732 if (it->flipped) edje_object_signal_emit(it->edit_obj, "elm,state,flip,enabled", "elm");
3733 it->item->edit_content_objs =
3734 _item_mode_content_realize(it, it->edit_obj, &it->contents,
3735 NULL, &it->item->edit_content_objs,
3736 "decorate_contents"); //FIXME
3737 _item_state_realize(it, it->edit_obj, &it->item->edit_states, NULL);
3738 edje_object_part_swallow(it->edit_obj, "elm.swallow.decorate.content", VIEW(it));
3740 _decorate_mode_item_position(it, it->item->scrl_x, it->item->scrl_y);
3741 evas_object_show(it->edit_obj);
3743 it->item->decorate_mode_item_realized = EINA_TRUE;
3744 it->want_unrealize = EINA_FALSE;
3748 _decorate_mode_item_unrealize(Elm_Gen_Item *it)
3751 if ((!it) || (!it->item->decorate_mode_item_realized)) return;
3753 edje_object_part_unswallow(it->edit_obj, VIEW(it));
3754 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3755 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3756 _elm_genlist_item_odd_even_update(it);
3757 _elm_genlist_item_state_update(it, NULL);
3759 evas_object_del(it->edit_obj);
3760 it->edit_obj = NULL;
3761 elm_widget_stringlist_free(it->item->edit_texts);
3762 it->item->edit_texts = NULL;
3763 elm_widget_stringlist_free(it->item->edit_contents);
3764 it->item->edit_contents = NULL;
3765 elm_widget_stringlist_free(it->item->edit_states);
3766 it->item->edit_states = NULL;
3767 EINA_LIST_FREE(it->item->edit_content_objs, icon)
3768 evas_object_del(icon);
3769 edje_object_message_signal_process(it->edit_obj);
3771 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
3773 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
3775 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
3777 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MULTI_DOWN,
3779 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MULTI_UP,
3781 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MULTI_MOVE,
3784 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
3786 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
3788 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
3790 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
3792 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
3794 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
3797 it->item->decorate_mode_item_realized = EINA_FALSE;
3801 _item_auto_scroll(Widget_Data *wd)
3804 Elm_Gen_Item *tmp_item = NULL;
3806 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3808 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3809 if (!tmp_item) return;
3810 wd->show_item = tmp_item;
3811 wd->bring_in = EINA_TRUE;
3812 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3813 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3815 wd->show_item->item->showme = EINA_TRUE;
3816 wd->auto_scroll_enabled = EINA_FALSE;
3824 elm_genlist_add(Evas_Object *parent)
3829 Evas_Coord minw, minh;
3830 static Evas_Smart *smart = NULL;
3834 static Evas_Smart_Class sc;
3836 evas_object_smart_clipped_smart_set(&_pan_sc);
3838 sc.name = "elm_genlist_pan";
3839 sc.version = EVAS_SMART_CLASS_VERSION;
3842 sc.resize = _pan_resize;
3843 sc.move = _pan_move;
3844 sc.calculate = _pan_calculate;
3845 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3848 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3850 ELM_SET_WIDTYPE(widtype, "genlist");
3852 elm_widget_type_set(obj, "genlist");
3853 elm_widget_sub_object_add(parent, obj);
3854 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3855 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3856 elm_widget_data_set(obj, wd);
3857 elm_widget_del_hook_set(obj, _del_hook);
3858 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3859 elm_widget_theme_hook_set(obj, _theme_hook);
3860 elm_widget_can_focus_set(obj, EINA_TRUE);
3861 elm_widget_event_hook_set(obj, _event_hook);
3862 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3863 elm_widget_translate_hook_set(obj, _translate_hook);
3866 wd->scr = elm_smart_scroller_add(e);
3867 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_DOWN,
3868 _mouse_down_scroller, obj);
3869 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_UP,
3870 _mouse_up_scroller, obj);
3871 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_MOVE,
3872 _mouse_move_scroller, obj);
3873 elm_smart_scroller_widget_set(wd->scr, obj);
3874 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3875 elm_widget_style_get(obj));
3876 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3877 _elm_config->thumbscroll_bounce_enable);
3878 elm_widget_resize_object_set(obj, wd->scr);
3880 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3881 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3882 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3883 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3884 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3885 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3886 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3887 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3890 wd->mode = ELM_LIST_SCROLL;
3891 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3892 wd->item_cache_max = wd->max_items_per_block * 2;
3893 wd->longpress_timeout = _elm_config->longpress_timeout;
3894 wd->highlight = EINA_TRUE;
3895 wd->tree_effect_enabled = _elm_config->effect_enable;
3897 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3898 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3899 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3900 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3902 wd->pan_smart = evas_object_smart_add(e, smart);
3903 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3906 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3907 _pan_set, _pan_get, _pan_max_get,
3908 _pan_min_get, _pan_child_size_get);
3910 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3912 evas_object_size_hint_min_set(obj, minw, minh);
3914 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3916 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3922 _item_select(Elm_Gen_Item *it)
3927 if ((it->generation < it->wd->generation) || (it->mode_set) ||
3928 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3929 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3933 it->selected = EINA_TRUE;
3934 it->wd->selected = eina_list_append(it->wd->selected, it);
3936 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3938 evas_object_ref(WIDGET(it));
3941 if (it->wd->last_selected_item &&
3942 (it != (Elm_Gen_Item *) it->wd->last_selected_item))
3944 EINA_LIST_FOREACH(((Elm_Gen_Item *)it->wd->last_selected_item)->content_objs, l, obj)
3946 elm_widget_focused_object_clear(obj);
3947 elm_widget_tree_unfocusable_set(obj, EINA_TRUE);
3949 ((Elm_Gen_Item *)it->wd->last_selected_item)->can_focus = EINA_FALSE;
3951 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3952 if (it->generation == it->wd->generation)
3953 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3956 if ((it->wd->clear_me) && (!it->wd->walking))
3957 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3960 if ((!it->walking) && (it->generation < it->wd->generation))
3965 elm_widget_item_free(it);
3969 it->wd->last_selected_item = (Elm_Object_Item *)it;
3971 evas_object_unref(WIDGET(it));
3974 static Evas_Object *
3975 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3977 return edje_object_part_swallow_get(VIEW(it), part);
3981 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3983 if (content && part)
3985 it->content_objs = eina_list_append(it->content_objs, content);
3986 edje_object_part_swallow(VIEW(it), part, content);
3990 static Evas_Object *
3991 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3994 obj = edje_object_part_swallow_get(VIEW(it), part);
3995 if (!obj) return NULL;
3996 it->content_objs = eina_list_remove(it->content_objs, obj);
3997 edje_object_part_unswallow(VIEW(it), obj);
4002 _item_text_hook(Elm_Gen_Item *it, const char *part)
4004 if (!it->itc->func.text_get) return NULL;
4005 return edje_object_part_text_get(VIEW(it), part);
4009 _item_disable_hook(Elm_Object_Item *it)
4013 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4015 if (_it->generation < _it->wd->generation) return;
4018 elm_genlist_item_selected_set(it, EINA_FALSE);
4022 if (elm_widget_item_disabled_get(it))
4024 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
4026 edje_object_signal_emit(_it->edit_obj, "elm,state,disabled", "elm");
4030 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
4032 edje_object_signal_emit(_it->edit_obj, "elm,state,enabled", "elm");
4034 EINA_LIST_FOREACH(_it->content_objs, l, obj)
4035 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
4040 _item_del_pre_hook(Elm_Object_Item *it)
4042 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4044 if ((_it->relcount > 0) || (_it->walking > 0))
4046 if (!_it->item->block && (_it->relcount == 1)) goto del;
4047 elm_genlist_item_subitems_clear(it);
4048 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
4049 _elm_genlist_item_del_notserious(_it);
4050 if (_it->item->block)
4052 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
4053 _it->item->block->changed = EINA_TRUE;
4054 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
4055 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
4059 _it->parent->item->items =
4060 eina_list_remove(_it->parent->item->items, it);
4071 _item_signal_emit_hook(Elm_Object_Item *it,
4072 const char *emission,
4075 edje_object_signal_emit(VIEW(it), emission, source);
4079 _elm_genlist_item_new(Widget_Data *wd,
4080 const Elm_Gen_Item_Class *itc,
4082 Elm_Gen_Item *parent,
4084 const void *func_data)
4088 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
4089 if (!it) return NULL;
4091 it->generation = wd->generation;
4093 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
4094 it->base.data = data;
4095 it->parent = parent;
4096 it->func.func = func;
4097 it->func.data = func_data;
4098 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
4099 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
4100 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
4101 elm_widget_item_text_get_hook_set(it, _item_text_hook);
4102 elm_widget_item_disable_hook_set(it, _item_disable_hook);
4103 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
4104 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
4107 it->sel_cb = (Ecore_Cb)_item_select;
4112 static Elm_Gen_Item *
4113 _item_new(Widget_Data *wd,
4114 const Elm_Genlist_Item_Class *itc,
4116 Elm_Gen_Item *parent,
4117 Elm_Genlist_Item_Type type,
4119 const void *func_data)
4121 Elm_Gen_Item *it, *it2;
4124 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
4125 if (!it) return NULL;
4126 it->item = ELM_NEW(Elm_Gen_Item_Type);
4127 it->item->type = type;
4128 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
4129 it->item->expanded_depth = 0;
4130 ELM_GEN_ITEM_SETUP(it);
4131 it->mouse_cursor = NULL;
4132 it->can_focus = EINA_TRUE;
4135 if (it->parent->group)
4136 it->item->group_item = parent;
4137 else if (it->parent->item->group_item)
4138 it->item->group_item = it->parent->item->group_item;
4140 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
4142 if (!it2->parent->group) depth += 1;
4144 it->item->expanded_depth = depth;
4150 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
4154 itb = calloc(1, sizeof(Item_Block));
4155 if (!itb) return NULL;
4159 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
4160 _item_block_position_update(wd->blocks, 0);
4164 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4165 itb->position_update = EINA_TRUE;
4166 if (wd->blocks != EINA_INLIST_GET(itb))
4168 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4179 _item_block_add(Widget_Data *wd,
4182 Item_Block *itb = NULL;
4189 itb = calloc(1, sizeof(Item_Block));
4190 if (!itb) return EINA_FALSE;
4192 if (!it->item->rel->item->block)
4195 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4196 itb->items = eina_list_append(itb->items, it);
4197 itb->position_update = EINA_TRUE;
4198 it->position = eina_list_count(itb->items);
4199 it->position_update = EINA_TRUE;
4201 if (wd->blocks != EINA_INLIST_GET(itb))
4203 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4214 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4215 if (it->item->before)
4217 wd->blocks = eina_inlist_prepend_relative
4218 (wd->blocks, EINA_INLIST_GET(itb),
4219 EINA_INLIST_GET(it->item->rel->item->block));
4221 eina_list_prepend_relative_list(itb->items, it, tmp);
4223 /* Update index from where we prepended */
4224 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4225 _item_block_position_update(EINA_INLIST_GET(itb),
4226 it->item->rel->item->block->position);
4230 wd->blocks = eina_inlist_append_relative
4231 (wd->blocks, EINA_INLIST_GET(itb),
4232 EINA_INLIST_GET(it->item->rel->item->block));
4234 eina_list_append_relative_list(itb->items, it, tmp);
4236 /* Update block index from where we appended */
4237 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4238 _item_block_position_update(EINA_INLIST_GET(itb),
4239 it->item->rel->item->block->position + 1);
4245 if (it->item->before)
4249 itb = (Item_Block *)(wd->blocks);
4250 if (itb->count >= wd->max_items_per_block)
4252 itb = _item_block_new(wd, EINA_TRUE);
4253 if (!itb) return EINA_FALSE;
4258 itb = _item_block_new(wd, EINA_TRUE);
4259 if (!itb) return EINA_FALSE;
4261 itb->items = eina_list_prepend(itb->items, it);
4263 _item_position_update(itb->items, 0);
4269 itb = (Item_Block *)(wd->blocks->last);
4270 if (itb->count >= wd->max_items_per_block)
4272 itb = _item_block_new(wd, EINA_FALSE);
4273 if (!itb) return EINA_FALSE;
4278 itb = _item_block_new(wd, EINA_FALSE);
4279 if (!itb) return EINA_FALSE;
4281 itb->items = eina_list_append(itb->items, it);
4282 it->position = eina_list_count(itb->items);
4290 if (it->item->rel->item->queued)
4292 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
4293 on sorted insertion order, so the queue is not always ordered like the item list.
4294 This lead to issue where we depend on an item that is not yet created. As a quick
4295 work around, we reschedule the calc of the item and stop reordering the list to
4296 prevent any nasty issue to show up here.
4298 wd->queue = eina_list_append(wd->queue, it);
4299 wd->requeued = EINA_TRUE;
4300 it->item->queued = EINA_TRUE;
4303 itb = it->item->rel->item->block;
4304 if (!itb) goto newblock;
4305 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4306 if (it->item->before)
4308 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4309 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4313 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4314 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4318 itb->changed = EINA_TRUE;
4319 it->item->block = itb;
4320 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
4321 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
4324 it->item->rel->relcount--;
4325 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
4327 _item_del(it->item->rel);
4328 elm_widget_item_free(it->item->rel);
4330 it->item->rel = NULL;
4332 if (itb->count > itb->wd->max_items_per_block)
4337 Eina_Bool done = EINA_FALSE;
4339 newc = itb->count / 2;
4341 if (EINA_INLIST_GET(itb)->prev)
4343 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4345 if (itbp->count + newc < wd->max_items_per_block / 2)
4347 /* moving items to previous block */
4348 while ((itb->count > newc) && (itb->items))
4350 it2 = eina_list_data_get(itb->items);
4351 itb->items = eina_list_remove_list(itb->items, itb->items);
4354 itbp->items = eina_list_append(itbp->items, it2);
4355 it2->item->block = itbp;
4363 if (!done && EINA_INLIST_GET(itb)->next)
4365 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4367 if (itbn->count + newc < wd->max_items_per_block / 2)
4369 /* moving items to next block */
4370 while ((itb->count > newc) && (itb->items))
4374 l = eina_list_last(itb->items);
4375 it2 = eina_list_data_get(l);
4376 itb->items = eina_list_remove_list(itb->items, l);
4379 itbn->items = eina_list_prepend(itbn->items, it2);
4380 it2->item->block = itbn;
4390 /* moving items to new block */
4391 itb2 = calloc(1, sizeof(Item_Block));
4392 if (!itb2) return EINA_FALSE;
4395 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4396 EINA_INLIST_GET(itb));
4397 itb2->changed = EINA_TRUE;
4398 while ((itb->count > newc) && (itb->items))
4402 l = eina_list_last(itb->items);
4404 itb->items = eina_list_remove_list(itb->items, l);
4407 itb2->items = eina_list_prepend(itb2->items, it2);
4408 it2->item->block = itb2;
4418 _queue_process(Widget_Data *wd)
4421 Eina_Bool showme = EINA_FALSE;
4424 t0 = ecore_loop_time_get();
4425 //evas_event_freeze(evas_object_evas_get(wd->obj));
4426 for (n = 0; (wd->queue) && (n < 128); n++)
4430 it = eina_list_data_get(wd->queue);
4431 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4432 it->item->queued = EINA_FALSE;
4433 if (!_item_block_add(wd, it)) continue;
4435 _item_block_realize(it->item->block);
4436 t = ecore_time_get();
4437 if (it->item->block->changed)
4439 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4440 it->item->block->changed = 0;
4441 if (wd->pan_changed)
4443 if (wd->calc_job) ecore_job_del(wd->calc_job);
4444 wd->calc_job = NULL;
4446 wd->pan_changed = EINA_FALSE;
4449 if (showme) it->item->block->showme = EINA_TRUE;
4450 /* same as eina_inlist_count > 1 */
4451 if (wd->blocks && wd->blocks->next)
4453 if ((t - t0) > (ecore_animator_frametime_get())) break;
4456 //evas_event_thaw(evas_object_evas_get(wd->obj));
4457 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4462 _idle_process(void *data, Eina_Bool *wakeup)
4464 Widget_Data *wd = data;
4467 //static double q_start = 0.0;
4468 //if (q_start == 0.0) q_start = ecore_time_get();
4470 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4474 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4476 return ECORE_CALLBACK_CANCEL;
4478 return ECORE_CALLBACK_RENEW;
4482 _item_idle_enterer(void *data)
4484 Widget_Data *wd = data;
4485 Eina_Bool wakeup = EINA_FALSE;
4486 Eina_Bool ok = _idle_process(data, &wakeup);
4491 if (wd->calc_job) ecore_job_del(wd->calc_job);
4492 wd->calc_job = ecore_job_add(_calc_job, wd);
4494 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4499 _item_queue(Widget_Data *wd,
4503 if (it->item->queued) return;
4504 it->item->queued = EINA_TRUE;
4505 if (cb && !wd->requeued)
4506 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4508 wd->queue = eina_list_append(wd->queue, it);
4509 // FIXME: why does a freeze then thaw here cause some genlist
4510 // elm_genlist_item_append() to be much much slower?
4511 // evas_event_freeze(evas_object_evas_get(wd->obj));
4512 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4514 if (wd->queue_idle_enterer)
4516 ecore_idle_enterer_del(wd->queue_idle_enterer);
4517 wd->queue_idle_enterer = NULL;
4521 // evas_event_thaw(evas_object_evas_get(wd->obj));
4522 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4523 if (!wd->queue_idle_enterer)
4524 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4528 _elm_genlist_item_compare(const void *data, const void *data1)
4530 const Elm_Gen_Item *it, *item1;
4531 it = ELM_GEN_ITEM_FROM_INLIST(data);
4532 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4533 return it->wd->item_compare_cb(it, item1);
4537 _elm_genlist_item_list_compare(const void *data, const void *data1)
4539 const Elm_Gen_Item *it = data;
4540 const Elm_Gen_Item *item1 = data1;
4541 return it->wd->item_compare_cb(it, item1);
4545 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4550 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4551 _item_block_del(it);
4553 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4554 it->item->rel = after;
4555 it->item->rel->relcount++;
4556 it->item->before = EINA_FALSE;
4557 if (after->item->group_item) it->item->group_item = after->item->group_item;
4558 _item_queue(it->wd, it, NULL);
4560 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4564 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4567 if (!before) return;
4569 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4570 _item_block_del(it);
4571 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4572 it->item->rel = before;
4573 it->item->rel->relcount++;
4574 it->item->before = EINA_TRUE;
4575 if (before->item->group_item) it->item->group_item = before->item->group_item;
4576 _item_queue(it->wd, it, NULL);
4578 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4582 elm_genlist_items_count(const Evas_Object *obj)
4584 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4585 Widget_Data *wd = elm_widget_data_get(obj);
4587 return wd->item_count;
4590 EAPI Elm_Object_Item *
4591 elm_genlist_item_append(Evas_Object *obj,
4592 const Elm_Genlist_Item_Class *itc,
4594 Elm_Object_Item *parent,
4595 Elm_Genlist_Item_Type type,
4597 const void *func_data)
4599 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4600 Widget_Data *wd = elm_widget_data_get(obj);
4601 if (!wd) return NULL;
4602 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4604 if (!it) return NULL;
4608 wd->group_items = eina_list_append(wd->group_items, it);
4609 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4610 it->item->rel = NULL;
4614 Elm_Gen_Item *it2 = NULL;
4615 Eina_List *ll = eina_list_last(it->parent->item->items);
4616 if (ll) it2 = ll->data;
4617 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4618 if (!it2) it2 = it->parent;
4620 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4621 EINA_INLIST_GET(it2));
4622 it->item->rel = it2;
4623 it->item->rel->relcount++;
4625 it->item->before = EINA_FALSE;
4626 _item_queue(wd, it, NULL);
4627 return (Elm_Object_Item *)it;
4630 EAPI Elm_Object_Item *
4631 elm_genlist_item_prepend(Evas_Object *obj,
4632 const Elm_Genlist_Item_Class *itc,
4634 Elm_Object_Item *parent,
4635 Elm_Genlist_Item_Type type,
4637 const void *func_data)
4639 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4640 Widget_Data *wd = elm_widget_data_get(obj);
4641 if (!wd) return NULL;
4642 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4644 if (!it) return NULL;
4648 wd->group_items = eina_list_prepend(wd->group_items, it);
4649 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4650 it->item->rel = NULL;
4654 Elm_Gen_Item *it2 = NULL;
4655 Eina_List *ll = it->parent->item->items;
4656 if (ll) it2 = ll->data;
4657 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4658 if (!it2) it2 = it->parent;
4660 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4661 EINA_INLIST_GET(it2));
4662 it->item->rel = it2;
4663 it->item->rel->relcount++;
4665 it->item->before = EINA_TRUE;
4666 _item_queue(wd, it, NULL);
4667 return (Elm_Object_Item *)it;
4670 EAPI Elm_Object_Item *
4671 elm_genlist_item_insert_after(Evas_Object *obj,
4672 const Elm_Genlist_Item_Class *itc,
4674 Elm_Object_Item *parent,
4675 Elm_Object_Item *after,
4676 Elm_Genlist_Item_Type type,
4678 const void *func_data)
4680 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4681 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4682 Widget_Data *wd = elm_widget_data_get(obj);
4683 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4684 if (!wd) return NULL;
4685 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4686 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4688 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4690 if (!it) return NULL;
4693 if ((it->group) && (_after->group))
4694 wd->group_items = eina_list_append_relative(wd->group_items, it,
4699 it->parent->item->items =
4700 eina_list_append_relative(it->parent->item->items, it, _after);
4702 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4703 EINA_INLIST_GET(_after));
4704 it->item->rel = _after;
4705 it->item->rel->relcount++;
4706 it->item->before = EINA_FALSE;
4707 _item_queue(wd, it, NULL);
4708 return (Elm_Object_Item *)it;
4711 EAPI Elm_Object_Item *
4712 elm_genlist_item_insert_before(Evas_Object *obj,
4713 const Elm_Genlist_Item_Class *itc,
4715 Elm_Object_Item *parent,
4716 Elm_Object_Item *before,
4717 Elm_Genlist_Item_Type type,
4719 const void *func_data)
4721 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4722 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4723 Widget_Data *wd = elm_widget_data_get(obj);
4724 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4725 if (!wd) return NULL;
4726 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4727 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4729 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4731 if (!it) return NULL;
4734 if (it->group && _before->group)
4735 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4740 it->parent->item->items =
4741 eina_list_prepend_relative(it->parent->item->items, it, _before);
4743 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4744 EINA_INLIST_GET(_before));
4745 it->item->rel = _before;
4746 it->item->rel->relcount++;
4747 it->item->before = EINA_TRUE;
4748 _item_queue(wd, it, NULL);
4749 return (Elm_Object_Item *)it;
4752 EAPI Elm_Object_Item *
4753 elm_genlist_item_sorted_insert(Evas_Object *obj,
4754 const Elm_Genlist_Item_Class *itc,
4756 Elm_Object_Item *parent,
4757 Elm_Genlist_Item_Type type,
4758 Eina_Compare_Cb comp,
4760 const void *func_data)
4762 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4763 Widget_Data *wd = elm_widget_data_get(obj);
4764 if (!wd) return NULL;
4765 Elm_Gen_Item *rel = NULL;
4766 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4768 if (!it) return NULL;
4770 wd->item_compare_cb = comp;
4777 l = eina_list_search_sorted_near_list(it->parent->item->items,
4778 _elm_genlist_item_list_compare,
4782 rel = eina_list_data_get(l);
4786 if (cmp_result >= 0)
4788 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4789 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4790 it->item->before = EINA_FALSE;
4792 else if (cmp_result < 0)
4794 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4795 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4796 it->item->before = EINA_TRUE;
4803 wd->state = eina_inlist_sorted_state_new();
4804 eina_inlist_sorted_state_init(wd->state, wd->items);
4805 wd->requeued = EINA_FALSE;
4809 wd->group_items = eina_list_append(wd->group_items, it);
4811 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4812 _elm_genlist_item_compare, wd->state);
4814 if (EINA_INLIST_GET(it)->next)
4816 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4817 it->item->before = EINA_TRUE;
4819 else if (EINA_INLIST_GET(it)->prev)
4821 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4822 it->item->before = EINA_FALSE;
4828 it->item->rel = rel;
4829 it->item->rel->relcount++;
4832 _item_queue(wd, it, _elm_genlist_item_list_compare);
4834 return (Elm_Object_Item *)it;
4838 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4840 Eina_Inlist *next, *l;
4841 Widget_Data *wd = elm_widget_data_get(obj);
4844 if (!standby) wd->generation++;
4848 eina_inlist_sorted_state_free(wd->state);
4852 if (wd->walking > 0)
4854 wd->clear_me = EINA_TRUE;
4857 evas_event_freeze(evas_object_evas_get(wd->obj));
4858 for (l = wd->items, next = l ? l->next : NULL;
4860 l = next, next = next ? next->next : NULL)
4862 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4864 if (it->generation < wd->generation)
4866 Elm_Gen_Item *itn = NULL;
4868 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4869 if (itn) itn->walking++; /* prevent early death of subitem */
4871 elm_widget_item_free(it);
4872 if (itn) itn->walking--;
4875 wd->clear_me = EINA_FALSE;
4876 wd->pan_changed = EINA_TRUE;
4879 ecore_job_del(wd->calc_job);
4880 wd->calc_job = NULL;
4882 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4883 if (wd->clear_cb) wd->clear_cb(wd);
4889 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4890 wd->alpha_bg = NULL;
4894 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4895 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4897 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4898 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4899 evas_event_thaw(evas_object_evas_get(wd->obj));
4900 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4904 elm_genlist_clear(Evas_Object *obj)
4906 ELM_CHECK_WIDTYPE(obj, widtype);
4907 _elm_genlist_clear(obj, EINA_FALSE);
4911 elm_genlist_multi_select_set(Evas_Object *obj,
4914 ELM_CHECK_WIDTYPE(obj, widtype);
4915 Widget_Data *wd = elm_widget_data_get(obj);
4917 wd->multi = !!multi;
4921 elm_genlist_multi_select_get(const Evas_Object *obj)
4923 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4924 Widget_Data *wd = elm_widget_data_get(obj);
4925 if (!wd) return EINA_FALSE;
4929 EAPI Elm_Object_Item *
4930 elm_genlist_selected_item_get(const Evas_Object *obj)
4932 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4933 Widget_Data *wd = elm_widget_data_get(obj);
4934 if (!wd) return NULL;
4935 if (wd->selected) return wd->selected->data;
4939 EAPI const Eina_List *
4940 elm_genlist_selected_items_get(const Evas_Object *obj)
4942 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4943 Widget_Data *wd = elm_widget_data_get(obj);
4944 if (!wd) return NULL;
4945 return wd->selected;
4949 elm_genlist_realized_items_get(const Evas_Object *obj)
4951 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4952 Widget_Data *wd = elm_widget_data_get(obj);
4953 Eina_List *list = NULL;
4955 Eina_Bool done = EINA_FALSE;
4956 if (!wd) return NULL;
4957 EINA_INLIST_FOREACH(wd->blocks, itb)
4965 EINA_LIST_FOREACH(itb->items, l, it)
4967 if (it->realized) list = eina_list_append(list, it);
4978 EAPI Elm_Object_Item *
4979 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4984 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4985 Widget_Data *wd = elm_widget_data_get(obj);
4986 Evas_Coord ox, oy, ow, oh;
4989 if (!wd) return NULL;
4990 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4992 EINA_INLIST_FOREACH(wd->blocks, itb)
4997 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4998 oy + itb->y - itb->wd->pan_y,
4999 itb->w, itb->h, x, y, 1, 1))
5001 EINA_LIST_FOREACH(itb->items, l, it)
5003 Evas_Coord itx, ity;
5005 itx = ox + itb->x + it->x - itb->wd->pan_x;
5006 ity = oy + itb->y + it->y - itb->wd->pan_y;
5007 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5011 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5012 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5016 return (Elm_Object_Item *)it;
5018 lasty = ity + it->item->h;
5023 if (y > lasty) *posret = 1;
5029 EAPI Elm_Object_Item *
5030 elm_genlist_first_item_get(const Evas_Object *obj)
5032 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5033 Widget_Data *wd = elm_widget_data_get(obj);
5034 if (!wd) return NULL;
5035 if (!wd->items) return NULL;
5036 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
5037 while ((it) && (it->generation < wd->generation))
5038 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5039 return (Elm_Object_Item *)it;
5042 EAPI Elm_Object_Item *
5043 elm_genlist_last_item_get(const Evas_Object *obj)
5045 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5046 Widget_Data *wd = elm_widget_data_get(obj);
5047 if (!wd) return NULL;
5048 if (!wd->items) return NULL;
5049 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
5050 while ((it) && (it->generation < wd->generation))
5051 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5052 return (Elm_Object_Item *)it;
5055 EAPI Elm_Object_Item *
5056 elm_genlist_item_next_get(const Elm_Object_Item *it)
5058 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5059 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5062 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
5063 if ((_it) && (_it->generation == _it->wd->generation)) break;
5065 return (Elm_Object_Item *) _it;
5068 EAPI Elm_Object_Item *
5069 elm_genlist_item_prev_get(const Elm_Object_Item *it)
5071 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5072 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5075 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
5076 if ((_it) && (_it->generation == _it->wd->generation)) break;
5078 return (Elm_Object_Item *) _it;
5081 EAPI Elm_Object_Item *
5082 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5084 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5085 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
5089 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
5091 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5092 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
5094 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5096 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
5097 _item_subitems_clear(_it);
5100 if (!wd->item_moving_effect_timer)
5102 wd->expanded_item = _it;
5103 _item_tree_effect_before(_it);
5104 evas_object_raise(wd->alpha_bg);
5105 evas_object_show(wd->alpha_bg);
5106 wd->start_time = ecore_time_get();
5107 wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, wd);
5110 _item_subitems_clear(_it);
5115 elm_genlist_item_selected_set(Elm_Object_Item *it,
5118 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5119 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5120 Widget_Data *wd = _it->wd;
5122 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
5124 selected = !!selected;
5125 if (_it->selected == selected) return;
5131 while (wd->selected)
5133 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
5134 _it->unsel_cb(wd->selected->data);
5137 _it->highlight_cb(_it);
5141 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
5146 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5148 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5149 return ((Elm_Gen_Item *)it)->selected;
5153 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5156 if (it->item->expanded)
5158 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5162 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5165 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5166 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5173 _elm_genlist_move_items_set(Elm_Gen_Item *it)
5176 Elm_Gen_Item *it2 = NULL;
5177 Evas_Coord ox, oy, ow, oh, dh = 0;
5179 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
5181 if (it->item->expanded)
5183 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
5184 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
5186 if (it2 == it->wd->expanded_next_item) break;
5187 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
5192 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
5193 it2 = it->wd->expanded_next_item;
5194 while (it2 && (dh < oy + oh))
5197 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
5198 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5204 elm_genlist_item_expanded_set(Elm_Object_Item *it,
5207 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5208 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5209 expanded = !!expanded;
5210 if (_it->item->expanded == expanded) return;
5211 _it->item->expanded = expanded;
5212 _it->wd->expanded_item = _it;
5213 _elm_genlist_move_items_set(_it);
5215 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
5216 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
5218 if (_it->item->expanded)
5220 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
5222 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
5223 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
5224 _it->wd->auto_scroll_enabled = EINA_TRUE;
5228 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
5230 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
5231 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
5232 _it->wd->auto_scroll_enabled = EINA_FALSE;
5237 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5239 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5240 return ((Elm_Gen_Item *)it)->item->expanded;
5244 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5246 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
5247 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5250 EINA_DEPRECATED EAPI void
5251 elm_genlist_item_display_only_set(Elm_Object_Item *it,
5252 Eina_Bool display_only)
5254 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5255 display_only = !!display_only;
5258 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
5261 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5262 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5263 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
5267 EINA_DEPRECATED EAPI Eina_Bool
5268 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
5270 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5271 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5272 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5273 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5274 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5280 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
5281 Elm_Genlist_Item_Scrollto_Type type,
5287 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5288 Evas_Coord gith = 0;
5289 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5290 if ((_it->item->queued) || (!_it->item->mincalcd))
5292 _it->wd->show_item = _it;
5293 _it->wd->bring_in = EINA_FALSE;
5294 _it->wd->scrollto_type = type;
5295 _it->item->showme = EINA_TRUE;
5298 if (_it->wd->show_item)
5300 _it->wd->show_item->item->showme = EINA_FALSE;
5301 _it->wd->show_item = NULL;
5304 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
5305 if (type==ELM_GENLIST_ITEM_SCROLLTO_IN)
5307 if ((_it->item->group_item) &&
5308 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
5309 gith = _it->item->group_item->item->h;
5312 *y = _it->y + _it->item->block->y - gith;
5314 else if (type==ELM_GENLIST_ITEM_SCROLLTO_TOP)
5316 if (_it->item->group_item) gith = _it->item->group_item->item->h;
5317 *y = _it->y + _it->item->block->y - gith;
5319 else if (type==ELM_GENLIST_ITEM_SCROLLTO_MIDDLE)
5321 *y = _it->y + _it->item->block->y - *h / 2 + _it->item->h / 2;
5326 *x = _it->x + _it->item->block->x;
5327 *w = _it->item->block->w;
5332 elm_genlist_item_promote(Elm_Object_Item *it)
5334 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5335 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5336 if (_it->generation < _it->wd->generation) return;
5337 _item_move_before(_it,
5338 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
5342 elm_genlist_item_demote(Elm_Object_Item *it)
5344 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5345 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5346 if (_it->generation < _it->wd->generation) return;
5347 _item_move_after(_it,
5348 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
5352 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5354 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5355 Evas_Coord x, y, w, h;
5356 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5358 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
5359 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
5363 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5366 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5367 Evas_Coord x, y, w, h;
5368 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5370 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
5371 elm_smart_scroller_region_bring_in(_it->wd->scr,x, y, w, h);
5375 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5377 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5379 Evas_Object *content;
5380 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5382 elm_widget_sub_object_del(WIDGET(it), content);
5383 evas_object_smart_member_del(content);
5384 evas_object_hide(content);
5386 *l = eina_list_append(*l, content);
5391 elm_genlist_item_update(Elm_Object_Item *it)
5393 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5394 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5396 if (!_it->item->block) return;
5397 if (_it->generation < _it->wd->generation) return;
5398 _it->item->mincalcd = EINA_FALSE;
5399 _it->item->updateme = EINA_TRUE;
5400 _it->item->block->updateme = EINA_TRUE;
5401 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5402 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5406 elm_genlist_item_fields_update(Elm_Object_Item *it,
5408 Elm_Genlist_Item_Field_Type itf)
5410 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5411 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5413 if (!_it->item->block) return;
5414 if (_it->generation < _it->wd->generation) return;
5416 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5417 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5418 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5420 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5421 &_it->contents, parts);
5422 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5423 &_it->contents, parts);
5427 _it->content_objs = _item_mode_content_unrealize(_it, VIEW(_it),
5428 &_it->contents, parts, &_it->content_objs, "flips");
5429 _it->content_objs = _item_mode_content_realize(_it, VIEW(_it),
5430 &_it->contents, parts, &_it->content_objs, "flips");
5433 if (_it->item->mode_view)
5435 _it->item->mode_content_objs = _item_mode_content_unrealize(_it, _it->item->mode_view,
5436 &_it->item->mode_contents, parts, &_it->item->mode_content_objs, "contents");
5437 _it->item->mode_content_objs = _item_mode_content_realize(_it, _it->item->mode_view,
5438 &_it->item->mode_contents, parts, &_it->item->mode_content_objs, "contents");
5441 if (_it->wd->decorate_mode)
5443 _it->item->edit_content_objs = _item_mode_content_unrealize(_it, _it->edit_obj,
5444 &_it->contents, parts, &_it->item->edit_content_objs, "decorate_contents");
5445 _it->item->edit_content_objs = _item_mode_content_realize(_it, _it->edit_obj,
5446 &_it->contents, parts, &_it->item->edit_content_objs, "decorate_contents"); // FIXME: is it "decorate_contents"??
5449 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5450 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5454 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5455 const Elm_Genlist_Item_Class *itc)
5457 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5458 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5460 if (!_it->item->block) return;
5461 EINA_SAFETY_ON_NULL_RETURN(itc);
5462 if (_it->generation < _it->wd->generation) return;
5464 _it->item->nocache_once = EINA_TRUE;
5465 elm_genlist_item_update(it);
5468 EAPI const Elm_Genlist_Item_Class *
5469 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5471 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5472 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5473 if (_it->generation < _it->wd->generation) return NULL;
5477 static Evas_Object *
5478 _elm_genlist_item_label_create(void *data,
5479 Evas_Object *obj __UNUSED__,
5480 Evas_Object *tooltip,
5481 void *it __UNUSED__)
5483 Evas_Object *label = elm_label_add(tooltip);
5486 elm_object_style_set(label, "tooltip");
5487 elm_object_text_set(label, data);
5492 _elm_genlist_item_label_del_cb(void *data,
5493 Evas_Object *obj __UNUSED__,
5494 void *event_info __UNUSED__)
5496 eina_stringshare_del(data);
5500 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5503 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5504 text = eina_stringshare_add(text);
5505 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5507 _elm_genlist_item_label_del_cb);
5511 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5512 Elm_Tooltip_Item_Content_Cb func,
5514 Evas_Smart_Cb del_cb)
5516 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5517 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5519 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5522 if (_it->tooltip.del_cb)
5523 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5525 _it->tooltip.content_cb = func;
5526 _it->tooltip.data = data;
5527 _it->tooltip.del_cb = del_cb;
5531 elm_widget_item_tooltip_content_cb_set(_it,
5532 _it->tooltip.content_cb,
5533 _it->tooltip.data, NULL);
5534 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5535 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5541 if (del_cb) del_cb((void *)data, NULL, NULL);
5545 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5547 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5548 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5550 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5551 elm_widget_item_tooltip_unset(_it);
5553 if (_it->tooltip.del_cb)
5554 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5555 _it->tooltip.del_cb = NULL;
5556 _it->tooltip.content_cb = NULL;
5557 _it->tooltip.data = NULL;
5558 _it->tooltip.free_size = EINA_FALSE;
5559 if (_it->tooltip.style)
5560 elm_genlist_item_tooltip_style_set(it, NULL);
5564 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5567 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5568 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5570 eina_stringshare_replace(&_it->tooltip.style, style);
5571 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5575 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5577 return elm_object_item_tooltip_style_get(it);
5581 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5584 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5585 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5587 _it->tooltip.free_size = disable;
5588 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5593 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5595 return elm_object_tooltip_window_mode_get(VIEW(it));
5599 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5602 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5603 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5604 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5605 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5609 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5611 return elm_widget_item_cursor_get(it);
5615 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5617 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5618 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5620 if (!_it->mouse_cursor) return;
5622 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5624 eina_stringshare_del(_it->mouse_cursor);
5625 _it->mouse_cursor = NULL;
5629 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5632 elm_widget_item_cursor_style_set(it, style);
5636 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5638 return elm_widget_item_cursor_style_get(it);
5642 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5643 Eina_Bool engine_only)
5645 elm_widget_item_cursor_engine_only_set(it, engine_only);
5649 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5651 return elm_widget_item_cursor_engine_only_get(it);
5655 elm_genlist_item_index_get(const Elm_Object_Item *it)
5657 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5658 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5660 if (_it->item->block)
5661 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5666 elm_genlist_mode_set(Evas_Object *obj,
5669 ELM_CHECK_WIDTYPE(obj, widtype);
5670 Widget_Data *wd = elm_widget_data_get(obj);
5672 if (wd->mode == mode) return;
5674 if (wd->mode == ELM_LIST_COMPRESS)
5675 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5681 elm_genlist_mode_get(const Evas_Object *obj)
5683 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5684 Widget_Data *wd = elm_widget_data_get(obj);
5685 if (!wd) return ELM_LIST_LAST;
5690 elm_genlist_bounce_set(Evas_Object *obj,
5694 ELM_CHECK_WIDTYPE(obj, widtype);
5695 Widget_Data *wd = elm_widget_data_get(obj);
5697 wd->h_bounce = !!h_bounce;
5698 wd->v_bounce = !!v_bounce;
5699 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5703 elm_genlist_bounce_get(const Evas_Object *obj,
5704 Eina_Bool *h_bounce,
5705 Eina_Bool *v_bounce)
5707 ELM_CHECK_WIDTYPE(obj, widtype);
5708 Widget_Data *wd = elm_widget_data_get(obj);
5710 if (h_bounce) *h_bounce = wd->h_bounce;
5711 if (v_bounce) *v_bounce = wd->v_bounce;
5715 elm_genlist_homogeneous_set(Evas_Object *obj,
5716 Eina_Bool homogeneous)
5718 ELM_CHECK_WIDTYPE(obj, widtype);
5719 Widget_Data *wd = elm_widget_data_get(obj);
5721 if (homogeneous) elm_genlist_mode_set(obj, ELM_LIST_COMPRESS);
5722 wd->homogeneous = !!homogeneous;
5726 elm_genlist_homogeneous_get(const Evas_Object *obj)
5728 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5729 Widget_Data *wd = elm_widget_data_get(obj);
5730 if (!wd) return EINA_FALSE;
5731 return wd->homogeneous;
5735 elm_genlist_block_count_set(Evas_Object *obj,
5738 ELM_CHECK_WIDTYPE(obj, widtype);
5739 Widget_Data *wd = elm_widget_data_get(obj);
5741 wd->max_items_per_block = count;
5742 wd->item_cache_max = wd->max_items_per_block * 2;
5743 _item_cache_clean(wd);
5747 elm_genlist_block_count_get(const Evas_Object *obj)
5749 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5750 Widget_Data *wd = elm_widget_data_get(obj);
5752 return wd->max_items_per_block;
5756 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5759 ELM_CHECK_WIDTYPE(obj, widtype);
5760 Widget_Data *wd = elm_widget_data_get(obj);
5762 wd->longpress_timeout = timeout;
5766 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5768 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5769 Widget_Data *wd = elm_widget_data_get(obj);
5771 return wd->longpress_timeout;
5775 elm_genlist_scroller_policy_set(Evas_Object *obj,
5776 Elm_Scroller_Policy policy_h,
5777 Elm_Scroller_Policy policy_v)
5779 ELM_CHECK_WIDTYPE(obj, widtype);
5780 Widget_Data *wd = elm_widget_data_get(obj);
5781 if ((!wd) || (!wd->scr)) return;
5782 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5783 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5785 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5789 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5790 Elm_Scroller_Policy *policy_h,
5791 Elm_Scroller_Policy *policy_v)
5793 ELM_CHECK_WIDTYPE(obj, widtype);
5794 Widget_Data *wd = elm_widget_data_get(obj);
5795 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5796 if ((!wd) || (!wd->scr)) return;
5797 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5798 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5799 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5803 elm_genlist_realized_items_update(Evas_Object *obj)
5805 ELM_CHECK_WIDTYPE(obj, widtype);
5807 Eina_List *list, *l;
5808 Elm_Object_Item *it;
5810 list = elm_genlist_realized_items_get(obj);
5811 EINA_LIST_FOREACH(list, l, it)
5812 elm_genlist_item_update(it);
5816 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5817 const char *decorate_type,
5820 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5821 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5823 Widget_Data *wd = _it->wd;
5825 Elm_Object_Item *it2;
5828 if (!decorate_type) return;
5829 if ((_it->generation < _it->wd->generation) ||
5830 elm_widget_item_disabled_get(_it)) return;
5831 if (wd->decorate_mode) return;
5833 if ((wd->mode_item == _it) &&
5834 (!strcmp(decorate_type, wd->decorate_type)) &&
5837 if (!_it->itc->decorate_item_style) return;
5838 _it->mode_set = mode_set;
5842 EINA_LIST_FOREACH(wd->selected, l, it2)
5843 if (((Elm_Gen_Item *)it2)->realized)
5844 elm_genlist_item_selected_set(it2, EINA_FALSE);
5848 it2 = elm_genlist_selected_item_get(wd->obj);
5849 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5850 elm_genlist_item_selected_set(it2, EINA_FALSE);
5853 if (((wd->decorate_type) && (strcmp(decorate_type, wd->decorate_type))) ||
5855 ((_it == wd->mode_item) && (!mode_set)))
5856 _item_mode_unset(wd);
5858 eina_stringshare_replace(&wd->decorate_type, decorate_type);
5859 if (mode_set) _item_mode_set(_it);
5863 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5865 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5866 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5867 return _it->wd->decorate_type;
5870 EAPI const Elm_Object_Item *
5871 elm_genlist_decorated_item_get(const Evas_Object *obj)
5873 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5874 Widget_Data *wd = elm_widget_data_get(obj);
5875 if (!wd) return NULL;
5876 return (Elm_Object_Item *) wd->mode_item;
5880 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5882 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5883 Widget_Data *wd = elm_widget_data_get(obj);
5884 if (!wd) return EINA_FALSE;
5886 return wd->decorate_mode;
5890 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5892 ELM_CHECK_WIDTYPE(obj, widtype);
5893 Eina_List *list, *l;
5896 Widget_Data *wd = elm_widget_data_get(obj);
5898 decorated = !!decorated;
5899 if (wd->decorate_mode == decorated) return;
5900 wd->decorate_mode = decorated;
5902 list = elm_genlist_realized_items_get(obj);
5903 if (!wd->decorate_mode)
5905 EINA_LIST_FOREACH(list, l, it)
5907 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5908 _decorate_mode_item_unrealize(it);
5910 _item_cache_zero(wd);
5914 EINA_LIST_FOREACH(list, l, it)
5916 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5918 if (it->selected) _item_unselect(it);
5919 if (it->itc->decorate_all_item_style)
5920 _decorate_mode_item_realize(it, EINA_TRUE);
5924 if (wd->calc_job) ecore_job_del(wd->calc_job);
5925 wd->calc_job = ecore_job_add(_calc_job, wd);
5929 elm_genlist_reorder_mode_set(Evas_Object *obj,
5930 Eina_Bool reorder_mode)
5932 ELM_CHECK_WIDTYPE(obj, widtype);
5933 Widget_Data *wd = elm_widget_data_get(obj);
5935 wd->reorder_mode = !!reorder_mode;
5939 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5941 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5942 Widget_Data *wd = elm_widget_data_get(obj);
5943 if (!wd) return EINA_FALSE;
5944 return wd->reorder_mode;
5947 EAPI Elm_Genlist_Item_Type
5948 elm_genlist_item_type_get(const Elm_Object_Item *it)
5950 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5951 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5952 return _it->item->type;
5955 EAPI Elm_Genlist_Item_Class *
5956 elm_genlist_item_class_new(void)
5958 Elm_Genlist_Item_Class *itc;
5960 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5963 itc->version = CLASS_ALLOCATED;
5965 itc->delete_me = EINA_FALSE;
5971 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5973 if (itc && (itc->version == CLASS_ALLOCATED))
5975 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5976 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5986 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5988 if (itc && (itc->version == CLASS_ALLOCATED))
5991 if (itc->refcount == 0) itc->refcount--;
5996 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5998 if (itc && (itc->version == CLASS_ALLOCATED))
6000 if (itc->refcount > 0) itc->refcount--;
6001 if (itc->delete_me && (!itc->refcount))
6002 elm_genlist_item_class_free(itc);
6006 void _flip_job(void *data)
6008 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
6009 _elm_genlist_item_unrealize(it, EINA_FALSE);
6010 if (it->selected) _item_unselect(it);
6011 it->flipped = EINA_TRUE;
6012 it->item->nocache = EINA_TRUE;
6016 elm_genlist_item_flip_set(Elm_Object_Item *it,
6019 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6020 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6023 if (_it->flipped == flip) return;
6027 ecore_job_add(_flip_job, _it);
6028 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
6029 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
6033 _it->flipped = flip;
6034 _item_cache_zero(_it->wd);
6035 elm_genlist_item_update(it);
6036 _it->item->nocache = EINA_FALSE;
6041 elm_genlist_item_flip_get(const Elm_Object_Item *it)
6043 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6044 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6045 return _it->flipped;
6049 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
6051 ELM_CHECK_WIDTYPE(obj, widtype);
6052 Widget_Data *wd = elm_widget_data_get(obj);
6054 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6056 if (wd->select_mode != mode)
6057 wd->select_mode = mode;
6060 EAPI Elm_Object_Select_Mode
6061 elm_genlist_select_mode_get(const Evas_Object *obj)
6063 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
6064 Widget_Data *wd = elm_widget_data_get(obj);
6065 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
6066 return wd->select_mode;
6070 elm_genlist_highlight_mode_set(Evas_Object *obj,
6071 Eina_Bool highlight)
6073 ELM_CHECK_WIDTYPE(obj, widtype);
6074 Widget_Data *wd = elm_widget_data_get(obj);
6076 wd->highlight = !!highlight;
6080 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6082 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6083 Widget_Data *wd = elm_widget_data_get(obj);
6084 if (!wd) return EINA_FALSE;
6085 return wd->highlight;
6089 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
6090 Elm_Object_Select_Mode mode)
6092 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6093 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6095 if (_it->generation < _it->wd->generation) return;
6096 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6098 if (_it->select_mode != mode)
6099 _it->select_mode = mode;
6101 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6103 _it->item->mincalcd = EINA_FALSE;
6104 _it->item->updateme = EINA_TRUE;
6105 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
6106 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
6107 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
6111 EAPI Elm_Object_Select_Mode
6112 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
6114 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
6115 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6116 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
6117 return _it->select_mode;
6120 /* for gengrid as of now */
6122 _elm_genlist_page_relative_set(Evas_Object *obj,
6126 Evas_Coord pagesize_h;
6127 Evas_Coord pagesize_v;
6129 ELM_CHECK_WIDTYPE(obj, widtype);
6130 Widget_Data *wd = elm_widget_data_get(obj);
6133 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
6134 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
6138 /* for gengrid as of now */
6140 _elm_genlist_page_relative_get(const Evas_Object *obj,
6144 ELM_CHECK_WIDTYPE(obj, widtype);
6145 Widget_Data *wd = elm_widget_data_get(obj);
6148 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
6151 /* for gengrid as of now */
6153 _elm_genlist_page_size_set(Evas_Object *obj,
6154 Evas_Coord h_pagesize,
6155 Evas_Coord v_pagesize)
6160 ELM_CHECK_WIDTYPE(obj, widtype);
6161 Widget_Data *wd = elm_widget_data_get(obj);
6163 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
6164 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
6168 /* for gengrid as of now */
6170 _elm_genlist_current_page_get(const Evas_Object *obj,
6174 ELM_CHECK_WIDTYPE(obj, widtype);
6175 Widget_Data *wd = elm_widget_data_get(obj);
6177 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
6180 /* for gengrid as of now */
6182 _elm_genlist_last_page_get(const Evas_Object *obj,
6186 ELM_CHECK_WIDTYPE(obj, widtype);
6187 Widget_Data *wd = elm_widget_data_get(obj);
6189 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
6192 /* for gengrid as of now */
6194 _elm_genlist_page_show(const Evas_Object *obj,
6198 ELM_CHECK_WIDTYPE(obj, widtype);
6199 Widget_Data *wd = elm_widget_data_get(obj);
6201 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
6204 /* for gengrid as of now */
6206 _elm_genlist_page_bring_in(const Evas_Object *obj,
6210 ELM_CHECK_WIDTYPE(obj, widtype);
6211 Widget_Data *wd = elm_widget_data_get(obj);
6213 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
6217 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
6220 Evas_Object *content;
6222 if (!it->realized) return;
6223 if (it->wd->reorder_it == it) return;
6224 if (it->defer_unrealize && !it->item->updateme) return;
6226 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
6228 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
6231 ecore_timer_del(it->long_timer);
6232 it->long_timer = NULL;
6235 elm_widget_stringlist_free(it->texts);
6237 elm_widget_stringlist_free(it->contents);
6238 it->contents = NULL;
6239 elm_widget_stringlist_free(it->states);
6242 EINA_LIST_FREE(it->content_objs, content)
6243 evas_object_del(content);
6245 it->unrealize_cb(it);
6247 it->realized = EINA_FALSE;
6248 it->want_unrealize = EINA_FALSE;
6249 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
6250 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
6254 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
6256 elm_widget_item_pre_notify_del(it);
6257 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
6259 if ((it->relcount > 0) || (it->walking > 0))
6261 if (!it->item->block && (it->relcount == 1))
6263 if (it->item->rel && it->item->rel->item)
6265 it->item->rel->relcount--;
6266 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
6268 _item_del(it->item->rel);
6269 elm_widget_item_free(it->item->rel);
6271 it->item->rel = NULL;
6276 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6278 if (it->itc->func.del)
6279 it->itc->func.del((void *)it->base.data, WIDGET(it));
6283 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
6285 _elm_genlist_item_del_notserious(it);
6286 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6287 if (it->tooltip.del_cb)
6288 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6289 it->wd->walking -= it->walking;
6290 if (it->long_timer) ecore_timer_del(it->long_timer);
6292 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
6296 eina_inlist_sorted_state_free(it->wd->state);
6297 it->wd->state = NULL;
6299 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6300 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
6304 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
6305 it->wd->last_selected_item = NULL;
6306 it->wd->item_count--;
6310 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
6312 ELM_CHECK_WIDTYPE(obj, widtype);
6313 Widget_Data *wd = elm_widget_data_get(obj);
6315 wd->tree_effect_enabled = !!enabled;
6319 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
6321 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6322 Widget_Data *wd = elm_widget_data_get(obj);
6323 if (!wd) return EINA_FALSE;
6324 return wd->tree_effect_enabled;
6328 _create_tray_alpha_bg(const Evas_Object *obj)
6330 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6331 Widget_Data *wd = elm_widget_data_get(obj);
6332 if (!wd) return NULL;
6334 Evas_Object *bg = NULL;
6335 Evas_Coord ox, oy, ow, oh;
6337 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6338 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6339 evas_object_color_set(bg,0,0,0,0);
6340 evas_object_resize(bg , ow, oh);
6341 evas_object_move(bg , ox, oy);
6346 _item_contract_emit(Elm_Gen_Item *it)
6351 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6352 it->item->tree_effect_finished = EINA_FALSE;
6354 EINA_LIST_FOREACH(it->item->items, l, it2)
6355 if (it2) _item_contract_emit(it2);
6359 _item_tree_effect_before(Elm_Gen_Item *it)
6364 EINA_LIST_FOREACH(it->item->items, l, it2)
6366 if (it2->parent && (it == it2->parent))
6368 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6369 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6370 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6371 _item_contract_emit(it2);
6374 return ECORE_CALLBACK_CANCEL;
6378 _item_tree_effect(Widget_Data *wd, int y)
6380 Elm_Gen_Item *it = NULL, *expanded_next_it;
6382 expanded_next_it = wd->expanded_next_item;
6384 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6386 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6389 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6390 if (it->item->scrl_y && (it->item->scrl_y < expanded_next_it->item->old_scrl_y + y) &&
6391 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6393 if (!it->item->tree_effect_finished)
6395 edje_object_signal_emit(VIEW(it), "flip_item", "");
6396 evas_object_show(VIEW(it));
6397 it->item->tree_effect_finished = EINA_TRUE;
6400 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6403 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6405 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6408 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6409 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6411 if (!it->item->tree_effect_finished)
6413 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6414 it->item->tree_effect_finished = EINA_TRUE;
6419 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6425 _item_tree_effect_finish(Widget_Data *wd)
6428 Elm_Gen_Item *it = NULL;
6431 if (wd->item_moving_effect_timer)
6433 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6434 _item_subitems_clear(wd->expanded_item);
6435 EINA_INLIST_FOREACH(wd->blocks, itb)
6437 EINA_LIST_FOREACH(itb->items, l, it)
6439 it->item->tree_effect_finished = EINA_TRUE;
6440 it->item->old_scrl_y = it->item->scrl_y;
6444 _item_auto_scroll(wd);
6445 evas_object_lower(wd->alpha_bg);
6446 evas_object_hide(wd->alpha_bg);
6447 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6448 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6450 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6451 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6452 evas_object_smart_changed(wd->pan_smart);
6454 wd->item_moving_effect_timer = NULL;
6458 _item_moving_effect_timer_cb(void *data)
6460 Widget_Data *wd = data;
6461 if (!wd) return EINA_FALSE;
6462 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6463 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6465 double effect_duration = 0.5, t;
6466 int y = 0, dy = 0, dh = 0;
6467 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6470 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6471 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6472 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6473 if (t > effect_duration) end = EINA_TRUE;
6475 // Below while statement is needed, when the genlist is resized.
6476 it2 = wd->expanded_item;
6479 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6480 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6481 cvx, cvy, cvw, cvh));
6482 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6485 if (wd->expanded_next_item)
6487 expanded_next_it = wd->expanded_next_item;
6490 EINA_LIST_FOREACH(wd->move_items, l, it)
6492 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6494 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6495 if (expanded_next_it->item->scrl_y < expanded_next_it->item->old_scrl_y) //did not calculate next item position
6496 expanded_next_it->item->scrl_y = cvy + cvh;
6498 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6499 cvy + cvh : expanded_next_it->item->scrl_y) -
6500 expanded_next_it->item->old_scrl_y;
6502 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6504 if (expanded_next_it->item->scrl_y > expanded_next_it->item->old_scrl_y) //did not calculate next item position
6505 expanded_next_it->item->old_scrl_y = cvy + cvh;
6507 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6509 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6511 expanded_next_it->item->old_scrl_y = cvy + cvh;
6515 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6516 expanded_next_it->item->old_scrl_y;
6520 if (t <= effect_duration)
6522 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6532 _item_realize(it, in, 0);
6536 if (it != expanded_next_it)
6538 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6542 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6543 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6546 _item_tree_effect(wd, y);
6550 int expanded_item_num = 0;
6553 if (wd->expanded_item)
6554 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6559 expanded_item_num++;
6560 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6566 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6567 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6569 if (!it->item->tree_effect_finished)
6571 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6573 edje_object_signal_emit(VIEW(it), "flip_item", "");
6574 evas_object_show(VIEW(it));
6575 it->item->tree_effect_finished = EINA_TRUE;
6579 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6585 _item_tree_effect_finish(wd);
6586 return ECORE_CALLBACK_CANCEL;
6588 return ECORE_CALLBACK_RENEW;