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 elm_genlist_item_subitems_clear(it);
4047 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
4048 _elm_genlist_item_del_notserious(_it);
4049 if (_it->item->block)
4051 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
4052 _it->item->block->changed = EINA_TRUE;
4053 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
4054 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
4058 _it->parent->item->items =
4059 eina_list_remove(_it->parent->item->items, it);
4069 _item_signal_emit_hook(Elm_Object_Item *it,
4070 const char *emission,
4073 edje_object_signal_emit(VIEW(it), emission, source);
4077 _elm_genlist_item_new(Widget_Data *wd,
4078 const Elm_Gen_Item_Class *itc,
4080 Elm_Gen_Item *parent,
4082 const void *func_data)
4086 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
4087 if (!it) return NULL;
4089 it->generation = wd->generation;
4091 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
4092 it->base.data = data;
4093 it->parent = parent;
4094 it->func.func = func;
4095 it->func.data = func_data;
4096 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
4097 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
4098 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
4099 elm_widget_item_text_get_hook_set(it, _item_text_hook);
4100 elm_widget_item_disable_hook_set(it, _item_disable_hook);
4101 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
4102 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
4105 it->sel_cb = (Ecore_Cb)_item_select;
4110 static Elm_Gen_Item *
4111 _item_new(Widget_Data *wd,
4112 const Elm_Genlist_Item_Class *itc,
4114 Elm_Gen_Item *parent,
4115 Elm_Genlist_Item_Type type,
4117 const void *func_data)
4119 Elm_Gen_Item *it, *it2;
4122 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
4123 if (!it) return NULL;
4124 it->item = ELM_NEW(Elm_Gen_Item_Type);
4125 it->item->type = type;
4126 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
4127 it->item->expanded_depth = 0;
4128 ELM_GEN_ITEM_SETUP(it);
4129 it->mouse_cursor = NULL;
4130 it->can_focus = EINA_TRUE;
4133 if (it->parent->group)
4134 it->item->group_item = parent;
4135 else if (it->parent->item->group_item)
4136 it->item->group_item = it->parent->item->group_item;
4138 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
4140 if (!it2->parent->group) depth += 1;
4142 it->item->expanded_depth = depth;
4148 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
4152 itb = calloc(1, sizeof(Item_Block));
4153 if (!itb) return NULL;
4157 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
4158 _item_block_position_update(wd->blocks, 0);
4162 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4163 itb->position_update = EINA_TRUE;
4164 if (wd->blocks != EINA_INLIST_GET(itb))
4166 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4177 _item_block_add(Widget_Data *wd,
4180 Item_Block *itb = NULL;
4187 itb = calloc(1, sizeof(Item_Block));
4188 if (!itb) return EINA_FALSE;
4190 if (!it->item->rel->item->block)
4193 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4194 itb->items = eina_list_append(itb->items, it);
4195 itb->position_update = EINA_TRUE;
4196 it->position = eina_list_count(itb->items);
4197 it->position_update = EINA_TRUE;
4199 if (wd->blocks != EINA_INLIST_GET(itb))
4201 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4212 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4213 if (it->item->before)
4215 wd->blocks = eina_inlist_prepend_relative
4216 (wd->blocks, EINA_INLIST_GET(itb),
4217 EINA_INLIST_GET(it->item->rel->item->block));
4219 eina_list_prepend_relative_list(itb->items, it, tmp);
4221 /* Update index from where we prepended */
4222 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4223 _item_block_position_update(EINA_INLIST_GET(itb),
4224 it->item->rel->item->block->position);
4228 wd->blocks = eina_inlist_append_relative
4229 (wd->blocks, EINA_INLIST_GET(itb),
4230 EINA_INLIST_GET(it->item->rel->item->block));
4232 eina_list_append_relative_list(itb->items, it, tmp);
4234 /* Update block index from where we appended */
4235 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4236 _item_block_position_update(EINA_INLIST_GET(itb),
4237 it->item->rel->item->block->position + 1);
4243 if (it->item->before)
4247 itb = (Item_Block *)(wd->blocks);
4248 if (itb->count >= wd->max_items_per_block)
4250 itb = _item_block_new(wd, EINA_TRUE);
4251 if (!itb) return EINA_FALSE;
4256 itb = _item_block_new(wd, EINA_TRUE);
4257 if (!itb) return EINA_FALSE;
4259 itb->items = eina_list_prepend(itb->items, it);
4261 _item_position_update(itb->items, 0);
4267 itb = (Item_Block *)(wd->blocks->last);
4268 if (itb->count >= wd->max_items_per_block)
4270 itb = _item_block_new(wd, EINA_FALSE);
4271 if (!itb) return EINA_FALSE;
4276 itb = _item_block_new(wd, EINA_FALSE);
4277 if (!itb) return EINA_FALSE;
4279 itb->items = eina_list_append(itb->items, it);
4280 it->position = eina_list_count(itb->items);
4288 if (it->item->rel->item->queued)
4290 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
4291 on sorted insertion order, so the queue is not always ordered like the item list.
4292 This lead to issue where we depend on an item that is not yet created. As a quick
4293 work around, we reschedule the calc of the item and stop reordering the list to
4294 prevent any nasty issue to show up here.
4296 wd->queue = eina_list_append(wd->queue, it);
4297 wd->requeued = EINA_TRUE;
4298 it->item->queued = EINA_TRUE;
4301 itb = it->item->rel->item->block;
4302 if (!itb) goto newblock;
4303 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4304 if (it->item->before)
4306 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4307 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4311 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4312 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4316 itb->changed = EINA_TRUE;
4317 it->item->block = itb;
4318 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
4319 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
4322 it->item->rel->relcount--;
4323 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
4325 _item_del(it->item->rel);
4326 elm_widget_item_free(it->item->rel);
4328 it->item->rel = NULL;
4330 if (itb->count > itb->wd->max_items_per_block)
4335 Eina_Bool done = EINA_FALSE;
4337 newc = itb->count / 2;
4339 if (EINA_INLIST_GET(itb)->prev)
4341 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4343 if (itbp->count + newc < wd->max_items_per_block / 2)
4345 /* moving items to previous block */
4346 while ((itb->count > newc) && (itb->items))
4348 it2 = eina_list_data_get(itb->items);
4349 itb->items = eina_list_remove_list(itb->items, itb->items);
4352 itbp->items = eina_list_append(itbp->items, it2);
4353 it2->item->block = itbp;
4361 if (!done && EINA_INLIST_GET(itb)->next)
4363 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4365 if (itbn->count + newc < wd->max_items_per_block / 2)
4367 /* moving items to next block */
4368 while ((itb->count > newc) && (itb->items))
4372 l = eina_list_last(itb->items);
4373 it2 = eina_list_data_get(l);
4374 itb->items = eina_list_remove_list(itb->items, l);
4377 itbn->items = eina_list_prepend(itbn->items, it2);
4378 it2->item->block = itbn;
4388 /* moving items to new block */
4389 itb2 = calloc(1, sizeof(Item_Block));
4390 if (!itb2) return EINA_FALSE;
4393 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4394 EINA_INLIST_GET(itb));
4395 itb2->changed = EINA_TRUE;
4396 while ((itb->count > newc) && (itb->items))
4400 l = eina_list_last(itb->items);
4402 itb->items = eina_list_remove_list(itb->items, l);
4405 itb2->items = eina_list_prepend(itb2->items, it2);
4406 it2->item->block = itb2;
4416 _queue_process(Widget_Data *wd)
4419 Eina_Bool showme = EINA_FALSE;
4422 t0 = ecore_loop_time_get();
4423 //evas_event_freeze(evas_object_evas_get(wd->obj));
4424 for (n = 0; (wd->queue) && (n < 128); n++)
4428 it = eina_list_data_get(wd->queue);
4429 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4430 it->item->queued = EINA_FALSE;
4431 if (!_item_block_add(wd, it)) continue;
4433 _item_block_realize(it->item->block);
4434 t = ecore_time_get();
4435 if (it->item->block->changed)
4437 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4438 it->item->block->changed = 0;
4439 if (wd->pan_changed)
4441 if (wd->calc_job) ecore_job_del(wd->calc_job);
4442 wd->calc_job = NULL;
4444 wd->pan_changed = EINA_FALSE;
4447 if (showme) it->item->block->showme = EINA_TRUE;
4448 /* same as eina_inlist_count > 1 */
4449 if (wd->blocks && wd->blocks->next)
4451 if ((t - t0) > (ecore_animator_frametime_get())) break;
4454 //evas_event_thaw(evas_object_evas_get(wd->obj));
4455 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4460 _idle_process(void *data, Eina_Bool *wakeup)
4462 Widget_Data *wd = data;
4465 //static double q_start = 0.0;
4466 //if (q_start == 0.0) q_start = ecore_time_get();
4468 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4472 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4474 return ECORE_CALLBACK_CANCEL;
4476 return ECORE_CALLBACK_RENEW;
4480 _item_idle_enterer(void *data)
4482 Widget_Data *wd = data;
4483 Eina_Bool wakeup = EINA_FALSE;
4484 Eina_Bool ok = _idle_process(data, &wakeup);
4489 if (wd->calc_job) ecore_job_del(wd->calc_job);
4490 wd->calc_job = ecore_job_add(_calc_job, wd);
4492 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4497 _item_queue(Widget_Data *wd,
4501 if (it->item->queued) return;
4502 it->item->queued = EINA_TRUE;
4503 if (cb && !wd->requeued)
4504 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4506 wd->queue = eina_list_append(wd->queue, it);
4507 // FIXME: why does a freeze then thaw here cause some genlist
4508 // elm_genlist_item_append() to be much much slower?
4509 // evas_event_freeze(evas_object_evas_get(wd->obj));
4510 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4512 if (wd->queue_idle_enterer)
4514 ecore_idle_enterer_del(wd->queue_idle_enterer);
4515 wd->queue_idle_enterer = NULL;
4519 // evas_event_thaw(evas_object_evas_get(wd->obj));
4520 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4521 if (!wd->queue_idle_enterer)
4522 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4526 _elm_genlist_item_compare(const void *data, const void *data1)
4528 const Elm_Gen_Item *it, *item1;
4529 it = ELM_GEN_ITEM_FROM_INLIST(data);
4530 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4531 return it->wd->item_compare_cb(it, item1);
4535 _elm_genlist_item_list_compare(const void *data, const void *data1)
4537 const Elm_Gen_Item *it = data;
4538 const Elm_Gen_Item *item1 = data1;
4539 return it->wd->item_compare_cb(it, item1);
4543 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4548 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4549 _item_block_del(it);
4551 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4552 it->item->rel = after;
4553 it->item->rel->relcount++;
4554 it->item->before = EINA_FALSE;
4555 if (after->item->group_item) it->item->group_item = after->item->group_item;
4556 _item_queue(it->wd, it, NULL);
4558 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4562 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4565 if (!before) return;
4567 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4568 _item_block_del(it);
4569 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4570 it->item->rel = before;
4571 it->item->rel->relcount++;
4572 it->item->before = EINA_TRUE;
4573 if (before->item->group_item) it->item->group_item = before->item->group_item;
4574 _item_queue(it->wd, it, NULL);
4576 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4580 elm_genlist_items_count(const Evas_Object *obj)
4582 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4583 Widget_Data *wd = elm_widget_data_get(obj);
4585 return wd->item_count;
4588 EAPI Elm_Object_Item *
4589 elm_genlist_item_append(Evas_Object *obj,
4590 const Elm_Genlist_Item_Class *itc,
4592 Elm_Object_Item *parent,
4593 Elm_Genlist_Item_Type type,
4595 const void *func_data)
4597 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4598 Widget_Data *wd = elm_widget_data_get(obj);
4599 if (!wd) return NULL;
4600 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4602 if (!it) return NULL;
4606 wd->group_items = eina_list_append(wd->group_items, it);
4607 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4608 it->item->rel = NULL;
4612 Elm_Gen_Item *it2 = NULL;
4613 Eina_List *ll = eina_list_last(it->parent->item->items);
4614 if (ll) it2 = ll->data;
4615 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4616 if (!it2) it2 = it->parent;
4618 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4619 EINA_INLIST_GET(it2));
4620 it->item->rel = it2;
4621 it->item->rel->relcount++;
4623 it->item->before = EINA_FALSE;
4624 _item_queue(wd, it, NULL);
4625 return (Elm_Object_Item *)it;
4628 EAPI Elm_Object_Item *
4629 elm_genlist_item_prepend(Evas_Object *obj,
4630 const Elm_Genlist_Item_Class *itc,
4632 Elm_Object_Item *parent,
4633 Elm_Genlist_Item_Type type,
4635 const void *func_data)
4637 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4638 Widget_Data *wd = elm_widget_data_get(obj);
4639 if (!wd) return NULL;
4640 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4642 if (!it) return NULL;
4646 wd->group_items = eina_list_prepend(wd->group_items, it);
4647 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4648 it->item->rel = NULL;
4652 Elm_Gen_Item *it2 = NULL;
4653 Eina_List *ll = it->parent->item->items;
4654 if (ll) it2 = ll->data;
4655 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4656 if (!it2) it2 = it->parent;
4658 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4659 EINA_INLIST_GET(it2));
4660 it->item->rel = it2;
4661 it->item->rel->relcount++;
4663 it->item->before = EINA_TRUE;
4664 _item_queue(wd, it, NULL);
4665 return (Elm_Object_Item *)it;
4668 EAPI Elm_Object_Item *
4669 elm_genlist_item_insert_after(Evas_Object *obj,
4670 const Elm_Genlist_Item_Class *itc,
4672 Elm_Object_Item *parent,
4673 Elm_Object_Item *after,
4674 Elm_Genlist_Item_Type type,
4676 const void *func_data)
4678 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4679 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4680 Widget_Data *wd = elm_widget_data_get(obj);
4681 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4682 if (!wd) return NULL;
4683 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4684 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4686 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4688 if (!it) return NULL;
4691 if ((it->group) && (_after->group))
4692 wd->group_items = eina_list_append_relative(wd->group_items, it,
4697 it->parent->item->items =
4698 eina_list_append_relative(it->parent->item->items, it, _after);
4700 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4701 EINA_INLIST_GET(_after));
4702 it->item->rel = _after;
4703 it->item->rel->relcount++;
4704 it->item->before = EINA_FALSE;
4705 _item_queue(wd, it, NULL);
4706 return (Elm_Object_Item *)it;
4709 EAPI Elm_Object_Item *
4710 elm_genlist_item_insert_before(Evas_Object *obj,
4711 const Elm_Genlist_Item_Class *itc,
4713 Elm_Object_Item *parent,
4714 Elm_Object_Item *before,
4715 Elm_Genlist_Item_Type type,
4717 const void *func_data)
4719 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4720 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4721 Widget_Data *wd = elm_widget_data_get(obj);
4722 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4723 if (!wd) return NULL;
4724 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4725 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4727 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4729 if (!it) return NULL;
4732 if (it->group && _before->group)
4733 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4738 it->parent->item->items =
4739 eina_list_prepend_relative(it->parent->item->items, it, _before);
4741 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4742 EINA_INLIST_GET(_before));
4743 it->item->rel = _before;
4744 it->item->rel->relcount++;
4745 it->item->before = EINA_TRUE;
4746 _item_queue(wd, it, NULL);
4747 return (Elm_Object_Item *)it;
4750 EAPI Elm_Object_Item *
4751 elm_genlist_item_sorted_insert(Evas_Object *obj,
4752 const Elm_Genlist_Item_Class *itc,
4754 Elm_Object_Item *parent,
4755 Elm_Genlist_Item_Type type,
4756 Eina_Compare_Cb comp,
4758 const void *func_data)
4760 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4761 Widget_Data *wd = elm_widget_data_get(obj);
4762 if (!wd) return NULL;
4763 Elm_Gen_Item *rel = NULL;
4764 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4766 if (!it) return NULL;
4768 wd->item_compare_cb = comp;
4775 l = eina_list_search_sorted_near_list(it->parent->item->items,
4776 _elm_genlist_item_list_compare,
4780 rel = eina_list_data_get(l);
4784 if (cmp_result >= 0)
4786 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4787 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4788 it->item->before = EINA_FALSE;
4790 else if (cmp_result < 0)
4792 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4793 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4794 it->item->before = EINA_TRUE;
4801 wd->state = eina_inlist_sorted_state_new();
4802 eina_inlist_sorted_state_init(wd->state, wd->items);
4803 wd->requeued = EINA_FALSE;
4807 wd->group_items = eina_list_append(wd->group_items, it);
4809 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4810 _elm_genlist_item_compare, wd->state);
4812 if (EINA_INLIST_GET(it)->next)
4814 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4815 it->item->before = EINA_TRUE;
4817 else if (EINA_INLIST_GET(it)->prev)
4819 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4820 it->item->before = EINA_FALSE;
4826 it->item->rel = rel;
4827 it->item->rel->relcount++;
4830 _item_queue(wd, it, _elm_genlist_item_list_compare);
4832 return (Elm_Object_Item *)it;
4836 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4838 Eina_Inlist *next, *l;
4839 Widget_Data *wd = elm_widget_data_get(obj);
4842 if (!standby) wd->generation++;
4846 eina_inlist_sorted_state_free(wd->state);
4850 if (wd->walking > 0)
4852 wd->clear_me = EINA_TRUE;
4855 evas_event_freeze(evas_object_evas_get(wd->obj));
4856 for (l = wd->items, next = l ? l->next : NULL;
4858 l = next, next = next ? next->next : NULL)
4860 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4862 if (it->generation < wd->generation)
4864 Elm_Gen_Item *itn = NULL;
4866 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4867 if (itn) itn->walking++; /* prevent early death of subitem */
4869 elm_widget_item_free(it);
4870 if (itn) itn->walking--;
4873 wd->clear_me = EINA_FALSE;
4874 wd->pan_changed = EINA_TRUE;
4877 ecore_job_del(wd->calc_job);
4878 wd->calc_job = NULL;
4880 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4881 if (wd->clear_cb) wd->clear_cb(wd);
4887 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4888 wd->alpha_bg = NULL;
4892 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4893 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4895 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4896 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4897 evas_event_thaw(evas_object_evas_get(wd->obj));
4898 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4902 elm_genlist_clear(Evas_Object *obj)
4904 ELM_CHECK_WIDTYPE(obj, widtype);
4905 _elm_genlist_clear(obj, EINA_FALSE);
4909 elm_genlist_multi_select_set(Evas_Object *obj,
4912 ELM_CHECK_WIDTYPE(obj, widtype);
4913 Widget_Data *wd = elm_widget_data_get(obj);
4915 wd->multi = !!multi;
4919 elm_genlist_multi_select_get(const Evas_Object *obj)
4921 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4922 Widget_Data *wd = elm_widget_data_get(obj);
4923 if (!wd) return EINA_FALSE;
4927 EAPI Elm_Object_Item *
4928 elm_genlist_selected_item_get(const Evas_Object *obj)
4930 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4931 Widget_Data *wd = elm_widget_data_get(obj);
4932 if (!wd) return NULL;
4933 if (wd->selected) return wd->selected->data;
4937 EAPI const Eina_List *
4938 elm_genlist_selected_items_get(const Evas_Object *obj)
4940 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4941 Widget_Data *wd = elm_widget_data_get(obj);
4942 if (!wd) return NULL;
4943 return wd->selected;
4947 elm_genlist_realized_items_get(const Evas_Object *obj)
4949 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4950 Widget_Data *wd = elm_widget_data_get(obj);
4951 Eina_List *list = NULL;
4953 Eina_Bool done = EINA_FALSE;
4954 if (!wd) return NULL;
4955 EINA_INLIST_FOREACH(wd->blocks, itb)
4963 EINA_LIST_FOREACH(itb->items, l, it)
4965 if (it->realized) list = eina_list_append(list, it);
4976 EAPI Elm_Object_Item *
4977 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4982 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4983 Widget_Data *wd = elm_widget_data_get(obj);
4984 Evas_Coord ox, oy, ow, oh;
4987 if (!wd) return NULL;
4988 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4990 EINA_INLIST_FOREACH(wd->blocks, itb)
4995 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4996 oy + itb->y - itb->wd->pan_y,
4997 itb->w, itb->h, x, y, 1, 1))
4999 EINA_LIST_FOREACH(itb->items, l, it)
5001 Evas_Coord itx, ity;
5003 itx = ox + itb->x + it->x - itb->wd->pan_x;
5004 ity = oy + itb->y + it->y - itb->wd->pan_y;
5005 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5009 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5010 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5014 return (Elm_Object_Item *)it;
5016 lasty = ity + it->item->h;
5021 if (y > lasty) *posret = 1;
5027 EAPI Elm_Object_Item *
5028 elm_genlist_first_item_get(const Evas_Object *obj)
5030 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5031 Widget_Data *wd = elm_widget_data_get(obj);
5032 if (!wd) return NULL;
5033 if (!wd->items) return NULL;
5034 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
5035 while ((it) && (it->generation < wd->generation))
5036 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5037 return (Elm_Object_Item *)it;
5040 EAPI Elm_Object_Item *
5041 elm_genlist_last_item_get(const Evas_Object *obj)
5043 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5044 Widget_Data *wd = elm_widget_data_get(obj);
5045 if (!wd) return NULL;
5046 if (!wd->items) return NULL;
5047 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
5048 while ((it) && (it->generation < wd->generation))
5049 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5050 return (Elm_Object_Item *)it;
5053 EAPI Elm_Object_Item *
5054 elm_genlist_item_next_get(const Elm_Object_Item *it)
5056 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5057 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5060 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
5061 if ((_it) && (_it->generation == _it->wd->generation)) break;
5063 return (Elm_Object_Item *) _it;
5066 EAPI Elm_Object_Item *
5067 elm_genlist_item_prev_get(const Elm_Object_Item *it)
5069 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5070 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5073 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
5074 if ((_it) && (_it->generation == _it->wd->generation)) break;
5076 return (Elm_Object_Item *) _it;
5079 EAPI Elm_Object_Item *
5080 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5082 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5083 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
5087 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
5089 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5090 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
5092 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5094 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
5095 _item_subitems_clear(_it);
5098 if (!wd->item_moving_effect_timer)
5100 wd->expanded_item = _it;
5101 _item_tree_effect_before(_it);
5102 evas_object_raise(wd->alpha_bg);
5103 evas_object_show(wd->alpha_bg);
5104 wd->start_time = ecore_time_get();
5105 wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, wd);
5108 _item_subitems_clear(_it);
5113 elm_genlist_item_selected_set(Elm_Object_Item *it,
5116 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5117 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5118 Widget_Data *wd = _it->wd;
5120 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
5122 selected = !!selected;
5123 if (_it->selected == selected) return;
5129 while (wd->selected)
5131 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
5132 _it->unsel_cb(wd->selected->data);
5135 _it->highlight_cb(_it);
5139 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
5144 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5146 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5147 return ((Elm_Gen_Item *)it)->selected;
5151 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5154 if (it->item->expanded)
5156 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5160 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5163 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5164 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5171 _elm_genlist_move_items_set(Elm_Gen_Item *it)
5174 Elm_Gen_Item *it2 = NULL;
5175 Evas_Coord ox, oy, ow, oh, dh = 0;
5177 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
5179 if (it->item->expanded)
5181 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
5182 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
5184 if (it2 == it->wd->expanded_next_item) break;
5185 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
5190 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
5191 it2 = it->wd->expanded_next_item;
5192 while (it2 && (dh < oy + oh))
5195 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
5196 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5202 elm_genlist_item_expanded_set(Elm_Object_Item *it,
5205 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5206 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5207 expanded = !!expanded;
5208 if (_it->item->expanded == expanded) return;
5209 _it->item->expanded = expanded;
5210 _it->wd->expanded_item = _it;
5211 _elm_genlist_move_items_set(_it);
5213 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
5214 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
5216 if (_it->item->expanded)
5218 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
5220 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
5221 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
5222 _it->wd->auto_scroll_enabled = EINA_TRUE;
5226 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
5228 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
5229 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
5230 _it->wd->auto_scroll_enabled = EINA_FALSE;
5235 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5237 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5238 return ((Elm_Gen_Item *)it)->item->expanded;
5242 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5244 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
5245 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5248 EINA_DEPRECATED EAPI void
5249 elm_genlist_item_display_only_set(Elm_Object_Item *it,
5250 Eina_Bool display_only)
5252 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5253 display_only = !!display_only;
5256 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
5259 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5260 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5261 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
5265 EINA_DEPRECATED EAPI Eina_Bool
5266 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
5268 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5269 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5270 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5271 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5272 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5278 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
5279 Elm_Genlist_Item_Scrollto_Type type,
5285 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5286 Evas_Coord gith = 0;
5287 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5288 if ((_it->item->queued) || (!_it->item->mincalcd))
5290 _it->wd->show_item = _it;
5291 _it->wd->bring_in = EINA_FALSE;
5292 _it->wd->scrollto_type = type;
5293 _it->item->showme = EINA_TRUE;
5296 if (_it->wd->show_item)
5298 _it->wd->show_item->item->showme = EINA_FALSE;
5299 _it->wd->show_item = NULL;
5302 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
5303 if (type==ELM_GENLIST_ITEM_SCROLLTO_IN)
5305 if ((_it->item->group_item) &&
5306 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
5307 gith = _it->item->group_item->item->h;
5310 *y = _it->y + _it->item->block->y - gith;
5312 else if (type==ELM_GENLIST_ITEM_SCROLLTO_TOP)
5314 if (_it->item->group_item) gith = _it->item->group_item->item->h;
5315 *y = _it->y + _it->item->block->y - gith;
5317 else if (type==ELM_GENLIST_ITEM_SCROLLTO_MIDDLE)
5319 *y = _it->y + _it->item->block->y - *h / 2 + _it->item->h / 2;
5324 *x = _it->x + _it->item->block->x;
5325 *w = _it->item->block->w;
5330 elm_genlist_item_promote(Elm_Object_Item *it)
5332 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5333 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5334 if (_it->generation < _it->wd->generation) return;
5335 _item_move_before(_it,
5336 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
5340 elm_genlist_item_demote(Elm_Object_Item *it)
5342 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5343 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5344 if (_it->generation < _it->wd->generation) return;
5345 _item_move_after(_it,
5346 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
5350 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5352 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5353 Evas_Coord x, y, w, h;
5354 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5356 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
5357 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
5361 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5364 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5365 Evas_Coord x, y, w, h;
5366 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5368 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
5369 elm_smart_scroller_region_bring_in(_it->wd->scr,x, y, w, h);
5373 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5375 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5377 Evas_Object *content;
5378 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5380 elm_widget_sub_object_del(WIDGET(it), content);
5381 evas_object_smart_member_del(content);
5382 evas_object_hide(content);
5384 *l = eina_list_append(*l, content);
5389 elm_genlist_item_update(Elm_Object_Item *it)
5391 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5392 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5394 if (!_it->item->block) return;
5395 if (_it->generation < _it->wd->generation) return;
5396 _it->item->mincalcd = EINA_FALSE;
5397 _it->item->updateme = EINA_TRUE;
5398 _it->item->block->updateme = EINA_TRUE;
5399 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5400 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5404 elm_genlist_item_fields_update(Elm_Object_Item *it,
5406 Elm_Genlist_Item_Field_Type itf)
5408 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5409 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5411 if (!_it->item->block) return;
5412 if (_it->generation < _it->wd->generation) return;
5414 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5415 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5416 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5418 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5419 &_it->contents, parts);
5420 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5421 &_it->contents, parts);
5425 _it->content_objs = _item_mode_content_unrealize(_it, VIEW(_it),
5426 &_it->contents, parts, &_it->content_objs, "flips");
5427 _it->content_objs = _item_mode_content_realize(_it, VIEW(_it),
5428 &_it->contents, parts, &_it->content_objs, "flips");
5431 if (_it->item->mode_view)
5433 _it->item->mode_content_objs = _item_mode_content_unrealize(_it, _it->item->mode_view,
5434 &_it->item->mode_contents, parts, &_it->item->mode_content_objs, "contents");
5435 _it->item->mode_content_objs = _item_mode_content_realize(_it, _it->item->mode_view,
5436 &_it->item->mode_contents, parts, &_it->item->mode_content_objs, "contents");
5439 if (_it->wd->decorate_mode)
5441 _it->item->edit_content_objs = _item_mode_content_unrealize(_it, _it->edit_obj,
5442 &_it->contents, parts, &_it->item->edit_content_objs, "decorate_contents");
5443 _it->item->edit_content_objs = _item_mode_content_realize(_it, _it->edit_obj,
5444 &_it->contents, parts, &_it->item->edit_content_objs, "decorate_contents"); // FIXME: is it "decorate_contents"??
5447 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5448 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5452 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5453 const Elm_Genlist_Item_Class *itc)
5455 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5456 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5458 if (!_it->item->block) return;
5459 EINA_SAFETY_ON_NULL_RETURN(itc);
5460 if (_it->generation < _it->wd->generation) return;
5462 _it->item->nocache_once = EINA_TRUE;
5463 elm_genlist_item_update(it);
5466 EAPI const Elm_Genlist_Item_Class *
5467 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5469 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5470 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5471 if (_it->generation < _it->wd->generation) return NULL;
5475 static Evas_Object *
5476 _elm_genlist_item_label_create(void *data,
5477 Evas_Object *obj __UNUSED__,
5478 Evas_Object *tooltip,
5479 void *it __UNUSED__)
5481 Evas_Object *label = elm_label_add(tooltip);
5484 elm_object_style_set(label, "tooltip");
5485 elm_object_text_set(label, data);
5490 _elm_genlist_item_label_del_cb(void *data,
5491 Evas_Object *obj __UNUSED__,
5492 void *event_info __UNUSED__)
5494 eina_stringshare_del(data);
5498 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5501 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5502 text = eina_stringshare_add(text);
5503 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5505 _elm_genlist_item_label_del_cb);
5509 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5510 Elm_Tooltip_Item_Content_Cb func,
5512 Evas_Smart_Cb del_cb)
5514 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5515 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5517 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5520 if (_it->tooltip.del_cb)
5521 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5523 _it->tooltip.content_cb = func;
5524 _it->tooltip.data = data;
5525 _it->tooltip.del_cb = del_cb;
5529 elm_widget_item_tooltip_content_cb_set(_it,
5530 _it->tooltip.content_cb,
5531 _it->tooltip.data, NULL);
5532 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5533 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5539 if (del_cb) del_cb((void *)data, NULL, NULL);
5543 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5545 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5546 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5548 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5549 elm_widget_item_tooltip_unset(_it);
5551 if (_it->tooltip.del_cb)
5552 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5553 _it->tooltip.del_cb = NULL;
5554 _it->tooltip.content_cb = NULL;
5555 _it->tooltip.data = NULL;
5556 _it->tooltip.free_size = EINA_FALSE;
5557 if (_it->tooltip.style)
5558 elm_genlist_item_tooltip_style_set(it, NULL);
5562 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5565 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5566 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5568 eina_stringshare_replace(&_it->tooltip.style, style);
5569 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5573 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5575 return elm_object_item_tooltip_style_get(it);
5579 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5582 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5583 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5585 _it->tooltip.free_size = disable;
5586 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5591 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5593 return elm_object_tooltip_window_mode_get(VIEW(it));
5597 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5600 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5601 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5602 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5603 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5607 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5609 return elm_widget_item_cursor_get(it);
5613 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5615 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5616 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5618 if (!_it->mouse_cursor) return;
5620 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5622 eina_stringshare_del(_it->mouse_cursor);
5623 _it->mouse_cursor = NULL;
5627 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5630 elm_widget_item_cursor_style_set(it, style);
5634 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5636 return elm_widget_item_cursor_style_get(it);
5640 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5641 Eina_Bool engine_only)
5643 elm_widget_item_cursor_engine_only_set(it, engine_only);
5647 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5649 return elm_widget_item_cursor_engine_only_get(it);
5653 elm_genlist_item_index_get(const Elm_Object_Item *it)
5655 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5656 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5658 if (_it->item->block)
5659 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5664 elm_genlist_mode_set(Evas_Object *obj,
5667 ELM_CHECK_WIDTYPE(obj, widtype);
5668 Widget_Data *wd = elm_widget_data_get(obj);
5670 if (wd->mode == mode) return;
5672 if (wd->mode == ELM_LIST_COMPRESS)
5673 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5679 elm_genlist_mode_get(const Evas_Object *obj)
5681 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5682 Widget_Data *wd = elm_widget_data_get(obj);
5683 if (!wd) return ELM_LIST_LAST;
5688 elm_genlist_bounce_set(Evas_Object *obj,
5692 ELM_CHECK_WIDTYPE(obj, widtype);
5693 Widget_Data *wd = elm_widget_data_get(obj);
5695 wd->h_bounce = !!h_bounce;
5696 wd->v_bounce = !!v_bounce;
5697 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5701 elm_genlist_bounce_get(const Evas_Object *obj,
5702 Eina_Bool *h_bounce,
5703 Eina_Bool *v_bounce)
5705 ELM_CHECK_WIDTYPE(obj, widtype);
5706 Widget_Data *wd = elm_widget_data_get(obj);
5708 if (h_bounce) *h_bounce = wd->h_bounce;
5709 if (v_bounce) *v_bounce = wd->v_bounce;
5713 elm_genlist_homogeneous_set(Evas_Object *obj,
5714 Eina_Bool homogeneous)
5716 ELM_CHECK_WIDTYPE(obj, widtype);
5717 Widget_Data *wd = elm_widget_data_get(obj);
5719 wd->homogeneous = !!homogeneous;
5723 elm_genlist_homogeneous_get(const Evas_Object *obj)
5725 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5726 Widget_Data *wd = elm_widget_data_get(obj);
5727 if (!wd) return EINA_FALSE;
5728 return wd->homogeneous;
5732 elm_genlist_block_count_set(Evas_Object *obj,
5735 ELM_CHECK_WIDTYPE(obj, widtype);
5736 Widget_Data *wd = elm_widget_data_get(obj);
5738 wd->max_items_per_block = count;
5739 wd->item_cache_max = wd->max_items_per_block * 2;
5740 _item_cache_clean(wd);
5744 elm_genlist_block_count_get(const Evas_Object *obj)
5746 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5747 Widget_Data *wd = elm_widget_data_get(obj);
5749 return wd->max_items_per_block;
5753 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5756 ELM_CHECK_WIDTYPE(obj, widtype);
5757 Widget_Data *wd = elm_widget_data_get(obj);
5759 wd->longpress_timeout = timeout;
5763 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5765 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5766 Widget_Data *wd = elm_widget_data_get(obj);
5768 return wd->longpress_timeout;
5772 elm_genlist_scroller_policy_set(Evas_Object *obj,
5773 Elm_Scroller_Policy policy_h,
5774 Elm_Scroller_Policy policy_v)
5776 ELM_CHECK_WIDTYPE(obj, widtype);
5777 Widget_Data *wd = elm_widget_data_get(obj);
5778 if ((!wd) || (!wd->scr)) return;
5779 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5780 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5782 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5786 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5787 Elm_Scroller_Policy *policy_h,
5788 Elm_Scroller_Policy *policy_v)
5790 ELM_CHECK_WIDTYPE(obj, widtype);
5791 Widget_Data *wd = elm_widget_data_get(obj);
5792 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5793 if ((!wd) || (!wd->scr)) return;
5794 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5795 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5796 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5800 elm_genlist_realized_items_update(Evas_Object *obj)
5802 ELM_CHECK_WIDTYPE(obj, widtype);
5804 Eina_List *list, *l;
5805 Elm_Object_Item *it;
5807 list = elm_genlist_realized_items_get(obj);
5808 EINA_LIST_FOREACH(list, l, it)
5809 elm_genlist_item_update(it);
5813 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5814 const char *decorate_type,
5817 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5818 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5820 Widget_Data *wd = _it->wd;
5822 Elm_Object_Item *it2;
5825 if (!decorate_type) return;
5826 if ((_it->generation < _it->wd->generation) ||
5827 elm_widget_item_disabled_get(_it)) return;
5828 if (wd->decorate_mode) return;
5830 if ((wd->mode_item == _it) &&
5831 (!strcmp(decorate_type, wd->decorate_type)) &&
5834 if (!_it->itc->decorate_item_style) return;
5835 _it->mode_set = mode_set;
5839 EINA_LIST_FOREACH(wd->selected, l, it2)
5840 if (((Elm_Gen_Item *)it2)->realized)
5841 elm_genlist_item_selected_set(it2, EINA_FALSE);
5845 it2 = elm_genlist_selected_item_get(wd->obj);
5846 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5847 elm_genlist_item_selected_set(it2, EINA_FALSE);
5850 if (((wd->decorate_type) && (strcmp(decorate_type, wd->decorate_type))) ||
5852 ((_it == wd->mode_item) && (!mode_set)))
5853 _item_mode_unset(wd);
5855 eina_stringshare_replace(&wd->decorate_type, decorate_type);
5856 if (mode_set) _item_mode_set(_it);
5860 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5862 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5863 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5864 return _it->wd->decorate_type;
5867 EAPI const Elm_Object_Item *
5868 elm_genlist_decorated_item_get(const Evas_Object *obj)
5870 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5871 Widget_Data *wd = elm_widget_data_get(obj);
5872 if (!wd) return NULL;
5873 return (Elm_Object_Item *) wd->mode_item;
5877 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5879 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5880 Widget_Data *wd = elm_widget_data_get(obj);
5881 if (!wd) return EINA_FALSE;
5883 return wd->decorate_mode;
5887 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5889 ELM_CHECK_WIDTYPE(obj, widtype);
5890 Eina_List *list, *l;
5893 Widget_Data *wd = elm_widget_data_get(obj);
5895 decorated = !!decorated;
5896 if (wd->decorate_mode == decorated) return;
5897 wd->decorate_mode = decorated;
5899 list = elm_genlist_realized_items_get(obj);
5900 if (!wd->decorate_mode)
5902 EINA_LIST_FOREACH(list, l, it)
5904 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5905 _decorate_mode_item_unrealize(it);
5907 _item_cache_zero(wd);
5911 EINA_LIST_FOREACH(list, l, it)
5913 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5915 if (it->selected) _item_unselect(it);
5916 if (it->itc->decorate_all_item_style)
5917 _decorate_mode_item_realize(it, EINA_TRUE);
5921 if (wd->calc_job) ecore_job_del(wd->calc_job);
5922 wd->calc_job = ecore_job_add(_calc_job, wd);
5926 elm_genlist_reorder_mode_set(Evas_Object *obj,
5927 Eina_Bool reorder_mode)
5929 ELM_CHECK_WIDTYPE(obj, widtype);
5930 Widget_Data *wd = elm_widget_data_get(obj);
5932 wd->reorder_mode = !!reorder_mode;
5936 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5938 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5939 Widget_Data *wd = elm_widget_data_get(obj);
5940 if (!wd) return EINA_FALSE;
5941 return wd->reorder_mode;
5944 EAPI Elm_Genlist_Item_Type
5945 elm_genlist_item_type_get(const Elm_Object_Item *it)
5947 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5948 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5949 return _it->item->type;
5952 EAPI Elm_Genlist_Item_Class *
5953 elm_genlist_item_class_new(void)
5955 Elm_Genlist_Item_Class *itc;
5957 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5960 itc->version = CLASS_ALLOCATED;
5962 itc->delete_me = EINA_FALSE;
5968 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5970 if (itc && (itc->version == CLASS_ALLOCATED))
5972 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5973 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5983 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5985 if (itc && (itc->version == CLASS_ALLOCATED))
5988 if (itc->refcount == 0) itc->refcount--;
5993 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5995 if (itc && (itc->version == CLASS_ALLOCATED))
5997 if (itc->refcount > 0) itc->refcount--;
5998 if (itc->delete_me && (!itc->refcount))
5999 elm_genlist_item_class_free(itc);
6003 void _flip_job(void *data)
6005 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
6006 _elm_genlist_item_unrealize(it, EINA_FALSE);
6007 if (it->selected) _item_unselect(it);
6008 it->flipped = EINA_TRUE;
6009 it->item->nocache = EINA_TRUE;
6013 elm_genlist_item_flip_set(Elm_Object_Item *it,
6016 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6017 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6020 if (_it->flipped == flip) return;
6024 ecore_job_add(_flip_job, _it);
6025 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
6026 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
6030 _it->flipped = flip;
6031 _item_cache_zero(_it->wd);
6032 elm_genlist_item_update(it);
6033 _it->item->nocache = EINA_FALSE;
6038 elm_genlist_item_flip_get(const Elm_Object_Item *it)
6040 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6041 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6042 return _it->flipped;
6046 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
6048 ELM_CHECK_WIDTYPE(obj, widtype);
6049 Widget_Data *wd = elm_widget_data_get(obj);
6051 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6053 if (wd->select_mode != mode)
6054 wd->select_mode = mode;
6057 EAPI Elm_Object_Select_Mode
6058 elm_genlist_select_mode_get(const Evas_Object *obj)
6060 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
6061 Widget_Data *wd = elm_widget_data_get(obj);
6062 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
6063 return wd->select_mode;
6067 elm_genlist_highlight_mode_set(Evas_Object *obj,
6068 Eina_Bool highlight)
6070 ELM_CHECK_WIDTYPE(obj, widtype);
6071 Widget_Data *wd = elm_widget_data_get(obj);
6073 wd->highlight = !!highlight;
6077 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6079 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6080 Widget_Data *wd = elm_widget_data_get(obj);
6081 if (!wd) return EINA_FALSE;
6082 return wd->highlight;
6086 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
6087 Elm_Object_Select_Mode mode)
6089 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6090 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6092 if (_it->generation < _it->wd->generation) return;
6093 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6095 if (_it->select_mode != mode)
6096 _it->select_mode = mode;
6098 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6100 _it->item->mincalcd = EINA_FALSE;
6101 _it->item->updateme = EINA_TRUE;
6102 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
6103 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
6104 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
6108 EAPI Elm_Object_Select_Mode
6109 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
6111 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
6112 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6113 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
6114 return _it->select_mode;
6117 /* for gengrid as of now */
6119 _elm_genlist_page_relative_set(Evas_Object *obj,
6123 Evas_Coord pagesize_h;
6124 Evas_Coord pagesize_v;
6126 ELM_CHECK_WIDTYPE(obj, widtype);
6127 Widget_Data *wd = elm_widget_data_get(obj);
6130 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
6131 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
6135 /* for gengrid as of now */
6137 _elm_genlist_page_relative_get(const Evas_Object *obj,
6141 ELM_CHECK_WIDTYPE(obj, widtype);
6142 Widget_Data *wd = elm_widget_data_get(obj);
6145 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
6148 /* for gengrid as of now */
6150 _elm_genlist_page_size_set(Evas_Object *obj,
6151 Evas_Coord h_pagesize,
6152 Evas_Coord v_pagesize)
6157 ELM_CHECK_WIDTYPE(obj, widtype);
6158 Widget_Data *wd = elm_widget_data_get(obj);
6160 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
6161 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
6165 /* for gengrid as of now */
6167 _elm_genlist_current_page_get(const Evas_Object *obj,
6171 ELM_CHECK_WIDTYPE(obj, widtype);
6172 Widget_Data *wd = elm_widget_data_get(obj);
6174 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
6177 /* for gengrid as of now */
6179 _elm_genlist_last_page_get(const Evas_Object *obj,
6183 ELM_CHECK_WIDTYPE(obj, widtype);
6184 Widget_Data *wd = elm_widget_data_get(obj);
6186 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
6189 /* for gengrid as of now */
6191 _elm_genlist_page_show(const Evas_Object *obj,
6195 ELM_CHECK_WIDTYPE(obj, widtype);
6196 Widget_Data *wd = elm_widget_data_get(obj);
6198 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
6201 /* for gengrid as of now */
6203 _elm_genlist_page_bring_in(const Evas_Object *obj,
6207 ELM_CHECK_WIDTYPE(obj, widtype);
6208 Widget_Data *wd = elm_widget_data_get(obj);
6210 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
6214 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
6217 Evas_Object *content;
6219 if (!it->realized) return;
6220 if (it->wd->reorder_it == it) return;
6221 if (it->defer_unrealize && !it->item->updateme) return;
6223 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
6225 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
6228 ecore_timer_del(it->long_timer);
6229 it->long_timer = NULL;
6232 elm_widget_stringlist_free(it->texts);
6234 elm_widget_stringlist_free(it->contents);
6235 it->contents = NULL;
6236 elm_widget_stringlist_free(it->states);
6239 EINA_LIST_FREE(it->content_objs, content)
6240 evas_object_del(content);
6242 it->unrealize_cb(it);
6244 it->realized = EINA_FALSE;
6245 it->want_unrealize = EINA_FALSE;
6246 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
6247 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
6251 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
6253 elm_widget_item_pre_notify_del(it);
6254 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
6256 if ((it->relcount > 0) || (it->walking > 0)) return;
6258 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6260 if (it->itc->func.del)
6261 it->itc->func.del((void *)it->base.data, WIDGET(it));
6265 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
6267 _elm_genlist_item_del_notserious(it);
6268 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6269 if (it->tooltip.del_cb)
6270 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6271 it->wd->walking -= it->walking;
6272 if (it->long_timer) ecore_timer_del(it->long_timer);
6274 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
6278 eina_inlist_sorted_state_free(it->wd->state);
6279 it->wd->state = NULL;
6281 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6282 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
6286 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
6287 it->wd->last_selected_item = NULL;
6288 it->wd->item_count--;
6292 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
6294 ELM_CHECK_WIDTYPE(obj, widtype);
6295 Widget_Data *wd = elm_widget_data_get(obj);
6297 wd->tree_effect_enabled = !!enabled;
6301 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
6303 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6304 Widget_Data *wd = elm_widget_data_get(obj);
6305 if (!wd) return EINA_FALSE;
6306 return wd->tree_effect_enabled;
6310 _create_tray_alpha_bg(const Evas_Object *obj)
6312 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6313 Widget_Data *wd = elm_widget_data_get(obj);
6314 if (!wd) return NULL;
6316 Evas_Object *bg = NULL;
6317 Evas_Coord ox, oy, ow, oh;
6319 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6320 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6321 evas_object_color_set(bg,0,0,0,0);
6322 evas_object_resize(bg , ow, oh);
6323 evas_object_move(bg , ox, oy);
6328 _item_contract_emit(Elm_Gen_Item *it)
6333 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6334 it->item->tree_effect_finished = EINA_FALSE;
6336 EINA_LIST_FOREACH(it->item->items, l, it2)
6337 if (it2) _item_contract_emit(it2);
6341 _item_tree_effect_before(Elm_Gen_Item *it)
6346 EINA_LIST_FOREACH(it->item->items, l, it2)
6348 if (it2->parent && (it == it2->parent))
6350 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6351 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6352 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6353 _item_contract_emit(it2);
6356 return ECORE_CALLBACK_CANCEL;
6360 _item_tree_effect(Widget_Data *wd, int y)
6362 Elm_Gen_Item *it = NULL, *expanded_next_it;
6364 expanded_next_it = wd->expanded_next_item;
6366 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6368 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6371 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6372 if (it->item->scrl_y && (it->item->scrl_y < expanded_next_it->item->old_scrl_y + y) &&
6373 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6375 if (!it->item->tree_effect_finished)
6377 edje_object_signal_emit(VIEW(it), "flip_item", "");
6378 evas_object_show(VIEW(it));
6379 it->item->tree_effect_finished = EINA_TRUE;
6382 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6385 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6387 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6390 if ((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), "elm,state,hide", "");
6396 it->item->tree_effect_finished = EINA_TRUE;
6401 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6407 _item_tree_effect_finish(Widget_Data *wd)
6410 Elm_Gen_Item *it = NULL;
6413 if (wd->item_moving_effect_timer)
6415 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6416 _item_subitems_clear(wd->expanded_item);
6417 EINA_INLIST_FOREACH(wd->blocks, itb)
6419 EINA_LIST_FOREACH(itb->items, l, it)
6421 it->item->tree_effect_finished = EINA_TRUE;
6422 it->item->old_scrl_y = it->item->scrl_y;
6426 _item_auto_scroll(wd);
6427 evas_object_lower(wd->alpha_bg);
6428 evas_object_hide(wd->alpha_bg);
6429 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6430 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6432 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6433 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6434 evas_object_smart_changed(wd->pan_smart);
6436 wd->item_moving_effect_timer = NULL;
6440 _item_moving_effect_timer_cb(void *data)
6442 Widget_Data *wd = data;
6443 if (!wd) return EINA_FALSE;
6444 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6445 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6447 double effect_duration = 0.5, t;
6448 int y = 0, dy = 0, dh = 0;
6449 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6452 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6453 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6454 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6455 if (t > effect_duration) end = EINA_TRUE;
6457 // Below while statement is needed, when the genlist is resized.
6458 it2 = wd->expanded_item;
6461 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6462 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6463 cvx, cvy, cvw, cvh));
6464 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6467 if (wd->expanded_next_item)
6469 expanded_next_it = wd->expanded_next_item;
6472 EINA_LIST_FOREACH(wd->move_items, l, it)
6474 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6476 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6477 if (expanded_next_it->item->scrl_y < expanded_next_it->item->old_scrl_y) //did not calculate next item position
6478 expanded_next_it->item->scrl_y = cvy + cvh;
6480 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6481 cvy + cvh : expanded_next_it->item->scrl_y) -
6482 expanded_next_it->item->old_scrl_y;
6484 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6486 if (expanded_next_it->item->scrl_y > expanded_next_it->item->old_scrl_y) //did not calculate next item position
6487 expanded_next_it->item->old_scrl_y = cvy + cvh;
6489 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6491 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6493 expanded_next_it->item->old_scrl_y = cvy + cvh;
6497 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6498 expanded_next_it->item->old_scrl_y;
6502 if (t <= effect_duration)
6504 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6514 _item_realize(it, in, 0);
6518 if (it != expanded_next_it)
6520 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6524 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6525 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6528 _item_tree_effect(wd, y);
6532 int expanded_item_num = 0;
6535 if (wd->expanded_item)
6536 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6541 expanded_item_num++;
6542 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6548 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6549 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6551 if (!it->item->tree_effect_finished)
6553 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6555 edje_object_signal_emit(VIEW(it), "flip_item", "");
6556 evas_object_show(VIEW(it));
6557 it->item->tree_effect_finished = EINA_TRUE;
6561 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6567 _item_tree_effect_finish(wd);
6568 return ECORE_CALLBACK_CANCEL;
6570 return ECORE_CALLBACK_RENEW;