3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.h"
9 // internally allocated
10 #define CLASS_ALLOCATED 0x3a70f11f
12 #define MAX_ITEMS_PER_BLOCK 32
13 #define REORDER_EFFECT_TIME 0.5
15 #define ELM_GEN_SETUP(wd) \
16 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
17 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
18 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
32 ERR("Genlist_Item_Class(itc) is NULL"); \
35 if ((itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) && \
36 (itc->version != CLASS_ALLOCATED)) \
38 ERR("Genlist_Item_Class version mismatched! current = (%d), required = (%d) or (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION, CLASS_ALLOCATED); \
44 typedef struct _Item_Block Item_Block;
45 typedef struct _Item_Cache Item_Cache;
47 struct Elm_Gen_Item_Type
52 Evas_Coord w, h, minw, minh;
53 Elm_Gen_Item *group_item;
54 Elm_Genlist_Item_Type type;
55 Eina_List *deco_it_texts, *deco_it_contents, *deco_it_states, *deco_it_content_objs;
56 Eina_List *deco_all_texts, *deco_all_contents, *deco_all_states, *deco_all_content_objs;
57 Eina_List *flip_contents, *flip_content_objs;
58 Ecore_Timer *swipe_timer;
59 Evas_Coord scrl_x, scrl_y, old_scrl_y;
62 Evas_Object *deco_it_view;
68 Eina_Bool want_realize : 1;
69 Eina_Bool expanded : 1;
70 Eina_Bool mincalcd : 1;
73 Eina_Bool updateme : 1;
74 Eina_Bool nocache : 1; /* do not use cache for this item */
75 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
76 Eina_Bool stacking_even : 1;
77 Eina_Bool nostacking : 1;
78 Eina_Bool move_effect_enabled : 1;
79 Eina_Bool decorate_all_item_realized : 1;
80 Eina_Bool tree_effect_finished : 1; /* tree effect */
81 Eina_Bool tree_effect_hideme : 1; /* item hide for tree effect */
92 Evas_Coord x, y, w, h, minw, minh;
94 int item_position_stamp;
96 Eina_Bool position_update : 1;
97 Eina_Bool want_unrealize : 1;
98 Eina_Bool realized : 1;
99 Eina_Bool changed : 1;
100 Eina_Bool updateme : 1;
101 Eina_Bool changeme : 1;
102 Eina_Bool showme : 1;
103 Eina_Bool must_recalc : 1;
110 Evas_Object *base_view, *spacer;
112 const char *item_style; // it->itc->item_style
113 Eina_Bool tree : 1; // it->group
115 Eina_Bool selected : 1; // it->selected
116 Eina_Bool disabled : 1; // it->disabled
117 Eina_Bool expanded : 1; // it->item->expanded
120 static const char *widtype = NULL;
121 static void _item_cache_zero(Widget_Data *wd);
122 static void _del_hook(Evas_Object *obj);
123 static void _mirrored_set(Evas_Object *obj,
125 static void _theme_hook(Evas_Object *obj);
126 static void _show_region_hook(void *data,
128 static void _sizing_eval(Evas_Object *obj);
129 static void _item_realize(Elm_Gen_Item *it,
132 static void _item_unrealize_cb(Elm_Gen_Item *it);
133 static void _item_block_unrealize(Item_Block *itb);
134 static void _calc_job(void *data);
135 static void _on_focus_hook(void *data,
137 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
138 static void _changed_job(void *data);
139 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
140 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
141 static Eina_Bool _item_single_select_up(Widget_Data *wd);
142 static Eina_Bool _item_single_select_down(Widget_Data *wd);
143 static Eina_Bool _event_hook(Evas_Object *obj,
145 Evas_Callback_Type type,
147 static void _signal_emit_hook(Evas_Object *obj,
148 const char *emission,
150 static Eina_Bool _deselect_all_items(Widget_Data *wd);
151 static void _pan_calculate(Evas_Object *obj);
152 static void _pan_max_get(Evas_Object *obj,
155 static void _item_position(Elm_Gen_Item *it,
159 static void _decorate_item_realize(Elm_Gen_Item *it);
160 static void _decorate_item_unrealize(Elm_Gen_Item *it);
161 static void _decorate_item_set(Elm_Gen_Item *it);
162 static void _decorate_item_unset(Widget_Data *wd);
163 static void _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity);
164 static void _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
165 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
168 static void _group_items_recalc(void *data);
170 static void _item_move_after(Elm_Gen_Item *it,
171 Elm_Gen_Item *after);
172 static void _item_move_before(Elm_Gen_Item *it,
173 Elm_Gen_Item *before);
174 static void _item_auto_scroll(Widget_Data *wd);
175 static void _elm_genlist_clear(Evas_Object *obj,
177 static void _pan_child_size_get(Evas_Object *obj,
180 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
181 static void _item_contract_emit(Elm_Gen_Item *it);
182 static int _item_tree_effect_before(Elm_Gen_Item *it);
183 static void _item_tree_effect(Widget_Data *wd, int y);
184 static void _item_tree_effect_finish(Widget_Data *wd);
185 static Eina_Bool _tree_effect_animator_cb(void *data);
187 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
189 static const char SIG_ACTIVATED[] = "activated";
190 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
191 static const char SIG_SELECTED[] = "selected";
192 static const char SIG_UNSELECTED[] = "unselected";
193 static const char SIG_EXPANDED[] = "expanded";
194 static const char SIG_CONTRACTED[] = "contracted";
195 static const char SIG_EXPAND_REQUEST[] = "expand,request";
196 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
197 static const char SIG_REALIZED[] = "realized";
198 static const char SIG_UNREALIZED[] = "unrealized";
199 static const char SIG_DRAG_START_UP[] = "drag,start,up";
200 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
201 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
202 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
203 static const char SIG_DRAG_STOP[] = "drag,stop";
204 static const char SIG_DRAG[] = "drag";
205 static const char SIG_LONGPRESSED[] = "longpressed";
206 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
207 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
208 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
209 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
210 static const char SIG_EDGE_TOP[] = "edge,top";
211 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
212 static const char SIG_EDGE_LEFT[] = "edge,left";
213 static const char SIG_EDGE_RIGHT[] = "edge,right";
214 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
215 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
216 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
217 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
218 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
219 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
220 static const char SIG_SWIPE[] = "swipe";
221 static const char SIG_MOVED[] = "moved";
222 static const char SIG_MOVED_AFTER[] = "moved,after";
223 static const char SIG_MOVED_BEFORE[] = "moved,before";
224 static const char SIG_INDEX_UPDATE[] = "index,update";
225 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
227 static const Evas_Smart_Cb_Description _signals[] = {
228 {SIG_CLICKED_DOUBLE, ""},
231 {SIG_UNSELECTED, ""},
233 {SIG_CONTRACTED, ""},
234 {SIG_EXPAND_REQUEST, ""},
235 {SIG_CONTRACT_REQUEST, ""},
237 {SIG_UNREALIZED, ""},
238 {SIG_DRAG_START_UP, ""},
239 {SIG_DRAG_START_DOWN, ""},
240 {SIG_DRAG_START_LEFT, ""},
241 {SIG_DRAG_START_RIGHT, ""},
244 {SIG_LONGPRESSED, ""},
245 {SIG_SCROLL_ANIM_START, ""},
246 {SIG_SCROLL_ANIM_STOP, ""},
247 {SIG_SCROLL_DRAG_START, ""},
248 {SIG_SCROLL_DRAG_STOP, ""},
250 {SIG_EDGE_BOTTOM, ""},
252 {SIG_EDGE_RIGHT, ""},
253 {SIG_MULTI_SWIPE_LEFT, ""},
254 {SIG_MULTI_SWIPE_RIGHT, ""},
255 {SIG_MULTI_SWIPE_UP, ""},
256 {SIG_MULTI_SWIPE_DOWN, ""},
257 {SIG_MULTI_PINCH_OUT, ""},
258 {SIG_MULTI_PINCH_IN, ""},
261 {SIG_MOVED_AFTER, ""},
262 {SIG_MOVED_BEFORE, ""},
263 {SIG_TREE_EFFECT_FINISHED, ""},
268 #undef ELM_CHECK_WIDTYPE
269 #define ELM_CHECK_WIDTYPE(obj, widtype) \
270 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
271 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
272 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
273 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
274 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
276 static const char *_gengrid = NULL;
277 static const char *_genlist = NULL;
279 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
281 elm_genlist_type_check(const Evas_Object *obj,
284 const char *provided, *expected = "(unknown)";
285 static int abort_on_warn = -1;
286 provided = elm_widget_type_get(obj);
287 if (!_genlist) _genlist = eina_stringshare_add("genlist");
288 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
289 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
291 if ((!provided) || (!provided[0]))
293 provided = evas_object_type_get(obj);
294 if ((!provided) || (!provided[0]))
295 provided = "(unknown)";
297 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
298 if (abort_on_warn == -1)
300 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
301 else abort_on_warn = 0;
303 if (abort_on_warn == 1) abort();
308 _event_hook(Evas_Object *obj,
309 Evas_Object *src __UNUSED__,
310 Evas_Callback_Type type,
313 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
314 Evas_Event_Key_Down *ev = event_info;
315 Widget_Data *wd = elm_widget_data_get(obj);
316 Evas_Coord pan_max_x = 0, pan_max_y = 0;
317 if (!wd) return EINA_FALSE;
318 if (!wd->items) return EINA_FALSE;
319 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
320 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
322 Elm_Object_Item *it = NULL;
325 Evas_Coord step_x = 0;
326 Evas_Coord step_y = 0;
329 Evas_Coord page_x = 0;
330 Evas_Coord page_y = 0;
332 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
333 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
334 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
335 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
337 if ((!strcmp(ev->keyname, "Left")) ||
338 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
342 else if ((!strcmp(ev->keyname, "Right")) ||
343 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
347 else if ((!strcmp(ev->keyname, "Up")) ||
348 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
350 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
351 (_item_multi_select_up(wd)))
352 || (_item_single_select_up(wd)))
354 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
360 else if ((!strcmp(ev->keyname, "Down")) ||
361 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
363 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
364 (_item_multi_select_down(wd)))
365 || (_item_single_select_down(wd)))
367 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
373 else if ((!strcmp(ev->keyname, "Home")) ||
374 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
376 it = elm_genlist_first_item_get(obj);
377 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
378 elm_genlist_item_selected_set(it, EINA_TRUE);
379 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
382 else if ((!strcmp(ev->keyname, "End")) ||
383 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
385 it = elm_genlist_last_item_get(obj);
386 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
387 elm_genlist_item_selected_set(it, EINA_TRUE);
388 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
391 else if ((!strcmp(ev->keyname, "Prior")) ||
392 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
395 y -= -(page_y * v_h) / 100;
399 else if ((!strcmp(ev->keyname, "Next")) ||
400 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
403 y += -(page_y * v_h) / 100;
407 else if (!strcmp(ev->keyname, "Escape"))
409 if (!_deselect_all_items(wd)) return EINA_FALSE;
410 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
413 else if (((!strcmp(ev->keyname, "Return")) ||
414 (!strcmp(ev->keyname, "KP_Enter")) ||
415 (!strcmp(ev->keyname, "space")))
416 && (!wd->multi) && (wd->selected))
418 it = elm_genlist_selected_item_get(obj);
419 elm_genlist_item_expanded_set(it,
420 !elm_genlist_item_expanded_get(it));
421 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
423 else return EINA_FALSE;
425 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
426 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
428 if (x > pan_max_x) x = pan_max_x;
430 if (y > pan_max_y) y = pan_max_y;
431 elm_smart_scroller_child_pos_set(wd->scr, x, y);
436 _deselect_all_items(Widget_Data *wd)
438 if (!wd->selected) return EINA_FALSE;
440 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
446 _item_multi_select_up(Widget_Data *wd)
448 if (!wd->selected) return EINA_FALSE;
449 if (!wd->multi) return EINA_FALSE;
451 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
452 if (!prev) return EINA_TRUE;
454 if (elm_genlist_item_selected_get(prev))
456 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
457 wd->last_selected_item = prev;
458 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
462 elm_genlist_item_selected_set(prev, EINA_TRUE);
463 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
469 _item_multi_select_down(Widget_Data *wd)
471 if (!wd->selected) return EINA_FALSE;
472 if (!wd->multi) return EINA_FALSE;
474 Elm_Object_Item *next;
475 next = elm_genlist_item_next_get(wd->last_selected_item);
476 if (!next) return EINA_TRUE;
478 if (elm_genlist_item_selected_get(next))
480 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
481 wd->last_selected_item = next;
482 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
486 elm_genlist_item_selected_set(next, EINA_TRUE);
487 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
493 _item_single_select_up(Widget_Data *wd)
498 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
499 while ((prev) && (prev->generation < wd->generation))
500 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
502 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
504 if (!prev) return EINA_FALSE;
506 _deselect_all_items(wd);
508 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
509 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
514 _item_single_select_down(Widget_Data *wd)
519 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
520 while ((next) && (next->generation < wd->generation))
521 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
523 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
525 if (!next) return EINA_FALSE;
527 _deselect_all_items(wd);
529 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
530 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
535 _on_focus_hook(void *data __UNUSED__,
538 Widget_Data *wd = elm_widget_data_get(obj);
540 if (elm_widget_focus_get(obj))
542 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
543 evas_object_focus_set(wd->obj, EINA_TRUE);
544 if ((wd->items) && (wd->selected) && (!wd->last_selected_item))
545 wd->last_selected_item = eina_list_data_get(wd->selected);
549 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
550 evas_object_focus_set(wd->obj, EINA_FALSE);
555 _del_hook(Evas_Object *obj)
557 Widget_Data *wd = elm_widget_data_get(obj);
559 _item_cache_zero(wd);
560 if (wd->calc_job) ecore_job_del(wd->calc_job);
561 if (wd->update_job) ecore_job_del(wd->update_job);
562 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
563 if (wd->changed_job) ecore_job_del(wd->changed_job);
564 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
565 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
566 if (wd->decorate_it_type) eina_stringshare_del(wd->decorate_it_type);
567 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
568 if (wd->tree_effect_animator) ecore_animator_del(wd->tree_effect_animator);
573 _del_pre_hook(Evas_Object *obj)
575 Widget_Data *wd = elm_widget_data_get(obj);
577 if (wd->decorate_all_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
578 elm_genlist_clear(obj);
579 evas_object_del(wd->pan_smart);
580 wd->pan_smart = NULL;
584 _mirrored_set(Evas_Object *obj,
587 Widget_Data *wd = elm_widget_data_get(obj);
589 _item_cache_zero(wd);
590 elm_smart_scroller_mirrored_set(wd->scr, rtl);
594 _theme_hook(Evas_Object *obj)
596 Widget_Data *wd = elm_widget_data_get(obj);
599 evas_event_freeze(evas_object_evas_get(wd->obj));
600 _item_cache_zero(wd);
601 _elm_widget_mirrored_reload(obj);
602 _mirrored_set(obj, elm_widget_mirrored_get(obj));
603 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
604 elm_widget_style_get(obj));
605 //edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
606 wd->item_width = wd->item_height = 0;
607 wd->group_item_width = wd->group_item_height = 0;
608 wd->minw = wd->minh = wd->realminw = 0;
609 EINA_INLIST_FOREACH(wd->blocks, itb)
614 if (itb->realized) _item_block_unrealize(itb);
615 EINA_LIST_FOREACH(itb->items, l, it)
616 it->item->mincalcd = EINA_FALSE;
618 itb->changed = EINA_TRUE;
620 if (wd->calc_job) ecore_job_del(wd->calc_job);
621 wd->calc_job = ecore_job_add(_calc_job, wd);
623 evas_event_thaw(evas_object_evas_get(wd->obj));
624 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
628 _show_region_hook(void *data,
631 Widget_Data *wd = elm_widget_data_get(data);
632 Evas_Coord x, y, w, h;
634 elm_widget_show_region_get(obj, &x, &y, &w, &h);
635 //x & y are screen coordinates, Add with pan coordinates
638 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
642 _translate_hook(Evas_Object *obj)
644 evas_object_smart_callback_call(obj, "language,changed", NULL);
648 _sizing_eval(Evas_Object *obj)
650 Widget_Data *wd = elm_widget_data_get(obj);
651 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
652 Evas_Coord vmw = 0, vmh = 0;
655 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
656 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
658 edje_object_size_min_calc
659 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
661 if (wd->mode == ELM_LIST_COMPRESS)
665 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
666 if ((vw != 0) && (vw != wd->prev_viewport_w))
670 wd->prev_viewport_w = vw;
671 EINA_INLIST_FOREACH(wd->blocks, itb)
673 itb->must_recalc = EINA_TRUE;
675 if (wd->calc_job) ecore_job_del(wd->calc_job);
676 wd->calc_job = ecore_job_add(_calc_job, wd);
678 edje_object_size_min_calc
679 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
683 else if (wd->mode == ELM_LIST_LIMIT)
694 evas_object_size_hint_min_set(obj, minw, minh);
695 evas_object_size_hint_max_set(obj, maxw, maxh);
699 _signal_emit_hook(Evas_Object *obj,
700 const char *emission,
703 Widget_Data *wd = elm_widget_data_get(obj);
704 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
709 _item_highlight(Elm_Gen_Item *it)
711 const char *selectraise;
712 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
713 (!it->wd->highlight) ||
714 (it->generation < it->wd->generation) ||
715 (it->highlighted) || elm_widget_item_disabled_get(it) ||
716 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->deco_it_view) ||
717 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
719 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
720 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
721 selectraise = edje_object_data_get(VIEW(it), "selectraise");
722 if ((selectraise) && (!strcmp(selectraise, "on")))
724 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
725 else evas_object_raise(VIEW(it));
728 if ((it->item->group_item) && (it->item->group_item->realized))
729 evas_object_raise(it->item->VIEW(group_item));
732 it->highlighted = EINA_TRUE;
736 _item_unhighlight(Elm_Gen_Item *it)
738 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
739 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
740 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
741 if (!it->item->nostacking)
743 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
745 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
746 else evas_object_lower(VIEW(it));
750 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
751 else evas_object_raise(VIEW(it));
754 it->highlighted = EINA_FALSE;
758 _item_block_position_update(Eina_Inlist *list, int idx)
762 EINA_INLIST_FOREACH(list, tmp)
764 tmp->position = idx++;
765 tmp->position_update = EINA_TRUE;
770 _item_position_update(Eina_List *list, int idx)
775 EINA_LIST_FOREACH(list, l, it)
777 it->position = idx++;
778 it->position_update = EINA_TRUE;
783 _item_block_del(Elm_Gen_Item *it)
786 Item_Block *itb = it->item->block;
787 Eina_Bool block_changed;
789 itb->items = eina_list_remove(itb->items, it);
791 itb->changed = EINA_TRUE;
792 if (!it->wd->reorder_deleted)
794 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
795 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
799 il = EINA_INLIST_GET(itb);
800 Item_Block *itbn = (Item_Block *)(il->next);
802 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
805 _item_block_position_update(il->next, itb->position);
806 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
809 if (itbn) itbn->changed = EINA_TRUE;
813 if (itb->count < itb->wd->max_items_per_block/2)
815 il = EINA_INLIST_GET(itb);
816 Item_Block *itbp = (Item_Block *)(il->prev);
817 Item_Block *itbn = (Item_Block *)(il->next);
818 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
822 EINA_LIST_FREE(itb->items, it2)
824 it2->item->block = itbp;
825 itbp->items = eina_list_append(itbp->items, it2);
827 itbp->changed = EINA_TRUE;
829 _item_block_position_update(EINA_INLIST_GET(itb)->next,
831 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
832 EINA_INLIST_GET(itb));
834 block_changed = EINA_TRUE;
836 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
840 Eina_List *last = eina_list_last(itb->items);
841 Elm_Gen_Item *it2 = last->data;
843 it2->item->block = itbn;
844 itb->items = eina_list_remove_list(itb->items, last);
845 itbn->items = eina_list_prepend(itbn->items, it2);
847 itbn->changed = EINA_TRUE;
849 _item_block_position_update(EINA_INLIST_GET(itb)->next,
852 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
854 block_changed = EINA_TRUE;
860 it->wd->pan_changed = EINA_TRUE;
861 evas_object_smart_changed(it->wd->pan_smart);
862 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
863 it->wd->calc_job = NULL;
868 _item_subitems_clear(Elm_Gen_Item *it)
870 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
871 Eina_List *tl = NULL, *l;
872 Elm_Object_Item *it2;
874 EINA_LIST_FOREACH(it->item->items, l, it2)
875 tl = eina_list_append(tl, it2);
876 EINA_LIST_FREE(tl, it2)
877 elm_object_item_del(it2);
881 _item_del(Elm_Gen_Item *it)
883 Evas_Object *obj = WIDGET(it);
884 Widget_Data *wd = it->wd;
886 evas_event_freeze(evas_object_evas_get(obj));
887 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
888 if (wd->show_item == it) wd->show_item = NULL;
889 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
890 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
891 if (it->item->block) _item_block_del(it);
892 if (it->item->queued)
893 wd->queue = eina_list_remove(wd->queue, it);
894 if (wd->anchor_item == it)
896 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
897 if (!wd->anchor_item)
898 wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
900 if (wd->expanded_item == it)
902 wd->expanded_item = NULL;
903 if (wd->tree_effect_animator)
905 ecore_animator_del(wd->tree_effect_animator);
906 wd->tree_effect_animator = NULL;
908 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
910 if (wd->expanded_next_item == it) wd->expanded_next_item = NULL;
911 if (wd->move_items) wd->move_items = eina_list_remove(wd->move_items, it);
913 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
914 if (it->item->swipe_timer)
916 ecore_timer_del(it->item->swipe_timer);
917 it->item->swipe_timer = NULL;
919 _elm_genlist_item_del_serious(it);
920 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
921 evas_event_thaw(evas_object_evas_get(obj));
922 evas_event_thaw_eval(evas_object_evas_get(obj));
926 _clear_cb(Widget_Data *wd)
928 wd->anchor_item = NULL;
929 if (wd->queue_idle_enterer)
931 ecore_idle_enterer_del(wd->queue_idle_enterer);
932 wd->queue_idle_enterer = NULL;
934 if (wd->must_recalc_idler)
936 ecore_idler_del(wd->must_recalc_idler);
937 wd->must_recalc_idler = NULL;
939 if (wd->queue) wd->queue = eina_list_free(wd->queue);
940 if (wd->reorder_move_animator)
942 ecore_animator_del(wd->reorder_move_animator);
943 wd->reorder_move_animator = NULL;
945 wd->show_item = NULL;
946 wd->reorder_old_pan_y = 0;
950 _item_unselect(Elm_Gen_Item *it)
952 if ((it->generation < it->wd->generation) || (!it->selected)) return;
953 it->selected = EINA_FALSE;
954 it->wd->selected = eina_list_remove(it->wd->selected, it);
955 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
959 _mouse_move(void *data,
960 Evas *evas __UNUSED__,
964 Elm_Gen_Item *it = data;
965 Evas_Event_Mouse_Move *ev = event_info;
966 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
967 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
969 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
971 if (!it->wd->on_hold)
973 it->wd->on_hold = EINA_TRUE;
974 if ((!it->wd->wasselected) && (!it->flipped))
976 _item_unhighlight(it);
981 if (it->wd->multitouched)
983 it->wd->cur_x = ev->cur.canvas.x;
984 it->wd->cur_y = ev->cur.canvas.y;
987 if ((it->dragging) && (it->down))
989 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
992 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
993 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
994 if (abs((it->wd->history[it->wd->movements].x -
995 it->wd->history[0].x)) > 40)
996 it->wd->swipe = EINA_TRUE;
1002 ecore_timer_del(it->long_timer);
1003 it->long_timer = NULL;
1005 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
1008 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
1012 ecore_timer_del(it->long_timer);
1013 it->long_timer = NULL;
1015 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1017 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
1018 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
1020 if (!it->wd->reorder_start_y)
1021 it->wd->reorder_start_y = it->item->block->y + it->y;
1025 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
1026 y_pos = oy + oh - it->wd->reorder_it->item->h;
1030 if (it->deco_all_view)
1031 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
1033 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1035 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1036 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1040 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1041 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1042 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1043 x = ev->cur.canvas.x - x;
1044 y = ev->cur.canvas.y - y;
1047 if (adx < 0) adx = -dx;
1050 if (ady < 0) ady = -dy;
1053 if ((adx > minw) || (ady > minh))
1055 it->dragging = EINA_TRUE;
1058 ecore_timer_del(it->long_timer);
1059 it->long_timer = NULL;
1061 if ((!it->wd->wasselected) && (!it->flipped))
1063 _item_unhighlight(it);
1068 if ((ady > adx) && (!it->wd->drag_started))
1069 evas_object_smart_callback_call(WIDGET(it),
1070 SIG_DRAG_START_UP, it);
1074 evas_object_smart_callback_call(WIDGET(it),
1075 SIG_DRAG_START_LEFT, it);
1077 evas_object_smart_callback_call(WIDGET(it),
1078 SIG_DRAG_START_RIGHT, it);
1083 if ((ady > adx) && (!it->wd->drag_started))
1084 evas_object_smart_callback_call(WIDGET(it),
1085 SIG_DRAG_START_DOWN, it);
1089 evas_object_smart_callback_call(WIDGET(it),
1090 SIG_DRAG_START_LEFT, it);
1092 evas_object_smart_callback_call(WIDGET(it),
1093 SIG_DRAG_START_RIGHT, it);
1100 _long_press(void *data)
1102 Elm_Gen_Item *it = data, *it_tmp;
1103 Eina_List *list, *l;
1105 it->long_timer = NULL;
1106 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1107 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1108 return ECORE_CALLBACK_CANCEL;
1109 it->wd->longpressed = EINA_TRUE;
1110 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1111 if ((it->wd->reorder_mode) && (!it->group))
1113 it->wd->reorder_it = it;
1114 it->wd->reorder_start_y = 0;
1115 if (it->deco_all_view)
1116 evas_object_raise(it->deco_all_view);
1118 evas_object_raise(VIEW(it));
1120 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1121 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1123 list = elm_genlist_realized_items_get(it->wd->obj);
1124 EINA_LIST_FOREACH(list, l, it_tmp)
1126 if (it != it_tmp) _item_unselect(it_tmp);
1128 if (it->item->items)
1130 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
1132 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
1134 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
1136 return ECORE_CALLBACK_RENEW;
1140 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1142 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1143 return ECORE_CALLBACK_RENEW;
1146 if (!it->wd->decorate_all_mode)
1147 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1149 return ECORE_CALLBACK_CANCEL;
1153 _swipe(Elm_Gen_Item *it)
1158 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1159 elm_widget_item_disabled_get(it)) return;
1160 it->wd->swipe = EINA_FALSE;
1161 for (i = 0; i < it->wd->movements; i++)
1163 sum += it->wd->history[i].x;
1164 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1167 sum /= it->wd->movements;
1168 if (abs(sum - it->wd->history[0].x) <= 10) return;
1169 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1173 _swipe_cancel(void *data)
1175 Elm_Gen_Item *it = data;
1177 if (!it) return ECORE_CALLBACK_CANCEL;
1178 it->wd->swipe = EINA_FALSE;
1179 it->wd->movements = 0;
1180 return ECORE_CALLBACK_RENEW;
1184 _multi_cancel(void *data)
1186 Widget_Data *wd = data;
1188 if (!wd) return ECORE_CALLBACK_CANCEL;
1189 wd->multi_timeout = EINA_TRUE;
1190 return ECORE_CALLBACK_RENEW;
1194 _multi_touch_gesture_eval(void *data)
1196 Elm_Gen_Item *it = data;
1198 it->wd->multitouched = EINA_FALSE;
1199 if (it->wd->multi_timer)
1201 ecore_timer_del(it->wd->multi_timer);
1202 it->wd->multi_timer = NULL;
1204 if (it->wd->multi_timeout)
1206 it->wd->multi_timeout = EINA_FALSE;
1210 Evas_Coord minw = 0, minh = 0;
1211 Evas_Coord off_x, off_y, off_mx, off_my;
1213 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1214 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1215 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1216 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1217 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1219 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1221 if ((off_x + off_mx) > (off_y + off_my))
1223 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1224 evas_object_smart_callback_call(WIDGET(it),
1225 SIG_MULTI_SWIPE_RIGHT, it);
1226 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1227 evas_object_smart_callback_call(WIDGET(it),
1228 SIG_MULTI_SWIPE_LEFT, it);
1229 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1230 evas_object_smart_callback_call(WIDGET(it),
1231 SIG_MULTI_PINCH_OUT, it);
1233 evas_object_smart_callback_call(WIDGET(it),
1234 SIG_MULTI_PINCH_IN, it);
1238 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1239 evas_object_smart_callback_call(WIDGET(it),
1240 SIG_MULTI_SWIPE_DOWN, it);
1241 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1242 evas_object_smart_callback_call(WIDGET(it),
1243 SIG_MULTI_SWIPE_UP, it);
1244 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1245 evas_object_smart_callback_call(WIDGET(it),
1246 SIG_MULTI_PINCH_OUT, it);
1248 evas_object_smart_callback_call(WIDGET(it),
1249 SIG_MULTI_PINCH_IN, it);
1252 it->wd->multi_timeout = EINA_FALSE;
1256 _multi_down(void *data,
1257 Evas *evas __UNUSED__,
1258 Evas_Object *obj __UNUSED__,
1261 Elm_Gen_Item *it = data;
1262 Evas_Event_Multi_Down *ev = event_info;
1264 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1265 it->wd->multi_device = ev->device;
1266 it->wd->multi_down = EINA_TRUE;
1267 it->wd->multitouched = EINA_TRUE;
1268 it->wd->prev_mx = ev->canvas.x;
1269 it->wd->prev_my = ev->canvas.y;
1270 if (!it->wd->wasselected)
1272 _item_unhighlight(it);
1275 it->wd->wasselected = EINA_FALSE;
1276 it->wd->longpressed = EINA_FALSE;
1279 ecore_timer_del(it->long_timer);
1280 it->long_timer = NULL;
1284 it->dragging = EINA_FALSE;
1285 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1287 if (it->item->swipe_timer)
1289 ecore_timer_del(it->item->swipe_timer);
1290 it->item->swipe_timer = NULL;
1292 if (it->wd->on_hold)
1294 it->wd->swipe = EINA_FALSE;
1295 it->wd->movements = 0;
1296 it->wd->on_hold = EINA_FALSE;
1301 _multi_up(void *data,
1302 Evas *evas __UNUSED__,
1303 Evas_Object *obj __UNUSED__,
1306 Elm_Gen_Item *it = data;
1307 Evas_Event_Multi_Up *ev = event_info;
1309 if (it->wd->multi_device != ev->device) return;
1310 it->wd->multi_device = 0;
1311 it->wd->multi_down = EINA_FALSE;
1312 if (it->wd->mouse_down) return;
1313 _multi_touch_gesture_eval(data);
1317 _multi_move(void *data,
1318 Evas *evas __UNUSED__,
1319 Evas_Object *obj __UNUSED__,
1322 Elm_Gen_Item *it = data;
1323 Evas_Event_Multi_Move *ev = event_info;
1325 if (it->wd->multi_device != ev->device) return;
1326 it->wd->cur_mx = ev->cur.canvas.x;
1327 it->wd->cur_my = ev->cur.canvas.y;
1331 _mouse_down(void *data,
1332 Evas *evas __UNUSED__,
1336 Elm_Gen_Item *it = data;
1337 Evas_Event_Mouse_Down *ev = event_info;
1340 Evas_Object *item_obj;
1342 if (ev->button != 1) return;
1345 EINA_LIST_FOREACH(it->content_objs, l, item_obj)
1347 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1349 if (elm_widget_type_get(obj) == _genlist)
1351 EINA_LIST_FOREACH(it->item->flip_content_objs, l, item_obj)
1353 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1355 EINA_LIST_FOREACH(it->item->deco_all_content_objs, l, item_obj)
1357 elm_widget_tree_unfocusable_set(item_obj, EINA_FALSE);
1360 it->can_focus = EINA_TRUE;
1362 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1364 it->wd->on_hold = EINA_TRUE;
1367 it->down = EINA_TRUE;
1368 it->dragging = EINA_FALSE;
1369 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1370 it->dx = ev->canvas.x - x;
1371 it->dy = ev->canvas.y - y;
1372 it->wd->mouse_down = EINA_TRUE;
1373 if (!it->wd->multitouched)
1375 it->wd->prev_x = ev->canvas.x;
1376 it->wd->prev_y = ev->canvas.y;
1377 it->wd->multi_timeout = EINA_FALSE;
1378 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1379 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1381 it->wd->longpressed = EINA_FALSE;
1382 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1383 else it->wd->on_hold = EINA_FALSE;
1384 if (it->wd->on_hold) return;
1385 it->wd->wasselected = it->selected;
1386 _item_highlight(it);
1387 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1388 if ((!elm_widget_item_disabled_get(it)) &&
1389 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1391 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1392 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1394 if (it->long_timer) ecore_timer_del(it->long_timer);
1395 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1396 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1398 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1401 it->long_timer = NULL;
1402 it->wd->swipe = EINA_FALSE;
1403 it->wd->movements = 0;
1407 _mouse_up(void *data,
1408 Evas *evas __UNUSED__,
1409 Evas_Object *obj __UNUSED__,
1412 Elm_Gen_Item *it = data;
1413 Evas_Event_Mouse_Up *ev = event_info;
1414 Eina_Bool dragged = EINA_FALSE;
1416 if (ev->button != 1) return;
1417 it->down = EINA_FALSE;
1418 it->wd->mouse_down = EINA_FALSE;
1419 if (it->wd->multitouched)
1421 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1422 if (it->wd->multi_down) return;
1423 _multi_touch_gesture_eval(data);
1426 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1427 else it->wd->on_hold = EINA_FALSE;
1430 ecore_timer_del(it->long_timer);
1431 it->long_timer = NULL;
1435 it->dragging = EINA_FALSE;
1436 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1439 if (it->item->swipe_timer)
1441 ecore_timer_del(it->item->swipe_timer);
1442 it->item->swipe_timer = NULL;
1444 if (it->wd->multi_timer)
1446 ecore_timer_del(it->wd->multi_timer);
1447 it->wd->multi_timer = NULL;
1448 it->wd->multi_timeout = EINA_FALSE;
1450 if (it->wd->on_hold)
1452 if (it->wd->swipe) _swipe(data);
1453 it->wd->longpressed = EINA_FALSE;
1454 it->wd->on_hold = EINA_FALSE;
1457 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1459 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1461 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1463 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1464 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1466 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1467 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1471 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1472 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1474 it->wd->reorder_deleted = EINA_FALSE;
1475 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1476 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1477 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1478 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1480 if (it->wd->longpressed)
1482 it->wd->longpressed = EINA_FALSE;
1483 if ((!it->wd->wasselected) && (!it->flipped))
1485 _item_unhighlight(it);
1488 it->wd->wasselected = EINA_FALSE;
1493 if (it->want_unrealize)
1495 _elm_genlist_item_unrealize(it, EINA_FALSE);
1496 if (it->item->block->want_unrealize)
1497 _item_block_unrealize(it->item->block);
1500 if (elm_widget_item_disabled_get(it) || (dragged) ||
1501 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1503 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1508 _item_highlight(it);
1513 _item_unhighlight(it);
1521 Widget_Data *wd = it->wd;
1524 while (wd->selected)
1526 _item_unhighlight(wd->selected->data);
1527 _item_unselect(wd->selected->data);
1533 const Eina_List *l, *l_next;
1536 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1539 _item_unhighlight(it2);
1540 _item_unselect(it2);
1542 //_item_highlight(it);
1545 _item_highlight(it);
1551 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1553 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1555 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1557 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1559 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1561 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1563 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1568 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1570 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1572 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1574 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1576 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1578 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1580 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1586 _mouse_down_scroller(void *data,
1587 Evas *evas __UNUSED__,
1588 Evas_Object *obj __UNUSED__,
1589 void *event_info __UNUSED__)
1591 Widget_Data *wd = elm_widget_data_get(data);
1594 wd->drag_started = EINA_FALSE;
1598 _mouse_up_scroller(void *data,
1599 Evas *evas __UNUSED__,
1600 Evas_Object *obj __UNUSED__,
1601 void *event_info __UNUSED__)
1603 Widget_Data *wd = elm_widget_data_get(data);
1606 wd->drag_started = EINA_FALSE;
1610 _mouse_move_scroller(void *data,
1611 Evas *evas __UNUSED__,
1612 Evas_Object *obj __UNUSED__,
1615 Widget_Data *wd = elm_widget_data_get(data);
1616 Evas_Event_Mouse_Move *ev = event_info;
1617 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
1620 if (wd->drag_started) return;
1622 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1623 dx = ev->cur.canvas.x - ev->prev.canvas.x;
1624 dy = ev->cur.canvas.y - ev->prev.canvas.y;
1627 if (adx < 0) adx = -dx;
1628 if (ady < 0) ady = -dy;
1629 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
1633 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
1634 wd->drag_started = EINA_TRUE;
1638 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
1639 wd->drag_started = EINA_TRUE;
1645 _signal_expand_toggle(void *data,
1646 Evas_Object *obj __UNUSED__,
1647 const char *emission __UNUSED__,
1648 const char *source __UNUSED__)
1650 Elm_Gen_Item *it = data;
1652 if (it->item->expanded)
1653 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1655 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1659 _signal_expand(void *data,
1660 Evas_Object *obj __UNUSED__,
1661 const char *emission __UNUSED__,
1662 const char *source __UNUSED__)
1664 Elm_Gen_Item *it = data;
1666 if (!it->item->expanded)
1667 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1671 _signal_contract(void *data,
1672 Evas_Object *obj __UNUSED__,
1673 const char *emission __UNUSED__,
1674 const char *source __UNUSED__)
1676 Elm_Gen_Item *it = data;
1678 if (it->item->expanded)
1679 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1683 _scr_hold_timer_cb(void *data)
1685 if (!data) return ECORE_CALLBACK_CANCEL;
1686 Widget_Data *wd = data;
1687 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1688 wd->scr_hold_timer = NULL;
1689 return ECORE_CALLBACK_CANCEL;
1693 _decorate_item_finished_signal_cb(void *data,
1695 const char *emission __UNUSED__,
1696 const char *source __UNUSED__)
1700 Elm_Gen_Item *it = data;
1701 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->deco_it_view)) return;
1703 Evas *te = evas_object_evas_get(obj);
1705 evas_event_freeze(te);
1706 it->item->nocache_once = EINA_FALSE;
1707 _decorate_item_unrealize(it);
1708 //FIXME: group raise
1710 if (it->item->group_item)
1711 evas_object_raise(it->item->VIEW(group_item));
1713 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_it_type);
1714 edje_object_signal_callback_del_full(obj, buf, "elm", _decorate_item_finished_signal_cb, it);
1715 evas_event_thaw(te);
1716 evas_event_thaw_eval(te);
1720 _item_cache_clean(Widget_Data *wd)
1722 evas_event_freeze(evas_object_evas_get(wd->obj));
1723 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1727 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1728 wd->item_cache = eina_inlist_remove(wd->item_cache,
1729 wd->item_cache->last);
1730 wd->item_cache_count--;
1731 if (itc->spacer) evas_object_del(itc->spacer);
1732 if (itc->base_view) evas_object_del(itc->base_view);
1733 eina_stringshare_del(itc->item_style);
1736 evas_event_thaw(evas_object_evas_get(wd->obj));
1737 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1741 _item_cache_zero(Widget_Data *wd)
1743 int pmax = wd->item_cache_max;
1744 wd->item_cache_max = 0;
1745 _item_cache_clean(wd);
1746 wd->item_cache_max = pmax;
1750 _item_cache_add(Elm_Gen_Item *it)
1754 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1755 if (it->wd->item_cache_max <= 0)
1757 evas_object_del(VIEW(it));
1761 evas_object_del(it->spacer);
1764 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1765 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1769 it->wd->item_cache_count++;
1770 itc = calloc(1, sizeof(Item_Cache));
1773 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1774 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1777 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1778 EINA_INLIST_GET(itc));
1779 itc->spacer = it->spacer;
1781 itc->base_view = VIEW(it);
1783 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1784 evas_object_hide(itc->base_view);
1785 evas_object_move(itc->base_view, -9999, -9999);
1786 itc->item_style = eina_stringshare_add(it->itc->item_style);
1787 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1788 itc->selected = it->selected;
1789 itc->disabled = elm_widget_item_disabled_get(it);
1790 itc->expanded = it->item->expanded;
1793 ecore_timer_del(it->long_timer);
1794 it->long_timer = NULL;
1796 if (it->item->swipe_timer)
1798 ecore_timer_del(it->item->swipe_timer);
1799 it->item->swipe_timer = NULL;
1801 // FIXME: other callbacks?
1802 edje_object_signal_callback_del_full(itc->base_view,
1803 "elm,action,expand,toggle",
1804 "elm", _signal_expand_toggle, it);
1805 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1807 _signal_expand, it);
1808 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1809 "elm", _signal_contract, it);
1810 _item_mouse_callbacks_del(it, itc->base_view);
1811 _item_cache_clean(it->wd);
1812 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1813 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1817 _item_cache_find(Elm_Gen_Item *it)
1822 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1823 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1825 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1827 if ((itc->tree == tree) &&
1828 (((!it->itc->item_style) && (!itc->item_style)) ||
1829 (it->itc->item_style && itc->item_style &&
1830 (!strcmp(it->itc->item_style, itc->item_style)))))
1832 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1833 EINA_INLIST_GET(itc));
1834 it->wd->item_cache_count--;
1842 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1844 if (it->position_update || it->item->block->position_update)
1846 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1847 it->position_update = EINA_FALSE;
1852 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1854 if (!it->item->nostacking)
1856 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1858 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
1859 else evas_object_lower(VIEW(it));
1863 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
1864 else evas_object_raise(VIEW(it));
1868 if (it->item->order_num_in & 0x1)
1870 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1871 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,odd", "elm");
1875 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1876 if (it->deco_all_view) edje_object_signal_emit(it->deco_all_view, "elm,state,even", "elm");
1881 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1885 if (it->selected != itc->selected)
1889 edje_object_signal_emit(VIEW(it),
1890 "elm,state,selected", "elm");
1892 if (it->deco_all_view)
1893 edje_object_signal_emit(it->deco_all_view,
1894 "elm,state,selected", "elm");
1897 if (elm_widget_item_disabled_get(it) != itc->disabled)
1899 if (elm_widget_item_disabled_get(it))
1900 edje_object_signal_emit(VIEW(it),
1901 "elm,state,disabled", "elm");
1902 if (it->deco_all_view)
1903 edje_object_signal_emit(it->deco_all_view,
1904 "elm,state,disabled", "elm");
1906 if (it->item->expanded != itc->expanded)
1908 if (it->item->expanded)
1909 edje_object_signal_emit(VIEW(it),
1910 "elm,state,expanded", "elm");
1911 if (it->deco_all_view)
1912 edje_object_signal_emit(it->deco_all_view,
1913 "elm,state,expanded", "elm");
1920 edje_object_signal_emit(VIEW(it),
1921 "elm,state,selected", "elm");
1922 if (it->deco_all_view)
1923 edje_object_signal_emit(it->deco_all_view,
1924 "elm,state,selected", "elm");
1926 if (elm_widget_item_disabled_get(it))
1928 edje_object_signal_emit(VIEW(it),
1929 "elm,state,disabled", "elm");
1930 if (it->deco_all_view)
1931 edje_object_signal_emit(it->deco_all_view,
1932 "elm,state,disabled", "elm");
1934 if (it->item->expanded)
1936 edje_object_signal_emit(VIEW(it),
1937 "elm,state,expanded", "elm");
1938 if (it->deco_all_view)
1939 edje_object_signal_emit(it->deco_all_view,
1940 "elm,state,expanded", "elm");
1946 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1948 Elm_Gen_Item *it = data;
1949 if (it) it->defer_unrealize = EINA_TRUE;
1953 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1955 Elm_Gen_Item *it = data;
1956 if (it) it->defer_unrealize = EINA_FALSE;
1961 _item_mode_content_realize(Elm_Gen_Item *it,
1962 Evas_Object *target,
1965 Eina_List **contents_list)
1967 Eina_List *res = *contents_list;
1969 if (it->itc->func.content_get)
1975 EINA_LIST_FOREACH(*source, l, key)
1977 if (parts && fnmatch(parts, key, FNM_PERIOD))
1980 ic = it->itc->func.content_get
1981 ((void *)it->base.data, WIDGET(it), key);
1985 res = eina_list_append(res, ic);
1986 edje_object_part_swallow(target, key, ic);
1987 evas_object_show(ic);
1988 elm_widget_sub_object_add(WIDGET(it), ic);
1991 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1992 // genlist does not need to handle this focus thing.
1993 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1994 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1996 if (elm_widget_item_disabled_get(it))
1997 elm_widget_disabled_set(ic, EINA_TRUE);
2006 _item_mode_content_unrealize(Elm_Gen_Item *it,
2007 Evas_Object *target,
2010 Eina_List **contents_list)
2012 Eina_List *res = *contents_list;
2014 if (it->itc->func.content_get)
2018 Evas_Object *ic = NULL;
2020 EINA_LIST_FOREACH(*source, l, key)
2022 if (parts && fnmatch(parts, key, FNM_PERIOD))
2025 ic = edje_object_part_swallow_get(target, key);
2028 res = eina_list_remove(res, ic);
2029 edje_object_part_unswallow(target, ic);
2030 evas_object_del(ic);
2039 _item_cache_free(Item_Cache *itc)
2041 if (itc->spacer) evas_object_del(itc->spacer);
2042 if (itc->base_view) evas_object_del(itc->base_view);
2043 eina_stringshare_del(itc->item_style);
2048 _item_text_realize(Elm_Gen_Item *it,
2049 Evas_Object *target,
2053 if (it->itc->func.text_get)
2059 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
2060 EINA_LIST_FOREACH(*source, l, key)
2062 if (parts && fnmatch(parts, key, FNM_PERIOD))
2065 char *s = it->itc->func.text_get
2066 ((void *)it->base.data, WIDGET(it), key);
2070 edje_object_part_text_escaped_set(target, key, s);
2075 edje_object_part_text_set(target, key, "");
2082 _item_content_unrealize(Elm_Gen_Item *it,
2083 Evas_Object *target,
2087 Eina_List *res = it->content_objs;
2089 if (it->itc->func.content_get)
2093 Evas_Object *ic = NULL;
2095 EINA_LIST_FOREACH(*source, l, key)
2097 if (parts && fnmatch(parts, key, FNM_PERIOD))
2100 ic = edje_object_part_swallow_get(target, key);
2103 res = eina_list_remove(res, ic);
2104 edje_object_part_unswallow(target, ic);
2105 evas_object_del(ic);
2114 _item_content_realize(Elm_Gen_Item *it,
2115 Evas_Object *target,
2119 Eina_List *res = it->content_objs;
2121 if (it->itc->func.content_get)
2125 Evas_Object *ic = NULL;
2128 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
2130 EINA_LIST_FOREACH(*source, l, key)
2132 if (parts && fnmatch(parts, key, FNM_PERIOD))
2135 if (it->itc->func.content_get)
2136 ic = it->itc->func.content_get
2137 ((void *)it->base.data, WIDGET(it), key);
2140 res = eina_list_append(res, ic);
2141 edje_object_part_swallow(target, key, ic);
2142 evas_object_show(ic);
2143 elm_widget_sub_object_add(WIDGET(it), ic);
2144 evas_object_event_callback_add(ic,
2145 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2146 _changed_size_hints, it);
2149 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2150 // genlist does not need to handle this focus thing.
2151 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2152 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2155 if (elm_widget_item_disabled_get(it))
2156 elm_widget_disabled_set(ic, EINA_TRUE);
2165 _item_state_realize(Elm_Gen_Item *it,
2166 Evas_Object *target,
2170 if (it->itc->func.state_get)
2177 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2178 EINA_LIST_FOREACH(*source, l, key)
2180 if (parts && fnmatch(parts, key, FNM_PERIOD))
2183 Eina_Bool on = it->itc->func.state_get
2184 ((void *)it->base.data, WIDGET(it), key);
2188 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2189 edje_object_signal_emit(target, buf, "elm");
2193 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2194 edje_object_signal_emit(target, buf, "elm");
2201 _item_realize(Elm_Gen_Item *it,
2205 const char *treesize;
2208 Item_Cache *itc = NULL;
2210 if (it->generation < it->wd->generation) return;
2211 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2214 if (it->item->order_num_in != in)
2216 it->item->order_num_in = in;
2217 _elm_genlist_item_odd_even_update(it);
2218 _elm_genlist_item_state_update(it, NULL);
2219 _elm_genlist_item_index_update(it);
2221 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2222 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2225 it->item->order_num_in = in;
2227 if ((it->item->nocache_once) && (!it->flipped))
2228 it->item->nocache_once = EINA_FALSE;
2229 else if (!it->item->nocache)
2230 itc = _item_cache_find(it);
2231 if (itc && (!it->wd->tree_effect_enabled))
2233 VIEW(it) = itc->base_view;
2234 itc->base_view = NULL;
2235 it->spacer = itc->spacer;
2240 const char *stacking_even;
2241 const char *stacking;
2243 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2244 edje_object_scale_set(VIEW(it),
2245 elm_widget_scale_get(WIDGET(it)) *
2246 _elm_config->scale);
2247 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2248 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2250 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2251 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2253 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2255 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2256 elm_widget_style_get(WIDGET(it)));
2258 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2259 if (!stacking_even) stacking_even = "above";
2260 it->item->stacking_even = !!strcmp("above", stacking_even);
2262 stacking = edje_object_data_get(VIEW(it), "stacking");
2263 if (!stacking) stacking = "yes";
2264 it->item->nostacking = !!strcmp("yes", stacking);
2266 edje_object_mirrored_set(VIEW(it),
2267 elm_widget_mirrored_get(WIDGET(it)));
2270 _elm_genlist_item_odd_even_update(it);
2272 treesize = edje_object_data_get(VIEW(it), "treesize");
2273 if (treesize) tsize = atoi(treesize);
2274 if (!it->spacer && treesize)
2277 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2278 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2279 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2283 evas_object_size_hint_min_set(it->spacer,
2284 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2285 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2289 edje_object_signal_callback_add(VIEW(it),
2290 "elm,action,expand,toggle",
2291 "elm", _signal_expand_toggle, it);
2292 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2293 "elm", _signal_expand, it);
2294 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2295 "elm", _signal_contract, it);
2296 _item_mouse_callbacks_add(it, VIEW(it));
2298 if ((it->wd->decorate_all_mode) && (!it->deco_all_view) &&
2299 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2300 _decorate_all_item_realize(it, EINA_FALSE);
2302 _elm_genlist_item_state_update(it, itc);
2303 _elm_genlist_item_index_update(it);
2306 if ((calc) && (it->wd->homogeneous) &&
2307 ((it->wd->item_width) ||
2308 ((it->wd->item_width) && (it->wd->group_item_width))))
2310 /* homogenous genlist shortcut */
2311 if (!it->item->mincalcd)
2315 it->item->w = it->item->minw = it->wd->group_item_width;
2316 it->item->h = it->item->minh = it->wd->group_item_height;
2320 it->item->w = it->item->minw = it->wd->item_width;
2321 it->item->h = it->item->minh = it->wd->item_height;
2323 it->item->mincalcd = EINA_TRUE;
2328 /* FIXME: If you see that assert, please notify us and we
2329 will clean our mess */
2330 assert(eina_list_count(it->content_objs) == 0);
2332 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2333 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2334 _item_state_realize(it, VIEW(it), &it->states, NULL);
2337 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2338 if (!(it->item->flip_contents))
2339 it->item->flip_contents =
2340 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "flips"));
2341 it->item->flip_content_objs =
2342 _item_mode_content_realize(it, VIEW(it),
2343 &it->item->flip_contents, NULL,
2344 &it->item->flip_content_objs);
2347 if (!it->item->mincalcd || ((it->wd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
2349 Evas_Coord mw = -1, mh = -1;
2351 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2352 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2353 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2354 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2356 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2357 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2358 it->item->w = it->item->minw = mw;
2359 it->item->h = it->item->minh = mh;
2360 it->item->mincalcd = EINA_TRUE;
2362 if ((!it->wd->group_item_width) && (it->group))
2364 it->wd->group_item_width = mw;
2365 it->wd->group_item_height = mh;
2367 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2369 it->wd->item_width = mw;
2370 it->wd->item_height = mh;
2373 if (!calc) evas_object_show(VIEW(it));
2376 if (it->tooltip.content_cb)
2378 elm_widget_item_tooltip_content_cb_set(it,
2379 it->tooltip.content_cb,
2380 it->tooltip.data, NULL);
2381 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2382 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2385 if (it->mouse_cursor)
2386 elm_widget_item_cursor_set(it, it->mouse_cursor);
2388 it->realized = EINA_TRUE;
2389 it->want_unrealize = EINA_FALSE;
2391 if (itc) _item_cache_free(itc);
2392 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2393 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2396 if (it->item->tree_effect_hideme)
2398 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2399 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2400 it->item->tree_effect_hideme = EINA_FALSE;
2402 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2405 if ((!calc) && (it->wd->decorate_all_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2407 if (it->itc->decorate_all_item_style)
2409 if (!it->deco_all_view) _decorate_all_item_realize(it, EINA_FALSE);
2410 edje_object_message_signal_process(it->deco_all_view);
2413 edje_object_message_signal_process(VIEW(it));
2417 _item_unrealize_cb(Elm_Gen_Item *it)
2419 Evas_Object *content;
2420 elm_widget_stringlist_free(it->item->flip_contents);
2421 it->item->flip_contents = NULL;
2422 EINA_LIST_FREE(it->item->flip_content_objs, content)
2423 evas_object_del(content);
2425 if (it->item->nocache_once || it->item->nocache)
2427 evas_object_del(VIEW(it));
2431 evas_object_del(it->spacer);
2437 edje_object_mirrored_set(VIEW(it),
2438 elm_widget_mirrored_get(WIDGET(it)));
2439 edje_object_scale_set(VIEW(it),
2440 elm_widget_scale_get(WIDGET(it))
2441 * _elm_config->scale);
2442 _item_cache_add(it);
2445 _decorate_item_unrealize(it);
2447 it->realized = EINA_FALSE;
2448 it->want_unrealize = EINA_FALSE;
2449 if (it->wd->decorate_all_mode) _decorate_all_item_unrealize(it);
2453 _item_block_recalc(Item_Block *itb,
2459 Evas_Coord minw = 0, minh = 0;
2460 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2463 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2465 EINA_LIST_FOREACH(itb->items, l, it)
2467 if (it->generation < it->wd->generation) continue;
2468 showme |= it->item->showme;
2473 if (!it->item->mincalcd) changed = EINA_TRUE;
2476 _item_realize(it, in, EINA_TRUE);
2477 _elm_genlist_item_unrealize(it, EINA_TRUE);
2482 _item_realize(it, in, EINA_TRUE);
2483 _elm_genlist_item_unrealize(it, EINA_TRUE);
2488 if (!it->item->mincalcd) changed = EINA_TRUE;
2489 _item_realize(it, in, EINA_FALSE);
2491 minh += it->item->minh;
2492 if (minw < it->item->minw) minw = it->item->minw;
2498 if (changed) itb->wd->pan_changed = changed;
2501 itb->changed = EINA_FALSE;
2502 itb->position_update = EINA_FALSE;
2503 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2504 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2509 _item_block_realize(Item_Block *itb)
2511 if (itb->realized) return;
2512 itb->realized = EINA_TRUE;
2513 itb->want_unrealize = EINA_FALSE;
2517 _item_block_unrealize(Item_Block *itb)
2521 Eina_Bool dragging = EINA_FALSE;
2523 if (!itb->realized) return;
2524 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2525 EINA_LIST_FOREACH(itb->items, l, it)
2527 if (itb->must_recalc || !it->group)
2531 dragging = EINA_TRUE;
2532 it->want_unrealize = EINA_TRUE;
2535 _elm_genlist_item_unrealize(it, EINA_FALSE);
2540 itb->realized = EINA_FALSE;
2541 itb->want_unrealize = EINA_TRUE;
2544 itb->want_unrealize = EINA_FALSE;
2545 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2546 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2550 _get_space_for_reorder_item(Elm_Gen_Item *it)
2552 Evas_Coord rox, roy, row, roh, oy, oh;
2553 Eina_Bool top = EINA_FALSE;
2554 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2555 if (!reorder_it) return 0;
2557 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2558 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2560 if ((it->wd->reorder_start_y < it->item->block->y) &&
2561 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2563 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2564 if (it->item->block->count == 1)
2565 it->wd->reorder_rel = it;
2567 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2568 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2570 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2573 it->item->block->reorder_offset = 0;
2575 it->item->scrl_y += it->item->block->reorder_offset;
2577 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2578 rox, roy + (roh / 2), row, 1));
2581 it->wd->reorder_rel = it;
2582 it->item->scrl_y += it->wd->reorder_it->item->h;
2583 return it->wd->reorder_it->item->h;
2590 _reorder_move_animator_cb(void *data)
2592 Elm_Gen_Item *it = data;
2593 Eina_Bool down = EINA_FALSE;
2595 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2597 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2599 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2602 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2603 if (diff > it->item->h) y = diff / 2;
2605 if (it->item->old_scrl_y < it->item->scrl_y)
2607 it->item->old_scrl_y += y;
2610 else if (it->item->old_scrl_y > it->item->scrl_y)
2612 it->item->old_scrl_y -= y;
2616 if (it->deco_all_view)
2617 _item_position(it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2619 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2620 //FIXME : group raise
2622 _group_items_recalc(it->wd);
2625 if ((it->wd->reorder_pan_move) ||
2626 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2627 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2629 it->item->old_scrl_y = it->item->scrl_y;
2630 it->item->move_effect_enabled = EINA_FALSE;
2631 it->wd->reorder_move_animator = NULL;
2632 return ECORE_CALLBACK_CANCEL;
2634 return ECORE_CALLBACK_RENEW;
2638 _item_position(Elm_Gen_Item *it,
2646 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2647 evas_object_resize(view, it->item->w, it->item->h);
2648 evas_object_move(view, it_x, it_y);
2649 evas_object_show(view);
2650 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2651 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2655 _item_block_position(Item_Block *itb,
2660 //FIXME : group raise
2664 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2665 Eina_Bool vis = EINA_FALSE;
2666 Evas_Coord minh = 0;
2668 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2669 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2670 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2672 EINA_LIST_FOREACH(itb->items, l, it)
2674 if (it->generation < it->wd->generation) continue;
2675 else if (it->wd->reorder_it == it) continue;
2678 it->item->w = itb->w;
2679 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2680 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2682 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2683 cvx, cvy, cvw, cvh));
2684 //FIXME : group raise
2689 if ((itb->realized) && (!it->realized))
2691 if (vis) _item_realize(it, in, EINA_FALSE);
2695 if (vis || it->dragging)
2697 if (it->wd->reorder_mode)
2698 y += _get_space_for_reorder_item(it);
2699 //FIXME : group raise
2701 git = it->item->group_item;
2704 if (git->item->scrl_y < oy)
2705 git->item->scrl_y = oy;
2706 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2707 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2708 git->item->want_realize = EINA_TRUE;
2711 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2713 if (!it->item->move_effect_enabled)
2715 it->item->move_effect_enabled = EINA_TRUE;
2716 it->wd->reorder_move_animator =
2718 _reorder_move_animator_cb, it);
2721 if (!it->item->move_effect_enabled)
2723 if ((it->wd->decorate_all_mode) && (it->itc->decorate_all_item_style))
2724 _decorate_all_item_position(it, it->item->scrl_x,
2728 if (!it->wd->tree_effect_enabled ||
2729 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2730 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2731 (it->item->old_scrl_y == it->item->scrl_y)))
2733 if (it->item->deco_it_view)
2734 _item_position(it, it->item->deco_it_view,
2738 _item_position(it, VIEW(it), it->item->scrl_x,
2742 it->item->old_scrl_y = it->item->scrl_y;
2747 if (!it->wd->tree_effect_animator)
2749 it->want_unrealize = EINA_TRUE;
2750 _elm_genlist_item_unrealize(it, EINA_FALSE);
2756 //FIXME : group raise
2760 if (vis) it->item->want_realize = EINA_TRUE;
2764 minh += it->item->minh;
2766 if (!itb->wd->reorder_it) itb->minh = minh;
2767 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2768 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2771 //FIXME: group raise
2774 _group_items_recalc(void *data)
2776 Widget_Data *wd = data;
2780 evas_event_freeze(evas_object_evas_get(wd->obj));
2781 EINA_LIST_FOREACH(wd->group_items, l, git)
2783 if (git->item->want_realize)
2786 _item_realize(git, 0, EINA_FALSE);
2787 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2788 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2789 evas_object_show(VIEW(git));
2790 evas_object_raise(VIEW(git));
2792 else if (!git->item->want_realize && git->realized)
2795 _elm_genlist_item_unrealize(git, EINA_FALSE);
2798 evas_event_thaw(evas_object_evas_get(wd->obj));
2799 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2804 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2806 Elm_Gen_Item *it = data;
2808 if (it->want_unrealize) return;
2809 it->item->mincalcd = EINA_FALSE;
2810 it->item->block->changeme = EINA_TRUE;
2811 if (it->wd->changed_job) ecore_job_del(it->wd->changed_job);
2812 it->wd->changed_job = ecore_job_add(_changed_job, it->wd);
2816 _must_recalc_idler(void *data)
2818 Widget_Data *wd = data;
2819 if (wd->calc_job) ecore_job_del(wd->calc_job);
2820 wd->calc_job = ecore_job_add(_calc_job, wd);
2821 wd->must_recalc_idler = NULL;
2822 return ECORE_CALLBACK_CANCEL;
2826 _scroll_item(Widget_Data *wd)
2828 Elm_Gen_Item *it = NULL;
2829 //FIXME: group raise
2831 Evas_Coord gith = 0;
2833 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2834 if (!wd->show_item) return;
2836 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2838 dx = it->x + it->item->block->x;
2839 dy = it->y + it->item->block->y;
2840 dw = it->item->block->w;
2842 switch (wd->scrollto_type)
2844 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2845 //FIXME: group raise
2847 if (it->item->group_item) gith = it->item->group_item->item->h;
2851 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2852 dy += ((it->item->h / 2) - (oh / 2));
2854 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2856 if ((wd->expanded_item) &&
2857 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2858 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2860 it = wd->expanded_item;
2861 dx = it->x + it->item->block->x;
2862 dy = it->y + it->item->block->y;
2863 //FIXME: group raise
2865 if (it->item->group_item) gith = it->item->group_item->item->h;
2866 dx = it->x + it->item->block->x;
2867 dy = it->y + it->item->block->y - gith;
2869 dw = it->item->block->w;
2873 //FIXME: group raise
2875 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2876 gith = it->item->group_item->item->h;
2884 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2886 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2888 it->item->showme = EINA_FALSE;
2889 wd->show_item = NULL;
2890 wd->auto_scroll_enabled = EINA_FALSE;
2891 wd->check_scroll = EINA_FALSE;
2895 _calc_job(void *data)
2897 Widget_Data *wd = data;
2898 Item_Block *itb, *chb = NULL;
2899 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2900 Evas_Coord pan_w = 0, pan_h = 0;
2902 Eina_Bool minw_change = EINA_FALSE;
2903 Eina_Bool did_must_recalc = EINA_FALSE;
2906 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2907 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2912 evas_event_freeze(evas_object_evas_get(wd->obj));
2913 EINA_INLIST_FOREACH(wd->blocks, itb)
2915 Eina_Bool showme = EINA_FALSE;
2918 showme = itb->showme;
2919 itb->showme = EINA_FALSE;
2922 if (itb->realized) _item_block_unrealize(itb);
2924 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2926 if (itb->must_recalc)
2930 EINA_LIST_FOREACH(itb->items, l, it)
2931 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2932 itb->changed = EINA_TRUE;
2933 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2934 if (itb->realized) _item_block_unrealize(itb);
2935 itb->must_recalc = EINA_FALSE;
2937 showme = _item_block_recalc(itb, in, EINA_FALSE);
2943 if (minw == -1) minw = itb->minw;
2944 else if ((!itb->must_recalc) && (minw < itb->minw))
2947 minw_change = EINA_TRUE;
2952 minw_change = EINA_TRUE;
2958 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2959 wd->check_scroll = EINA_TRUE;
2963 EINA_INLIST_FOREACH(wd->blocks, itb)
2969 if ((chb) && (EINA_INLIST_GET(chb)->next))
2971 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2973 if (itb->realized) _item_block_unrealize(itb);
2976 wd->realminw = minw;
2977 if (minw < wd->w) minw = wd->w;
2978 if ((minw != wd->minw) || (minh != wd->minh))
2982 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2983 _sizing_eval(wd->obj);
2984 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2989 it = wd->anchor_item;
2990 it_y = wd->anchor_y;
2991 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2992 it->item->block->y + it->y + it_y);
2993 wd->anchor_item = it;
2994 wd->anchor_y = it_y;
2997 if (did_must_recalc)
2999 if (!wd->must_recalc_idler)
3000 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
3002 if (wd->check_scroll)
3004 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
3005 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
3006 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3007 switch (wd->scrollto_type)
3009 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
3012 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
3015 case ELM_GENLIST_ITEM_SCROLLTO_IN:
3022 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
3023 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
3029 wd->calc_job = NULL;
3030 evas_object_smart_changed(wd->pan_smart);
3031 evas_event_thaw(evas_object_evas_get(wd->obj));
3032 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3036 _update_job(void *data)
3038 Widget_Data *wd = data;
3042 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
3044 wd->update_job = NULL;
3047 evas_event_freeze(evas_object_evas_get(wd->obj));
3048 EINA_INLIST_FOREACH(wd->blocks, itb)
3050 Evas_Coord itminw, itminh;
3057 _item_block_position(itb, num);
3061 recalc = EINA_FALSE;
3062 EINA_LIST_FOREACH(itb->items, l2, it)
3064 if (it->item->updateme)
3066 itminw = it->item->minw;
3067 itminh = it->item->minh;
3071 _elm_genlist_item_unrealize(it, EINA_FALSE);
3072 _item_realize(it, num, EINA_FALSE);
3073 position = EINA_TRUE;
3077 _item_realize(it, num, EINA_TRUE);
3078 _elm_genlist_item_unrealize(it, EINA_TRUE);
3080 if ((it->item->minw != itminw) || (it->item->minh != itminh))
3082 it->item->updateme = EINA_FALSE;
3086 itb->updateme = EINA_FALSE;
3089 position = EINA_TRUE;
3090 itb->changed = EINA_TRUE;
3091 _item_block_recalc(itb, num0, EINA_FALSE);
3092 _item_block_position(itb, num0);
3097 if (wd->calc_job) ecore_job_del(wd->calc_job);
3098 wd->calc_job = ecore_job_add(_calc_job, wd);
3100 evas_event_thaw(evas_object_evas_get(wd->obj));
3101 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3105 _changed_job(void *data)
3107 Widget_Data *wd = data; Eina_List *l2;
3109 int num, num0, position = 0;
3110 Eina_Bool width_changed = EINA_FALSE, height_changed = EINA_FALSE;
3112 wd->changed_job = NULL;
3114 EINA_INLIST_FOREACH(wd->blocks, itb)
3116 Evas_Coord itminw, itminh;
3123 _item_block_position(itb, num);
3127 width_changed = height_changed = EINA_FALSE;
3128 EINA_LIST_FOREACH(itb->items, l2, it)
3130 if ((!it->item->mincalcd) && (it->realized))
3132 Evas_Coord mw = -1, mh = -1;
3133 itminw = it->item->minw;
3134 itminh = it->item->minh;
3136 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->w;
3137 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3138 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3139 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
3140 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
3141 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3142 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3144 width_changed = EINA_TRUE;
3147 it->item->w = it->item->minw = mw;
3148 it->item->h = it->item->minh = mh;
3149 it->item->mincalcd = EINA_TRUE;
3151 //if ((it->item->minw != itminw) || (it->item->minh != itminh))
3152 //if ((it->item->minh != itminh))
3154 if ((it->item->minw != itminw))
3155 width_changed = EINA_TRUE;
3156 if ((it->item->minh != itminh))
3157 height_changed = EINA_TRUE;
3159 if ((!it->wd->group_item_width) && (it->group))
3161 it->wd->group_item_width = mw;
3162 it->wd->group_item_height = mh;
3164 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
3166 it->wd->item_width = mw;
3167 it->wd->item_height = mh;
3172 itb->changeme = EINA_FALSE;
3173 // TODO: why this is separated.
3177 itb->changed = EINA_TRUE;
3178 _item_block_recalc(itb, num0, 0);
3179 _item_block_position(itb, num0);
3181 else if (width_changed)
3183 _item_block_position(itb, num0);
3188 if (wd->calc_job) ecore_job_del(wd->calc_job);
3189 wd->calc_job = ecore_job_add(_calc_job, wd);
3194 _pan_set(Evas_Object *obj,
3198 Pan *sd = evas_object_smart_data_get(obj);
3202 // Evas_Coord ow, oh;
3203 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3204 // ow = sd->wd->minw - ow;
3205 // if (ow < 0) ow = 0;
3206 // oh = sd->wd->minh - oh;
3207 // if (oh < 0) oh = 0;
3208 // if (x < 0) x = 0;
3209 // if (y < 0) y = 0;
3210 // if (x > ow) x = ow;
3211 // if (y > oh) y = oh;
3212 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
3216 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3218 if ((itb->y + itb->h) > y)
3223 EINA_LIST_FOREACH(itb->items, l2, it)
3225 if ((itb->y + it->y) >= y)
3227 sd->wd->anchor_item = it;
3228 sd->wd->anchor_y = -(itb->y + it->y - y);
3235 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
3239 _pan_get(Evas_Object *obj,
3243 Pan *sd = evas_object_smart_data_get(obj);
3246 if (x) *x = sd->wd->pan_x;
3247 if (y) *y = sd->wd->pan_y;
3251 _pan_max_get(Evas_Object *obj,
3255 Pan *sd = evas_object_smart_data_get(obj);
3259 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3260 ow = sd->wd->minw - ow;
3262 oh = sd->wd->minh - oh;
3269 _pan_min_get(Evas_Object *obj __UNUSED__,
3278 _pan_child_size_get(Evas_Object *obj,
3282 Pan *sd = evas_object_smart_data_get(obj);
3285 if (w) *w = sd->wd->minw;
3286 if (h) *h = sd->wd->minh;
3290 _pan_add(Evas_Object *obj)
3293 Evas_Object_Smart_Clipped_Data *cd;
3296 cd = evas_object_smart_data_get(obj);
3299 sd->__clipped_data = *cd;
3301 evas_object_smart_data_set(obj, sd);
3305 _pan_del(Evas_Object *obj)
3307 Pan *sd = evas_object_smart_data_get(obj);
3312 ecore_job_del(sd->resize_job);
3313 sd->resize_job = NULL;
3319 _pan_resize_job(void *data)
3323 _sizing_eval(sd->wd->obj);
3324 sd->resize_job = NULL;
3328 _pan_resize(Evas_Object *obj,
3332 Pan *sd = evas_object_smart_data_get(obj);
3336 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3337 if ((ow == w) && (oh == h)) return;
3338 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3341 if (sd->resize_job) ecore_job_del(sd->resize_job);
3342 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3344 sd->wd->pan_changed = EINA_TRUE;
3345 evas_object_smart_changed(obj);
3346 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3347 sd->wd->calc_job = NULL;
3351 _pan_calculate(Evas_Object *obj)
3353 Pan *sd = evas_object_smart_data_get(obj);
3355 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3357 //FIXME: group raise
3364 evas_event_freeze(evas_object_evas_get(obj));
3366 if (sd->wd->pan_changed)
3369 sd->wd->pan_changed = EINA_FALSE;
3372 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3373 sd->wd->prev_viewport_w = ow;
3374 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3375 //FIXME: group raise
3377 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3379 git->item->want_realize = EINA_FALSE;
3383 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3385 if (!sd->wd->tree_effect_animator)
3387 _item_tree_effect_before(sd->wd->expanded_item);
3388 evas_object_raise(sd->wd->alpha_bg);
3389 evas_object_show(sd->wd->alpha_bg);
3390 sd->wd->start_time = ecore_time_get();
3391 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3395 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3397 itb->w = sd->wd->minw;
3398 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3399 itb->y - sd->wd->pan_y + oy,
3401 cvx, cvy, cvw, cvh))
3403 if ((!itb->realized) || (itb->changed))
3405 _item_block_realize(itb);
3407 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3408 sd->wd->calc_job = NULL;
3411 _item_block_position(itb, in);
3415 if (itb->realized) _item_block_unrealize(itb);
3419 //FIXME: group raise
3421 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3422 _group_items_recalc(sd->wd);
3424 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3426 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3427 sd->wd->reorder_pan_move = EINA_TRUE;
3428 else sd->wd->reorder_pan_move = EINA_FALSE;
3429 evas_object_raise(sd->wd->VIEW(reorder_it));
3430 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3431 sd->wd->start_time = ecore_loop_time_get();
3434 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3435 _item_auto_scroll(sd->wd);
3437 evas_event_thaw(evas_object_evas_get(obj));
3438 evas_event_thaw_eval(evas_object_evas_get(obj));
3442 _pan_move(Evas_Object *obj,
3443 Evas_Coord x __UNUSED__,
3444 Evas_Coord y __UNUSED__)
3446 Pan *sd = evas_object_smart_data_get(obj);
3450 sd->wd->pan_changed = EINA_TRUE;
3451 evas_object_smart_changed(obj);
3452 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3453 sd->wd->calc_job = NULL;
3457 _hold_on(void *data __UNUSED__,
3459 void *event_info __UNUSED__)
3461 Widget_Data *wd = elm_widget_data_get(obj);
3463 elm_smart_scroller_hold_set(wd->scr, 1);
3467 _hold_off(void *data __UNUSED__,
3469 void *event_info __UNUSED__)
3471 Widget_Data *wd = elm_widget_data_get(obj);
3473 elm_smart_scroller_hold_set(wd->scr, 0);
3477 _freeze_on(void *data __UNUSED__,
3479 void *event_info __UNUSED__)
3481 Widget_Data *wd = elm_widget_data_get(obj);
3483 elm_smart_scroller_freeze_set(wd->scr, 1);
3487 _freeze_off(void *data __UNUSED__,
3489 void *event_info __UNUSED__)
3491 Widget_Data *wd = elm_widget_data_get(obj);
3493 elm_smart_scroller_freeze_set(wd->scr, 0);
3497 _scr_anim_start(void *data,
3498 Evas_Object *obj __UNUSED__,
3499 void *event_info __UNUSED__)
3501 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3505 _scr_anim_stop(void *data,
3506 Evas_Object *obj __UNUSED__,
3507 void *event_info __UNUSED__)
3509 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3513 _scr_drag_start(void *data,
3514 Evas_Object *obj __UNUSED__,
3515 void *event_info __UNUSED__)
3517 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3521 _scr_drag_stop(void *data,
3522 Evas_Object *obj __UNUSED__,
3523 void *event_info __UNUSED__)
3525 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3529 _edge_left(void *data,
3530 Evas_Object *scr __UNUSED__,
3531 void *event_info __UNUSED__)
3533 Evas_Object *obj = data;
3534 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3538 _edge_right(void *data,
3539 Evas_Object *scr __UNUSED__,
3540 void *event_info __UNUSED__)
3542 Evas_Object *obj = data;
3543 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3547 _edge_top(void *data,
3548 Evas_Object *scr __UNUSED__,
3549 void *event_info __UNUSED__)
3551 Evas_Object *obj = data;
3552 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3556 _edge_bottom(void *data,
3557 Evas_Object *scr __UNUSED__,
3558 void *event_info __UNUSED__)
3560 Evas_Object *obj = data;
3561 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3565 _decorate_item_realize(Elm_Gen_Item *it)
3569 if ((it->item->deco_it_view) || (it->generation < it->wd->generation)) return;
3571 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3572 it->item->deco_it_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3573 edje_object_scale_set(it->item->deco_it_view,
3574 elm_widget_scale_get(WIDGET(it)) *
3575 _elm_config->scale);
3576 evas_object_smart_member_add(it->item->deco_it_view, it->wd->pan_smart);
3577 elm_widget_sub_object_add(WIDGET(it), it->item->deco_it_view);
3579 strncpy(buf, "item", sizeof(buf));
3580 if (it->wd->mode == ELM_LIST_COMPRESS)
3581 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3583 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3584 strncat(buf, "/", sizeof(buf) - strlen(buf));
3585 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3587 _elm_theme_object_set(WIDGET(it), it->item->deco_it_view, "genlist", buf,
3588 elm_widget_style_get(WIDGET(it)));
3589 edje_object_mirrored_set(it->item->deco_it_view,
3590 elm_widget_mirrored_get(WIDGET(it)));
3592 /* signal callback add */
3593 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN,
3595 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_UP,
3597 evas_object_event_callback_add(it->item->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE,
3600 /* text_get, content_get, state_get */
3601 /* FIXME: If you see that assert, please notify us and we
3602 will clean our mess */
3603 assert(eina_list_count(it->item->deco_it_content_objs) == 0);
3605 _item_text_realize(it, it->item->deco_it_view, &it->item->deco_it_texts, NULL);
3606 if (!it->item->deco_it_contents)
3607 it->item->deco_it_contents =
3608 elm_widget_stringlist_get(edje_object_data_get(it->item->deco_it_view, "contents"));
3609 it->item->deco_it_content_objs =
3610 _item_mode_content_realize(it, it->item->deco_it_view,
3611 &it->item->deco_it_contents, NULL,
3612 &it->item->deco_it_content_objs);
3613 _item_state_realize(it, it->item->deco_it_view, &it->item->deco_it_states, NULL);
3614 edje_object_part_swallow(it->item->deco_it_view,
3615 edje_object_data_get(it->item->deco_it_view, "mode_part"),
3618 it->want_unrealize = EINA_FALSE;
3619 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3620 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3624 _decorate_item_unrealize(Elm_Gen_Item *it)
3626 Widget_Data *wd = it->wd;
3627 Evas_Object *content;
3628 if (!it->item->deco_it_view) return;
3630 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3631 elm_widget_stringlist_free(it->item->deco_it_texts);
3632 it->item->deco_it_texts = NULL;
3633 elm_widget_stringlist_free(it->item->deco_it_contents);
3634 it->item->deco_it_contents = NULL;
3635 elm_widget_stringlist_free(it->item->deco_it_states);
3637 EINA_LIST_FREE(it->item->deco_it_content_objs, content)
3638 evas_object_del(content);
3640 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
3641 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3642 evas_object_del(it->item->deco_it_view);
3643 it->item->deco_it_view = NULL;
3645 if (wd->mode_item == it)
3646 wd->mode_item = NULL;
3647 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3648 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3652 _decorate_item_set(Elm_Gen_Item *it)
3655 Widget_Data *wd = it->wd;
3660 it->item->nocache_once = EINA_TRUE;
3662 if (wd->scr_hold_timer)
3664 ecore_timer_del(wd->scr_hold_timer);
3665 wd->scr_hold_timer = NULL;
3667 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3668 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3670 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3671 _decorate_item_realize(it);
3672 if (it->item->group_item)
3673 evas_object_raise(it->item->VIEW(group_item));
3674 _item_position(it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
3675 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3676 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3678 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_it_type);
3679 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3683 _decorate_item_unset(Widget_Data *wd)
3686 if (!wd->mode_item) return;
3687 char buf[1024], buf2[1024];
3691 it->item->nocache_once = EINA_TRUE;
3693 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_it_type);
3694 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_it_type);
3696 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
3697 edje_object_signal_callback_add(it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb, it);
3699 wd->mode_item = NULL;
3703 _decorate_all_item_position(Elm_Gen_Item *it, int itx, int ity)
3705 if ((!it) || (!it->wd->decorate_all_mode)) return;
3706 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
3707 evas_object_move(it->deco_all_view, itx, ity);
3711 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3714 const char *stacking_even;
3715 const char *stacking;
3717 if ((!it) || (it->item->decorate_all_item_realized) ||
3718 (it->generation < it->wd->generation))
3721 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3722 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
3723 _elm_config->scale);
3724 evas_object_smart_member_add(it->deco_all_view, it->wd->pan_smart);
3725 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
3727 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3728 strncpy(buf, "tree", sizeof(buf));
3729 else strncpy(buf, "item", sizeof(buf));
3730 if (it->wd->mode == ELM_LIST_COMPRESS)
3731 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3733 strncat(buf, "/", sizeof(buf) - strlen(buf));
3734 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3736 _elm_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
3737 elm_widget_style_get(WIDGET(it)));
3739 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3740 if (!stacking_even) stacking_even = "above";
3741 it->item->stacking_even = !!strcmp("above", stacking_even);
3743 stacking = edje_object_data_get(VIEW(it), "stacking");
3744 if (!stacking) stacking = "yes";
3745 it->item->nostacking = !!strcmp("yes", stacking);
3747 edje_object_mirrored_set(it->deco_all_view,
3748 elm_widget_mirrored_get(WIDGET(it)));
3750 _elm_genlist_item_odd_even_update(it);
3751 _elm_genlist_item_state_update(it, NULL);
3753 if (effect_on) edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled,effect", "elm");
3754 else edje_object_signal_emit(it->deco_all_view, "elm,state,decorate,enabled", "elm");
3756 _item_mouse_callbacks_del(it, VIEW(it));
3757 _item_mouse_callbacks_add(it, it->deco_all_view);
3759 _item_text_realize(it, it->deco_all_view, &it->item->deco_all_texts, NULL);
3760 if (it->flipped) edje_object_signal_emit(it->deco_all_view, "elm,state,flip,enabled", "elm");
3761 if (!it->item->deco_all_contents)
3762 it->item->deco_all_contents =
3763 elm_widget_stringlist_get(edje_object_data_get(it->deco_all_view, "decorate_contents"));
3764 it->item->deco_all_content_objs =
3765 _item_mode_content_realize(it, it->deco_all_view,
3766 &it->item->deco_all_contents, NULL,
3767 &it->item->deco_all_content_objs);
3768 _item_state_realize(it, it->deco_all_view, &it->item->deco_all_states, NULL);
3769 edje_object_part_swallow(it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
3771 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
3772 evas_object_show(it->deco_all_view);
3774 if (it->selected) edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
3776 it->item->decorate_all_item_realized = EINA_TRUE;
3777 it->want_unrealize = EINA_FALSE;
3781 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3784 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3786 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3787 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3788 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3789 _elm_genlist_item_odd_even_update(it);
3790 _elm_genlist_item_state_update(it, NULL);
3792 evas_object_del(it->deco_all_view);
3793 it->deco_all_view = NULL;
3794 elm_widget_stringlist_free(it->item->deco_all_texts);
3795 it->item->deco_all_texts = NULL;
3796 elm_widget_stringlist_free(it->item->deco_all_contents);
3797 it->item->deco_all_contents = NULL;
3798 elm_widget_stringlist_free(it->item->deco_all_states);
3799 it->item->deco_all_states = NULL;
3800 EINA_LIST_FREE(it->item->deco_all_content_objs, icon)
3801 evas_object_del(icon);
3802 edje_object_message_signal_process(it->deco_all_view);
3803 _item_mouse_callbacks_del(it, it->deco_all_view);
3804 _item_mouse_callbacks_add(it, VIEW(it));
3806 it->item->decorate_all_item_realized = EINA_FALSE;
3810 _item_auto_scroll(Widget_Data *wd)
3813 Elm_Gen_Item *tmp_item = NULL;
3815 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3817 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3818 if (!tmp_item) return;
3819 wd->show_item = tmp_item;
3820 wd->bring_in = EINA_TRUE;
3821 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3822 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3824 wd->show_item->item->showme = EINA_TRUE;
3825 wd->auto_scroll_enabled = EINA_FALSE;
3833 elm_genlist_add(Evas_Object *parent)
3838 Evas_Coord minw, minh;
3839 static Evas_Smart *smart = NULL;
3843 static Evas_Smart_Class sc;
3845 evas_object_smart_clipped_smart_set(&_pan_sc);
3847 sc.name = "elm_genlist_pan";
3848 sc.version = EVAS_SMART_CLASS_VERSION;
3851 sc.resize = _pan_resize;
3852 sc.move = _pan_move;
3853 sc.calculate = _pan_calculate;
3854 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3857 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3859 ELM_SET_WIDTYPE(widtype, "genlist");
3861 elm_widget_type_set(obj, "genlist");
3862 elm_widget_sub_object_add(parent, obj);
3863 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3864 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3865 elm_widget_data_set(obj, wd);
3866 elm_widget_del_hook_set(obj, _del_hook);
3867 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3868 elm_widget_theme_hook_set(obj, _theme_hook);
3869 elm_widget_can_focus_set(obj, EINA_TRUE);
3870 elm_widget_event_hook_set(obj, _event_hook);
3871 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3872 elm_widget_translate_hook_set(obj, _translate_hook);
3875 wd->scr = elm_smart_scroller_add(e);
3876 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_DOWN,
3877 _mouse_down_scroller, obj);
3878 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_UP,
3879 _mouse_up_scroller, obj);
3880 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_MOVE,
3881 _mouse_move_scroller, obj);
3882 elm_smart_scroller_widget_set(wd->scr, obj);
3883 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3884 elm_widget_style_get(obj));
3885 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3886 _elm_config->thumbscroll_bounce_enable);
3887 elm_widget_resize_object_set(obj, wd->scr);
3889 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3890 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3891 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3892 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3893 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3894 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3895 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3896 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3899 wd->mode = ELM_LIST_SCROLL;
3900 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3901 wd->item_cache_max = wd->max_items_per_block * 2;
3902 wd->longpress_timeout = _elm_config->longpress_timeout;
3903 wd->highlight = EINA_TRUE;
3904 wd->tree_effect_enabled = _elm_config->effect_enable;
3906 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3907 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3908 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3909 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3911 wd->pan_smart = evas_object_smart_add(e, smart);
3912 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3915 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3916 _pan_set, _pan_get, _pan_max_get,
3917 _pan_min_get, _pan_child_size_get);
3919 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3921 evas_object_size_hint_min_set(obj, minw, minh);
3923 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3925 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3931 _item_select(Elm_Gen_Item *it)
3934 Evas_Object *obj = WIDGET(it);
3935 Evas_Object *item_obj;
3937 if ((it->generation < it->wd->generation) || (it->decorate_it_set) ||
3938 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3939 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3943 it->selected = EINA_TRUE;
3944 it->wd->selected = eina_list_append(it->wd->selected, it);
3946 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3948 evas_object_ref(obj);
3951 if (it->wd->last_selected_item &&
3952 (it != (Elm_Gen_Item *) it->wd->last_selected_item))
3954 Elm_Gen_Item *_lsit = (Elm_Gen_Item *)it->wd->last_selected_item;
3956 EINA_LIST_FOREACH(_lsit->content_objs, l, item_obj)
3958 elm_widget_focused_object_clear(item_obj);
3959 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3961 if (elm_widget_type_get(obj) == _genlist)
3963 EINA_LIST_FOREACH(_lsit->item->flip_content_objs, l, item_obj)
3965 elm_widget_focused_object_clear(item_obj);
3966 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3968 EINA_LIST_FOREACH(_lsit->item->deco_all_content_objs, l, item_obj)
3970 elm_widget_focused_object_clear(item_obj);
3971 elm_widget_tree_unfocusable_set(item_obj, EINA_TRUE);
3974 _lsit->can_focus = EINA_FALSE;
3976 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3977 if (it->generation == it->wd->generation)
3978 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3981 if ((it->wd->clear_me) && (!it->wd->walking))
3982 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3985 if ((!it->walking) && (it->generation < it->wd->generation))
3990 elm_widget_item_free(it);
3994 it->wd->last_selected_item = (Elm_Object_Item *)it;
3996 evas_object_unref(obj);
3999 static Evas_Object *
4000 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
4002 return edje_object_part_swallow_get(VIEW(it), part);
4006 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
4008 if (content && part)
4010 it->content_objs = eina_list_append(it->content_objs, content);
4011 edje_object_part_swallow(VIEW(it), part, content);
4015 static Evas_Object *
4016 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
4019 obj = edje_object_part_swallow_get(VIEW(it), part);
4020 if (!obj) return NULL;
4021 it->content_objs = eina_list_remove(it->content_objs, obj);
4022 edje_object_part_unswallow(VIEW(it), obj);
4027 _item_text_get_hook(Elm_Gen_Item *it, const char *part)
4029 if (!it->itc->func.text_get) return NULL;
4030 return edje_object_part_text_get(VIEW(it), part);
4034 _item_disable_hook(Elm_Object_Item *it)
4038 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4040 if (_it->generation < _it->wd->generation) return;
4043 elm_genlist_item_selected_set(it, EINA_FALSE);
4047 if (elm_widget_item_disabled_get(it))
4049 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
4050 if (_it->deco_all_view)
4051 edje_object_signal_emit(_it->deco_all_view, "elm,state,disabled", "elm");
4055 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
4056 if (_it->deco_all_view)
4057 edje_object_signal_emit(_it->deco_all_view, "elm,state,enabled", "elm");
4059 EINA_LIST_FOREACH(_it->content_objs, l, obj)
4060 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
4065 _item_del_pre_hook(Elm_Object_Item *it)
4067 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4069 if ((_it->relcount > 0) || (_it->walking > 0))
4071 elm_genlist_item_subitems_clear(it);
4072 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
4073 _elm_genlist_item_del_notserious(_it);
4074 if (_it->item->block)
4076 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
4077 _it->item->block->changed = EINA_TRUE;
4078 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
4079 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
4083 _it->parent->item->items =
4084 eina_list_remove(_it->parent->item->items, it);
4094 _item_signal_emit_hook(Elm_Object_Item *it,
4095 const char *emission,
4098 edje_object_signal_emit(VIEW(it), emission, source);
4102 _elm_genlist_item_new(Widget_Data *wd,
4103 const Elm_Gen_Item_Class *itc,
4105 Elm_Gen_Item *parent,
4107 const void *func_data)
4111 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
4112 if (!it) return NULL;
4114 it->generation = wd->generation;
4116 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
4117 it->base.data = data;
4118 it->parent = parent;
4119 it->func.func = func;
4120 it->func.data = func_data;
4121 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
4122 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
4123 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
4124 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
4125 elm_widget_item_disable_hook_set(it, _item_disable_hook);
4126 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
4127 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
4130 it->sel_cb = (Ecore_Cb)_item_select;
4135 static Elm_Gen_Item *
4136 _item_new(Widget_Data *wd,
4137 const Elm_Genlist_Item_Class *itc,
4139 Elm_Gen_Item *parent,
4140 Elm_Genlist_Item_Type type,
4142 const void *func_data)
4144 Elm_Gen_Item *it, *it2;
4147 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
4148 if (!it) return NULL;
4149 it->item = ELM_NEW(Elm_Gen_Item_Type);
4150 it->item->type = type;
4151 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
4152 it->item->expanded_depth = 0;
4153 ELM_GEN_ITEM_SETUP(it);
4154 it->mouse_cursor = NULL;
4155 it->can_focus = EINA_TRUE;
4158 if (it->parent->group)
4159 it->item->group_item = parent;
4160 else if (it->parent->item->group_item)
4161 it->item->group_item = it->parent->item->group_item;
4163 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
4165 if (!it2->parent->group) depth += 1;
4167 it->item->expanded_depth = depth;
4173 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
4177 itb = calloc(1, sizeof(Item_Block));
4178 if (!itb) return NULL;
4182 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
4183 _item_block_position_update(wd->blocks, 0);
4187 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4188 itb->position_update = EINA_TRUE;
4189 if (wd->blocks != EINA_INLIST_GET(itb))
4191 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4202 _item_block_add(Widget_Data *wd,
4205 Item_Block *itb = NULL;
4212 itb = calloc(1, sizeof(Item_Block));
4213 if (!itb) return EINA_FALSE;
4215 if (!it->item->rel->item->block)
4218 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4219 itb->items = eina_list_append(itb->items, it);
4220 itb->position_update = EINA_TRUE;
4221 it->position = eina_list_count(itb->items);
4222 it->position_update = EINA_TRUE;
4224 if (wd->blocks != EINA_INLIST_GET(itb))
4226 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4237 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4238 if (it->item->before)
4240 wd->blocks = eina_inlist_prepend_relative
4241 (wd->blocks, EINA_INLIST_GET(itb),
4242 EINA_INLIST_GET(it->item->rel->item->block));
4244 eina_list_prepend_relative_list(itb->items, it, tmp);
4246 /* Update index from where we prepended */
4247 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4248 _item_block_position_update(EINA_INLIST_GET(itb),
4249 it->item->rel->item->block->position);
4253 wd->blocks = eina_inlist_append_relative
4254 (wd->blocks, EINA_INLIST_GET(itb),
4255 EINA_INLIST_GET(it->item->rel->item->block));
4257 eina_list_append_relative_list(itb->items, it, tmp);
4259 /* Update block index from where we appended */
4260 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4261 _item_block_position_update(EINA_INLIST_GET(itb),
4262 it->item->rel->item->block->position + 1);
4268 if (it->item->before)
4272 itb = (Item_Block *)(wd->blocks);
4273 if (itb->count >= wd->max_items_per_block)
4275 itb = _item_block_new(wd, EINA_TRUE);
4276 if (!itb) return EINA_FALSE;
4281 itb = _item_block_new(wd, EINA_TRUE);
4282 if (!itb) return EINA_FALSE;
4284 itb->items = eina_list_prepend(itb->items, it);
4286 _item_position_update(itb->items, 0);
4292 itb = (Item_Block *)(wd->blocks->last);
4293 if (itb->count >= wd->max_items_per_block)
4295 itb = _item_block_new(wd, EINA_FALSE);
4296 if (!itb) return EINA_FALSE;
4301 itb = _item_block_new(wd, EINA_FALSE);
4302 if (!itb) return EINA_FALSE;
4304 itb->items = eina_list_append(itb->items, it);
4305 it->position = eina_list_count(itb->items);
4313 if (it->item->rel->item->queued)
4315 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
4316 on sorted insertion order, so the queue is not always ordered like the item list.
4317 This lead to issue where we depend on an item that is not yet created. As a quick
4318 work around, we reschedule the calc of the item and stop reordering the list to
4319 prevent any nasty issue to show up here.
4321 wd->queue = eina_list_append(wd->queue, it);
4322 wd->requeued = EINA_TRUE;
4323 it->item->queued = EINA_TRUE;
4326 itb = it->item->rel->item->block;
4327 if (!itb) goto newblock;
4328 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4329 if (it->item->before)
4331 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4332 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4336 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4337 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4341 itb->changed = EINA_TRUE;
4342 it->item->block = itb;
4343 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
4344 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
4347 it->item->rel->relcount--;
4348 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
4350 _item_del(it->item->rel);
4351 elm_widget_item_free(it->item->rel);
4353 it->item->rel = NULL;
4355 if (itb->count > itb->wd->max_items_per_block)
4360 Eina_Bool done = EINA_FALSE;
4362 newc = itb->count / 2;
4364 if (EINA_INLIST_GET(itb)->prev)
4366 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4368 if (itbp->count + newc < wd->max_items_per_block / 2)
4370 /* moving items to previous block */
4371 while ((itb->count > newc) && (itb->items))
4373 it2 = eina_list_data_get(itb->items);
4374 itb->items = eina_list_remove_list(itb->items, itb->items);
4377 itbp->items = eina_list_append(itbp->items, it2);
4378 it2->item->block = itbp;
4386 if (!done && EINA_INLIST_GET(itb)->next)
4388 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4390 if (itbn->count + newc < wd->max_items_per_block / 2)
4392 /* moving items to next block */
4393 while ((itb->count > newc) && (itb->items))
4397 l = eina_list_last(itb->items);
4398 it2 = eina_list_data_get(l);
4399 itb->items = eina_list_remove_list(itb->items, l);
4402 itbn->items = eina_list_prepend(itbn->items, it2);
4403 it2->item->block = itbn;
4413 /* moving items to new block */
4414 itb2 = calloc(1, sizeof(Item_Block));
4415 if (!itb2) return EINA_FALSE;
4418 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4419 EINA_INLIST_GET(itb));
4420 itb2->changed = EINA_TRUE;
4421 while ((itb->count > newc) && (itb->items))
4425 l = eina_list_last(itb->items);
4427 itb->items = eina_list_remove_list(itb->items, l);
4430 itb2->items = eina_list_prepend(itb2->items, it2);
4431 it2->item->block = itb2;
4441 _queue_process(Widget_Data *wd)
4444 Eina_Bool showme = EINA_FALSE;
4447 t0 = ecore_loop_time_get();
4448 //evas_event_freeze(evas_object_evas_get(wd->obj));
4449 for (n = 0; (wd->queue) && (n < 128); n++)
4453 it = eina_list_data_get(wd->queue);
4454 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4455 it->item->queued = EINA_FALSE;
4456 if (!_item_block_add(wd, it)) continue;
4458 _item_block_realize(it->item->block);
4459 t = ecore_time_get();
4460 if (it->item->block->changed)
4462 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4463 it->item->block->changed = 0;
4464 if (wd->pan_changed)
4466 if (wd->calc_job) ecore_job_del(wd->calc_job);
4467 wd->calc_job = NULL;
4469 wd->pan_changed = EINA_FALSE;
4472 if (showme) it->item->block->showme = EINA_TRUE;
4473 /* same as eina_inlist_count > 1 */
4474 if (wd->blocks && wd->blocks->next)
4476 if ((t - t0) > (ecore_animator_frametime_get())) break;
4479 //evas_event_thaw(evas_object_evas_get(wd->obj));
4480 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4485 _idle_process(void *data, Eina_Bool *wakeup)
4487 Widget_Data *wd = data;
4490 //static double q_start = 0.0;
4491 //if (q_start == 0.0) q_start = ecore_time_get();
4493 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4497 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4499 return ECORE_CALLBACK_CANCEL;
4501 return ECORE_CALLBACK_RENEW;
4505 _item_idle_enterer(void *data)
4507 Widget_Data *wd = data;
4508 Eina_Bool wakeup = EINA_FALSE;
4509 Eina_Bool ok = _idle_process(data, &wakeup);
4514 if (wd->calc_job) ecore_job_del(wd->calc_job);
4515 wd->calc_job = ecore_job_add(_calc_job, wd);
4517 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4522 _item_queue(Widget_Data *wd,
4526 if (it->item->queued) return;
4527 it->item->queued = EINA_TRUE;
4528 if (cb && !wd->requeued)
4529 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4531 wd->queue = eina_list_append(wd->queue, it);
4532 // FIXME: why does a freeze then thaw here cause some genlist
4533 // elm_genlist_item_append() to be much much slower?
4534 // evas_event_freeze(evas_object_evas_get(wd->obj));
4535 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4537 if (wd->queue_idle_enterer)
4539 ecore_idle_enterer_del(wd->queue_idle_enterer);
4540 wd->queue_idle_enterer = NULL;
4544 // evas_event_thaw(evas_object_evas_get(wd->obj));
4545 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4546 if (!wd->queue_idle_enterer)
4547 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4551 _elm_genlist_item_compare(const void *data, const void *data1)
4553 const Elm_Gen_Item *it, *item1;
4554 it = ELM_GEN_ITEM_FROM_INLIST(data);
4555 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4556 return it->wd->item_compare_cb(it, item1);
4560 _elm_genlist_item_list_compare(const void *data, const void *data1)
4562 const Elm_Gen_Item *it = data;
4563 const Elm_Gen_Item *item1 = data1;
4564 return it->wd->item_compare_cb(it, item1);
4567 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4569 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4574 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4575 _item_block_del(it);
4577 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4578 it->item->rel = after;
4579 it->item->rel->relcount++;
4580 it->item->before = EINA_FALSE;
4581 if (after->item->group_item) it->item->group_item = after->item->group_item;
4582 _item_queue(it->wd, it, NULL);
4584 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4587 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4589 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4592 if (!before) return;
4594 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4595 _item_block_del(it);
4596 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4597 it->item->rel = before;
4598 it->item->rel->relcount++;
4599 it->item->before = EINA_TRUE;
4600 if (before->item->group_item) it->item->group_item = before->item->group_item;
4601 _item_queue(it->wd, it, NULL);
4603 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4607 elm_genlist_items_count(const Evas_Object *obj)
4609 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4610 Widget_Data *wd = elm_widget_data_get(obj);
4612 return wd->item_count;
4615 EAPI Elm_Object_Item *
4616 elm_genlist_item_append(Evas_Object *obj,
4617 const Elm_Genlist_Item_Class *itc,
4619 Elm_Object_Item *parent,
4620 Elm_Genlist_Item_Type type,
4622 const void *func_data)
4624 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4625 Widget_Data *wd = elm_widget_data_get(obj);
4626 if (!wd) return NULL;
4627 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4629 if (!it) return NULL;
4633 wd->group_items = eina_list_append(wd->group_items, it);
4634 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4635 it->item->rel = NULL;
4639 Elm_Gen_Item *it2 = NULL;
4640 Eina_List *ll = eina_list_last(it->parent->item->items);
4641 if (ll) it2 = ll->data;
4642 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4643 if (!it2) it2 = it->parent;
4645 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4646 EINA_INLIST_GET(it2));
4647 it->item->rel = it2;
4648 it->item->rel->relcount++;
4650 it->item->before = EINA_FALSE;
4651 _item_queue(wd, it, NULL);
4652 return (Elm_Object_Item *)it;
4655 EAPI Elm_Object_Item *
4656 elm_genlist_item_prepend(Evas_Object *obj,
4657 const Elm_Genlist_Item_Class *itc,
4659 Elm_Object_Item *parent,
4660 Elm_Genlist_Item_Type type,
4662 const void *func_data)
4664 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4665 Widget_Data *wd = elm_widget_data_get(obj);
4666 if (!wd) return NULL;
4667 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4669 if (!it) return NULL;
4673 wd->group_items = eina_list_prepend(wd->group_items, it);
4674 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4675 it->item->rel = NULL;
4679 Elm_Gen_Item *it2 = NULL;
4680 Eina_List *ll = it->parent->item->items;
4681 if (ll) it2 = ll->data;
4682 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4683 if (!it2) it2 = it->parent;
4685 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4686 EINA_INLIST_GET(it2));
4687 it->item->rel = it2;
4688 it->item->rel->relcount++;
4690 it->item->before = EINA_TRUE;
4691 _item_queue(wd, it, NULL);
4692 return (Elm_Object_Item *)it;
4695 EAPI Elm_Object_Item *
4696 elm_genlist_item_insert_after(Evas_Object *obj,
4697 const Elm_Genlist_Item_Class *itc,
4699 Elm_Object_Item *parent,
4700 Elm_Object_Item *after,
4701 Elm_Genlist_Item_Type type,
4703 const void *func_data)
4705 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4706 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4707 Widget_Data *wd = elm_widget_data_get(obj);
4708 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4709 if (!wd) return NULL;
4710 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4711 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4713 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4715 if (!it) return NULL;
4718 if ((it->group) && (_after->group))
4719 wd->group_items = eina_list_append_relative(wd->group_items, it,
4724 it->parent->item->items =
4725 eina_list_append_relative(it->parent->item->items, it, _after);
4727 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4728 EINA_INLIST_GET(_after));
4729 it->item->rel = _after;
4730 it->item->rel->relcount++;
4731 it->item->before = EINA_FALSE;
4732 _item_queue(wd, it, NULL);
4733 return (Elm_Object_Item *)it;
4736 EAPI Elm_Object_Item *
4737 elm_genlist_item_insert_before(Evas_Object *obj,
4738 const Elm_Genlist_Item_Class *itc,
4740 Elm_Object_Item *parent,
4741 Elm_Object_Item *before,
4742 Elm_Genlist_Item_Type type,
4744 const void *func_data)
4746 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4747 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4748 Widget_Data *wd = elm_widget_data_get(obj);
4749 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4750 if (!wd) return NULL;
4751 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4752 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4754 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4756 if (!it) return NULL;
4759 if (it->group && _before->group)
4760 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4765 it->parent->item->items =
4766 eina_list_prepend_relative(it->parent->item->items, it, _before);
4768 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4769 EINA_INLIST_GET(_before));
4770 it->item->rel = _before;
4771 it->item->rel->relcount++;
4772 it->item->before = EINA_TRUE;
4773 _item_queue(wd, it, NULL);
4774 return (Elm_Object_Item *)it;
4777 EAPI Elm_Object_Item *
4778 elm_genlist_item_sorted_insert(Evas_Object *obj,
4779 const Elm_Genlist_Item_Class *itc,
4781 Elm_Object_Item *parent,
4782 Elm_Genlist_Item_Type type,
4783 Eina_Compare_Cb comp,
4785 const void *func_data)
4787 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4788 Widget_Data *wd = elm_widget_data_get(obj);
4789 if (!wd) return NULL;
4790 Elm_Gen_Item *rel = NULL;
4791 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4793 if (!it) return NULL;
4795 wd->item_compare_cb = comp;
4802 l = eina_list_search_sorted_near_list(it->parent->item->items,
4803 _elm_genlist_item_list_compare,
4807 rel = eina_list_data_get(l);
4811 if (cmp_result >= 0)
4813 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4814 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4815 it->item->before = EINA_FALSE;
4817 else if (cmp_result < 0)
4819 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4820 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4821 it->item->before = EINA_TRUE;
4828 wd->state = eina_inlist_sorted_state_new();
4829 eina_inlist_sorted_state_init(wd->state, wd->items);
4830 wd->requeued = EINA_FALSE;
4834 wd->group_items = eina_list_append(wd->group_items, it);
4836 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4837 _elm_genlist_item_compare, wd->state);
4839 if (EINA_INLIST_GET(it)->next)
4841 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4842 it->item->before = EINA_TRUE;
4844 else if (EINA_INLIST_GET(it)->prev)
4846 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4847 it->item->before = EINA_FALSE;
4853 it->item->rel = rel;
4854 it->item->rel->relcount++;
4857 _item_queue(wd, it, _elm_genlist_item_list_compare);
4859 return (Elm_Object_Item *)it;
4863 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4865 Eina_Inlist *next, *l;
4866 Widget_Data *wd = elm_widget_data_get(obj);
4869 if (!standby) wd->generation++;
4873 eina_inlist_sorted_state_free(wd->state);
4877 if (wd->walking > 0)
4879 wd->clear_me = EINA_TRUE;
4882 evas_event_freeze(evas_object_evas_get(wd->obj));
4883 for (l = wd->items, next = l ? l->next : NULL;
4885 l = next, next = next ? next->next : NULL)
4887 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4889 if (it->generation < wd->generation)
4891 Elm_Gen_Item *itn = NULL;
4893 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4894 if (itn) itn->walking++; /* prevent early death of subitem */
4896 elm_widget_item_free(it);
4897 if (itn) itn->walking--;
4900 wd->clear_me = EINA_FALSE;
4901 wd->pan_changed = EINA_TRUE;
4904 ecore_job_del(wd->calc_job);
4905 wd->calc_job = NULL;
4907 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4908 if (wd->clear_cb) wd->clear_cb(wd);
4914 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4915 wd->alpha_bg = NULL;
4919 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4920 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4922 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4923 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4924 evas_event_thaw(evas_object_evas_get(wd->obj));
4925 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4929 elm_genlist_clear(Evas_Object *obj)
4931 ELM_CHECK_WIDTYPE(obj, widtype);
4932 _elm_genlist_clear(obj, EINA_FALSE);
4936 elm_genlist_multi_select_set(Evas_Object *obj,
4939 ELM_CHECK_WIDTYPE(obj, widtype);
4940 Widget_Data *wd = elm_widget_data_get(obj);
4942 wd->multi = !!multi;
4946 elm_genlist_multi_select_get(const Evas_Object *obj)
4948 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4949 Widget_Data *wd = elm_widget_data_get(obj);
4950 if (!wd) return EINA_FALSE;
4954 EAPI Elm_Object_Item *
4955 elm_genlist_selected_item_get(const Evas_Object *obj)
4957 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4958 Widget_Data *wd = elm_widget_data_get(obj);
4959 if (!wd) return NULL;
4960 if (wd->selected) return wd->selected->data;
4964 EAPI const Eina_List *
4965 elm_genlist_selected_items_get(const Evas_Object *obj)
4967 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4968 Widget_Data *wd = elm_widget_data_get(obj);
4969 if (!wd) return NULL;
4970 return wd->selected;
4974 elm_genlist_realized_items_get(const Evas_Object *obj)
4976 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4977 Widget_Data *wd = elm_widget_data_get(obj);
4978 Eina_List *list = NULL;
4980 Eina_Bool done = EINA_FALSE;
4981 if (!wd) return NULL;
4982 EINA_INLIST_FOREACH(wd->blocks, itb)
4990 EINA_LIST_FOREACH(itb->items, l, it)
4992 if (it->realized) list = eina_list_append(list, it);
5003 EAPI Elm_Object_Item *
5004 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5009 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5010 Widget_Data *wd = elm_widget_data_get(obj);
5011 Evas_Coord ox, oy, ow, oh;
5014 if (!wd) return NULL;
5015 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5017 EINA_INLIST_FOREACH(wd->blocks, itb)
5022 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
5023 oy + itb->y - itb->wd->pan_y,
5024 itb->w, itb->h, x, y, 1, 1))
5026 EINA_LIST_FOREACH(itb->items, l, it)
5028 Evas_Coord itx, ity;
5030 itx = ox + itb->x + it->x - itb->wd->pan_x;
5031 ity = oy + itb->y + it->y - itb->wd->pan_y;
5032 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5036 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5037 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5041 return (Elm_Object_Item *)it;
5043 lasty = ity + it->item->h;
5048 if (y > lasty) *posret = 1;
5054 EAPI Elm_Object_Item *
5055 elm_genlist_first_item_get(const Evas_Object *obj)
5057 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5058 Widget_Data *wd = elm_widget_data_get(obj);
5059 if (!wd) return NULL;
5060 if (!wd->items) return NULL;
5061 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
5062 while ((it) && (it->generation < wd->generation))
5063 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5064 return (Elm_Object_Item *)it;
5067 EAPI Elm_Object_Item *
5068 elm_genlist_last_item_get(const Evas_Object *obj)
5070 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5071 Widget_Data *wd = elm_widget_data_get(obj);
5072 if (!wd) return NULL;
5073 if (!wd->items) return NULL;
5074 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
5075 while ((it) && (it->generation < wd->generation))
5076 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5077 return (Elm_Object_Item *)it;
5080 EAPI Elm_Object_Item *
5081 elm_genlist_item_next_get(const Elm_Object_Item *it)
5083 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5084 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5087 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
5088 if ((_it) && (_it->generation == _it->wd->generation)) break;
5090 return (Elm_Object_Item *) _it;
5093 EAPI Elm_Object_Item *
5094 elm_genlist_item_prev_get(const Elm_Object_Item *it)
5096 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5097 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5100 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
5101 if ((_it) && (_it->generation == _it->wd->generation)) break;
5103 return (Elm_Object_Item *) _it;
5106 EAPI Elm_Object_Item *
5107 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5109 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5110 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
5114 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
5116 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5117 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
5119 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5121 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
5122 _item_subitems_clear(_it);
5125 if (!wd->tree_effect_animator)
5127 wd->expanded_item = _it;
5128 _item_tree_effect_before(_it);
5129 evas_object_raise(wd->alpha_bg);
5130 evas_object_show(wd->alpha_bg);
5131 wd->start_time = ecore_time_get();
5132 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
5135 _item_subitems_clear(_it);
5140 elm_genlist_item_selected_set(Elm_Object_Item *it,
5143 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5144 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5145 Widget_Data *wd = _it->wd;
5147 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
5149 selected = !!selected;
5150 if (_it->selected == selected) return;
5156 while (wd->selected)
5158 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
5159 _it->unsel_cb(wd->selected->data);
5162 _it->highlight_cb(_it);
5166 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
5171 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5173 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5174 return ((Elm_Gen_Item *)it)->selected;
5178 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5181 if (it->item->expanded)
5183 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5187 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5190 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5191 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5198 _elm_genlist_move_items_set(Elm_Gen_Item *it)
5201 Elm_Gen_Item *it2 = NULL;
5202 Evas_Coord ox, oy, ow, oh, dh = 0;
5204 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
5206 if (it->item->expanded)
5208 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
5209 EINA_LIST_FOREACH_SAFE(it->wd->move_items, l, ll, it2)
5211 if (it2 == it->wd->expanded_next_item) break;
5212 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
5217 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
5218 it2 = it->wd->expanded_next_item;
5219 while (it2 && (dh < oy + oh))
5222 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
5223 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5229 elm_genlist_item_expanded_set(Elm_Object_Item *it,
5232 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5233 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5234 expanded = !!expanded;
5235 if (_it->item->expanded == expanded) return;
5236 _it->item->expanded = expanded;
5237 _it->wd->expanded_item = _it;
5238 _elm_genlist_move_items_set(_it);
5240 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
5241 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
5243 if (_it->item->expanded)
5245 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
5247 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
5248 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
5249 _it->wd->auto_scroll_enabled = EINA_TRUE;
5253 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
5255 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
5256 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
5257 _it->wd->auto_scroll_enabled = EINA_FALSE;
5262 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5264 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5265 return ((Elm_Gen_Item *)it)->item->expanded;
5269 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5271 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
5272 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5275 EINA_DEPRECATED EAPI void
5276 elm_genlist_item_display_only_set(Elm_Object_Item *it,
5277 Eina_Bool display_only)
5279 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5280 display_only = !!display_only;
5283 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
5286 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5287 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5288 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
5292 EINA_DEPRECATED EAPI Eina_Bool
5293 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
5295 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5296 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5297 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5298 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5299 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5305 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
5306 Elm_Genlist_Item_Scrollto_Type type,
5313 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5314 Evas_Coord gith = 0;
5315 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5316 if ((_it->item->queued) || (!_it->item->mincalcd))
5318 _it->wd->show_item = _it;
5319 _it->wd->bring_in = bring_in;
5320 _it->wd->scrollto_type = type;
5321 _it->item->showme = EINA_TRUE;
5324 if (_it->wd->show_item)
5326 _it->wd->show_item->item->showme = EINA_FALSE;
5327 _it->wd->show_item = NULL;
5330 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
5333 case ELM_GENLIST_ITEM_SCROLLTO_IN:
5334 if ((_it->item->group_item) &&
5335 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
5336 gith = _it->item->group_item->item->h;
5338 *y = _it->y + _it->item->block->y - gith;
5340 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
5341 if (_it->item->group_item) gith = _it->item->group_item->item->h;
5342 *y = _it->y + _it->item->block->y - gith;
5344 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
5345 *y = _it->y + _it->item->block->y - (*h / 2) + (_it->item->h / 2);
5351 *x = _it->x + _it->item->block->x;
5352 *w = _it->item->block->w;
5357 elm_genlist_item_promote(Elm_Object_Item *it)
5359 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5360 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5361 if (_it->generation < _it->wd->generation) return;
5362 _item_move_before(_it,
5363 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
5367 elm_genlist_item_demote(Elm_Object_Item *it)
5369 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5370 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5371 if (_it->generation < _it->wd->generation) return;
5372 _item_move_after(_it,
5373 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
5377 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5379 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5380 Evas_Coord x, y, w, h;
5381 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5383 if (_elm_genlist_item_compute_coordinates(it, type, EINA_FALSE, &x, &y, &w, &h))
5384 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
5388 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5391 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5392 Evas_Coord x, y, w, h;
5393 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5395 if (_elm_genlist_item_compute_coordinates(it, type, EINA_TRUE, &x, &y, &w, &h))
5396 elm_smart_scroller_region_bring_in(_it->wd->scr, x, y, w, h);
5400 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5402 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5404 Evas_Object *content;
5405 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5407 elm_widget_sub_object_del(WIDGET(it), content);
5408 evas_object_smart_member_del(content);
5409 evas_object_hide(content);
5410 if (l) *l = eina_list_append(*l, content);
5415 elm_genlist_item_update(Elm_Object_Item *it)
5417 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5418 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5420 if (!_it->item->block) return;
5421 if (_it->generation < _it->wd->generation) return;
5422 _it->item->mincalcd = EINA_FALSE;
5423 _it->item->updateme = EINA_TRUE;
5424 _it->item->block->updateme = EINA_TRUE;
5425 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5426 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5430 elm_genlist_item_fields_update(Elm_Object_Item *it,
5432 Elm_Genlist_Item_Field_Type itf)
5434 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5435 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5437 if (!_it->item->block) return;
5438 if (_it->generation < _it->wd->generation) return;
5440 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5441 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5442 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5444 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5445 &_it->contents, parts);
5446 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5447 &_it->contents, parts);
5451 _it->item->flip_content_objs =
5452 _item_mode_content_unrealize(_it, VIEW(_it),
5453 &_it->item->flip_contents, parts,
5454 &_it->item->flip_content_objs);
5455 _it->item->flip_content_objs =
5456 _item_mode_content_realize(_it, VIEW(_it),
5457 &_it->item->flip_contents, parts,
5458 &_it->item->flip_content_objs);
5460 if (_it->item->deco_it_view)
5462 _it->item->deco_it_content_objs =
5463 _item_mode_content_unrealize(_it, _it->item->deco_it_view,
5464 &_it->item->deco_it_contents, parts,
5465 &_it->item->deco_it_content_objs);
5466 _it->item->deco_it_content_objs =
5467 _item_mode_content_realize(_it, _it->item->deco_it_view,
5468 &_it->item->deco_it_contents, parts,
5469 &_it->item->deco_it_content_objs);
5471 if (_it->wd->decorate_all_mode)
5473 _it->item->deco_all_content_objs =
5474 _item_mode_content_unrealize(_it, _it->deco_all_view,
5475 &_it->item->deco_all_contents, parts,
5476 &_it->item->deco_all_content_objs);
5477 _it->item->deco_all_content_objs =
5478 _item_mode_content_realize(_it, _it->deco_all_view,
5479 &_it->item->deco_all_contents, parts,
5480 &_it->item->deco_all_content_objs);
5483 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5484 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5488 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5489 const Elm_Genlist_Item_Class *itc)
5491 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5492 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5494 if (!_it->item->block) return;
5495 EINA_SAFETY_ON_NULL_RETURN(itc);
5496 if (_it->generation < _it->wd->generation) return;
5498 _it->item->nocache_once = EINA_TRUE;
5500 elm_widget_stringlist_free(_it->texts);
5502 elm_widget_stringlist_free(_it->contents);
5503 _it->contents = NULL;
5504 elm_widget_stringlist_free(_it->states);
5509 elm_widget_stringlist_free(_it->item->flip_contents);
5510 _it->item->flip_contents = NULL;
5512 if (_it->item->deco_it_view)
5514 elm_widget_stringlist_free(_it->item->deco_it_texts);
5515 _it->item->deco_it_texts = NULL;
5516 elm_widget_stringlist_free(_it->item->deco_it_contents);
5517 _it->item->deco_it_contents = NULL;
5519 if (_it->wd->decorate_all_mode)
5521 elm_widget_stringlist_free(_it->item->deco_all_texts);
5522 _it->item->deco_all_texts = NULL;
5523 elm_widget_stringlist_free(_it->item->deco_all_contents);
5524 _it->item->deco_all_contents = NULL;
5527 elm_genlist_item_update(it);
5530 EAPI const Elm_Genlist_Item_Class *
5531 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5533 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5534 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5535 if (_it->generation < _it->wd->generation) return NULL;
5539 static Evas_Object *
5540 _elm_genlist_item_label_create(void *data,
5541 Evas_Object *obj __UNUSED__,
5542 Evas_Object *tooltip,
5543 void *it __UNUSED__)
5545 Evas_Object *label = elm_label_add(tooltip);
5548 elm_object_style_set(label, "tooltip");
5549 elm_object_text_set(label, data);
5554 _elm_genlist_item_label_del_cb(void *data,
5555 Evas_Object *obj __UNUSED__,
5556 void *event_info __UNUSED__)
5558 eina_stringshare_del(data);
5562 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5565 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5566 text = eina_stringshare_add(text);
5567 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5569 _elm_genlist_item_label_del_cb);
5573 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5574 Elm_Tooltip_Item_Content_Cb func,
5576 Evas_Smart_Cb del_cb)
5578 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5579 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5581 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5584 if (_it->tooltip.del_cb)
5585 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5587 _it->tooltip.content_cb = func;
5588 _it->tooltip.data = data;
5589 _it->tooltip.del_cb = del_cb;
5593 elm_widget_item_tooltip_content_cb_set(_it,
5594 _it->tooltip.content_cb,
5595 _it->tooltip.data, NULL);
5596 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5597 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5603 if (del_cb) del_cb((void *)data, NULL, NULL);
5607 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5609 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5610 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5612 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5613 elm_widget_item_tooltip_unset(_it);
5615 if (_it->tooltip.del_cb)
5616 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5617 _it->tooltip.del_cb = NULL;
5618 _it->tooltip.content_cb = NULL;
5619 _it->tooltip.data = NULL;
5620 _it->tooltip.free_size = EINA_FALSE;
5621 if (_it->tooltip.style)
5622 elm_genlist_item_tooltip_style_set(it, NULL);
5626 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5629 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5630 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5632 eina_stringshare_replace(&_it->tooltip.style, style);
5633 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5637 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5639 return elm_object_item_tooltip_style_get(it);
5643 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5646 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5647 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5649 _it->tooltip.free_size = disable;
5650 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5655 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5657 return elm_object_tooltip_window_mode_get(VIEW(it));
5661 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5664 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5665 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5666 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5667 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5671 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5673 return elm_widget_item_cursor_get(it);
5677 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5679 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5680 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5682 if (!_it->mouse_cursor) return;
5684 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5686 eina_stringshare_del(_it->mouse_cursor);
5687 _it->mouse_cursor = NULL;
5691 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5694 elm_widget_item_cursor_style_set(it, style);
5698 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5700 return elm_widget_item_cursor_style_get(it);
5704 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5705 Eina_Bool engine_only)
5707 elm_widget_item_cursor_engine_only_set(it, engine_only);
5711 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5713 return elm_widget_item_cursor_engine_only_get(it);
5717 elm_genlist_item_index_get(const Elm_Object_Item *it)
5719 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5720 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5722 if (_it->item->block)
5723 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5728 elm_genlist_mode_set(Evas_Object *obj,
5731 ELM_CHECK_WIDTYPE(obj, widtype);
5732 Widget_Data *wd = elm_widget_data_get(obj);
5734 if (wd->mode == mode) return;
5736 if (wd->mode == ELM_LIST_COMPRESS)
5737 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5743 elm_genlist_mode_get(const Evas_Object *obj)
5745 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5746 Widget_Data *wd = elm_widget_data_get(obj);
5747 if (!wd) return ELM_LIST_LAST;
5752 elm_genlist_bounce_set(Evas_Object *obj,
5756 ELM_CHECK_WIDTYPE(obj, widtype);
5757 Widget_Data *wd = elm_widget_data_get(obj);
5759 wd->h_bounce = !!h_bounce;
5760 wd->v_bounce = !!v_bounce;
5761 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5765 elm_genlist_bounce_get(const Evas_Object *obj,
5766 Eina_Bool *h_bounce,
5767 Eina_Bool *v_bounce)
5769 ELM_CHECK_WIDTYPE(obj, widtype);
5770 Widget_Data *wd = elm_widget_data_get(obj);
5772 if (h_bounce) *h_bounce = wd->h_bounce;
5773 if (v_bounce) *v_bounce = wd->v_bounce;
5777 elm_genlist_homogeneous_set(Evas_Object *obj,
5778 Eina_Bool homogeneous)
5780 ELM_CHECK_WIDTYPE(obj, widtype);
5781 Widget_Data *wd = elm_widget_data_get(obj);
5783 wd->homogeneous = !!homogeneous;
5787 elm_genlist_homogeneous_get(const Evas_Object *obj)
5789 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5790 Widget_Data *wd = elm_widget_data_get(obj);
5791 if (!wd) return EINA_FALSE;
5792 return wd->homogeneous;
5796 elm_genlist_block_count_set(Evas_Object *obj,
5799 ELM_CHECK_WIDTYPE(obj, widtype);
5800 Widget_Data *wd = elm_widget_data_get(obj);
5802 wd->max_items_per_block = count;
5803 wd->item_cache_max = wd->max_items_per_block * 2;
5804 _item_cache_clean(wd);
5808 elm_genlist_block_count_get(const Evas_Object *obj)
5810 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5811 Widget_Data *wd = elm_widget_data_get(obj);
5813 return wd->max_items_per_block;
5817 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5820 ELM_CHECK_WIDTYPE(obj, widtype);
5821 Widget_Data *wd = elm_widget_data_get(obj);
5823 wd->longpress_timeout = timeout;
5827 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5829 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5830 Widget_Data *wd = elm_widget_data_get(obj);
5832 return wd->longpress_timeout;
5836 elm_genlist_scroller_policy_set(Evas_Object *obj,
5837 Elm_Scroller_Policy policy_h,
5838 Elm_Scroller_Policy policy_v)
5840 ELM_CHECK_WIDTYPE(obj, widtype);
5841 Widget_Data *wd = elm_widget_data_get(obj);
5842 if ((!wd) || (!wd->scr)) return;
5843 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5844 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5846 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5850 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5851 Elm_Scroller_Policy *policy_h,
5852 Elm_Scroller_Policy *policy_v)
5854 ELM_CHECK_WIDTYPE(obj, widtype);
5855 Widget_Data *wd = elm_widget_data_get(obj);
5856 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5857 if ((!wd) || (!wd->scr)) return;
5858 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5859 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5860 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5864 elm_genlist_realized_items_update(Evas_Object *obj)
5866 ELM_CHECK_WIDTYPE(obj, widtype);
5868 Eina_List *list, *l;
5869 Elm_Object_Item *it;
5871 list = elm_genlist_realized_items_get(obj);
5872 EINA_LIST_FOREACH(list, l, it)
5873 elm_genlist_item_update(it);
5877 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5878 const char *decorate_it_type,
5879 Eina_Bool decorate_it_set)
5881 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5882 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5884 Widget_Data *wd = _it->wd;
5886 Elm_Object_Item *it2;
5889 if (!decorate_it_type) return;
5890 if ((_it->generation < _it->wd->generation) ||
5891 elm_widget_item_disabled_get(_it)) return;
5892 if (wd->decorate_all_mode) return;
5894 if ((wd->mode_item == _it) &&
5895 (!strcmp(decorate_it_type, wd->decorate_it_type)) &&
5898 if (!_it->itc->decorate_item_style) return;
5899 _it->decorate_it_set = decorate_it_set;
5903 EINA_LIST_FOREACH(wd->selected, l, it2)
5904 if (((Elm_Gen_Item *)it2)->realized)
5905 elm_genlist_item_selected_set(it2, EINA_FALSE);
5909 it2 = elm_genlist_selected_item_get(wd->obj);
5910 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5911 elm_genlist_item_selected_set(it2, EINA_FALSE);
5914 if (((wd->decorate_it_type) && (strcmp(decorate_it_type, wd->decorate_it_type))) ||
5915 (decorate_it_set) || ((_it == wd->mode_item) && (!decorate_it_set)))
5916 _decorate_item_unset(wd);
5918 eina_stringshare_replace(&wd->decorate_it_type, decorate_it_type);
5919 if (decorate_it_set) _decorate_item_set(_it);
5923 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5925 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5926 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5927 return _it->wd->decorate_it_type;
5930 EAPI const Elm_Object_Item *
5931 elm_genlist_decorated_item_get(const Evas_Object *obj)
5933 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5934 Widget_Data *wd = elm_widget_data_get(obj);
5935 if (!wd) return NULL;
5936 return (Elm_Object_Item *) wd->mode_item;
5940 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5942 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5943 Widget_Data *wd = elm_widget_data_get(obj);
5944 if (!wd) return EINA_FALSE;
5946 return wd->decorate_all_mode;
5950 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5952 ELM_CHECK_WIDTYPE(obj, widtype);
5953 Eina_List *list, *l;
5956 Widget_Data *wd = elm_widget_data_get(obj);
5958 decorated = !!decorated;
5959 if (wd->decorate_all_mode == decorated) return;
5960 wd->decorate_all_mode = decorated;
5962 list = elm_genlist_realized_items_get(obj);
5963 if (!wd->decorate_all_mode)
5965 EINA_LIST_FOREACH(list, l, it)
5967 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5968 _decorate_all_item_unrealize(it);
5970 _item_cache_zero(wd);
5974 EINA_LIST_FOREACH(list, l, it)
5976 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5978 if (it->itc->decorate_all_item_style)
5979 _decorate_all_item_realize(it, EINA_TRUE);
5983 if (wd->calc_job) ecore_job_del(wd->calc_job);
5984 wd->calc_job = ecore_job_add(_calc_job, wd);
5988 elm_genlist_reorder_mode_set(Evas_Object *obj,
5989 Eina_Bool reorder_mode)
5991 ELM_CHECK_WIDTYPE(obj, widtype);
5992 Widget_Data *wd = elm_widget_data_get(obj);
5994 wd->reorder_mode = !!reorder_mode;
5998 elm_genlist_reorder_mode_get(const Evas_Object *obj)
6000 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6001 Widget_Data *wd = elm_widget_data_get(obj);
6002 if (!wd) return EINA_FALSE;
6003 return wd->reorder_mode;
6006 EAPI Elm_Genlist_Item_Type
6007 elm_genlist_item_type_get(const Elm_Object_Item *it)
6009 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
6010 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6011 return _it->item->type;
6014 EAPI Elm_Genlist_Item_Class *
6015 elm_genlist_item_class_new(void)
6017 Elm_Genlist_Item_Class *itc;
6019 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
6022 itc->version = CLASS_ALLOCATED;
6024 itc->delete_me = EINA_FALSE;
6030 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
6032 if (itc && (itc->version == CLASS_ALLOCATED))
6034 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
6035 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6045 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6047 if (itc && (itc->version == CLASS_ALLOCATED))
6050 if (itc->refcount == 0) itc->refcount--;
6055 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6057 if (itc && (itc->version == CLASS_ALLOCATED))
6059 if (itc->refcount > 0) itc->refcount--;
6060 if (itc->delete_me && (!itc->refcount))
6061 elm_genlist_item_class_free(itc);
6065 void _flip_job(void *data)
6067 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
6068 _item_unhighlight(it);
6070 _elm_genlist_item_unrealize(it, EINA_FALSE);
6071 it->flipped = EINA_TRUE;
6072 it->item->nocache = EINA_TRUE;
6073 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6074 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
6078 elm_genlist_item_flip_set(Elm_Object_Item *it,
6081 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6082 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6085 if (_it->flipped == flip) return;
6089 ecore_job_add(_flip_job, _it);
6093 _it->flipped = flip;
6094 _item_cache_zero(_it->wd);
6095 elm_genlist_item_update(it);
6096 _it->item->nocache = EINA_FALSE;
6101 elm_genlist_item_flip_get(const Elm_Object_Item *it)
6103 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6104 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6105 return _it->flipped;
6109 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
6111 ELM_CHECK_WIDTYPE(obj, widtype);
6112 Widget_Data *wd = elm_widget_data_get(obj);
6114 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6116 if (wd->select_mode != mode)
6117 wd->select_mode = mode;
6120 EAPI Elm_Object_Select_Mode
6121 elm_genlist_select_mode_get(const Evas_Object *obj)
6123 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
6124 Widget_Data *wd = elm_widget_data_get(obj);
6125 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
6126 return wd->select_mode;
6130 elm_genlist_highlight_mode_set(Evas_Object *obj,
6131 Eina_Bool highlight)
6133 ELM_CHECK_WIDTYPE(obj, widtype);
6134 Widget_Data *wd = elm_widget_data_get(obj);
6136 wd->highlight = !!highlight;
6140 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6142 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6143 Widget_Data *wd = elm_widget_data_get(obj);
6144 if (!wd) return EINA_FALSE;
6145 return wd->highlight;
6149 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
6150 Elm_Object_Select_Mode mode)
6152 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6153 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6155 if (_it->generation < _it->wd->generation) return;
6156 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6158 if (_it->select_mode != mode)
6159 _it->select_mode = mode;
6161 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6163 _it->item->mincalcd = EINA_FALSE;
6164 _it->item->updateme = EINA_TRUE;
6165 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
6166 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
6167 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
6171 EAPI Elm_Object_Select_Mode
6172 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
6174 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
6175 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6176 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
6177 return _it->select_mode;
6180 /* for gengrid as of now */
6182 _elm_genlist_page_relative_set(Evas_Object *obj,
6186 Evas_Coord pagesize_h;
6187 Evas_Coord pagesize_v;
6189 ELM_CHECK_WIDTYPE(obj, widtype);
6190 Widget_Data *wd = elm_widget_data_get(obj);
6193 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
6194 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
6198 /* for gengrid as of now */
6200 _elm_genlist_page_relative_get(const Evas_Object *obj,
6204 ELM_CHECK_WIDTYPE(obj, widtype);
6205 Widget_Data *wd = elm_widget_data_get(obj);
6208 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
6211 /* for gengrid as of now */
6213 _elm_genlist_page_size_set(Evas_Object *obj,
6214 Evas_Coord h_pagesize,
6215 Evas_Coord v_pagesize)
6220 ELM_CHECK_WIDTYPE(obj, widtype);
6221 Widget_Data *wd = elm_widget_data_get(obj);
6223 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
6224 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
6228 /* for gengrid as of now */
6230 _elm_genlist_current_page_get(const Evas_Object *obj,
6234 ELM_CHECK_WIDTYPE(obj, widtype);
6235 Widget_Data *wd = elm_widget_data_get(obj);
6237 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
6240 /* for gengrid as of now */
6242 _elm_genlist_last_page_get(const Evas_Object *obj,
6246 ELM_CHECK_WIDTYPE(obj, widtype);
6247 Widget_Data *wd = elm_widget_data_get(obj);
6249 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
6252 /* for gengrid as of now */
6254 _elm_genlist_page_show(const Evas_Object *obj,
6258 ELM_CHECK_WIDTYPE(obj, widtype);
6259 Widget_Data *wd = elm_widget_data_get(obj);
6261 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
6264 /* for gengrid as of now */
6266 _elm_genlist_page_bring_in(const Evas_Object *obj,
6270 ELM_CHECK_WIDTYPE(obj, widtype);
6271 Widget_Data *wd = elm_widget_data_get(obj);
6273 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
6277 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
6280 Evas_Object *content;
6282 if (!it->realized) return;
6283 if (it->wd->reorder_it == it) return;
6284 if (it->defer_unrealize && !it->item->updateme) return;
6286 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
6288 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
6291 ecore_timer_del(it->long_timer);
6292 it->long_timer = NULL;
6295 elm_widget_stringlist_free(it->texts);
6297 elm_widget_stringlist_free(it->contents);
6298 it->contents = NULL;
6299 elm_widget_stringlist_free(it->states);
6301 EINA_LIST_FREE(it->content_objs, content)
6302 evas_object_del(content);
6304 it->unrealize_cb(it);
6306 it->realized = EINA_FALSE;
6307 it->want_unrealize = EINA_FALSE;
6308 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
6309 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
6313 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
6315 elm_widget_item_pre_notify_del(it);
6316 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
6318 if ((it->relcount > 0) || (it->walking > 0)) return;
6320 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6322 if (it->itc->func.del)
6323 it->itc->func.del((void *)it->base.data, WIDGET(it));
6327 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
6329 _elm_genlist_item_del_notserious(it);
6330 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6331 if (it->tooltip.del_cb)
6332 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6333 it->wd->walking -= it->walking;
6336 ecore_timer_del(it->long_timer);
6337 it->long_timer = NULL;
6340 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
6344 eina_inlist_sorted_state_free(it->wd->state);
6345 it->wd->state = NULL;
6347 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6348 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
6352 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
6353 it->wd->last_selected_item = NULL;
6354 it->wd->item_count--;
6358 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
6360 ELM_CHECK_WIDTYPE(obj, widtype);
6361 Widget_Data *wd = elm_widget_data_get(obj);
6363 wd->tree_effect_enabled = !!enabled;
6367 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
6369 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6370 Widget_Data *wd = elm_widget_data_get(obj);
6371 if (!wd) return EINA_FALSE;
6372 return wd->tree_effect_enabled;
6376 _create_tray_alpha_bg(const Evas_Object *obj)
6378 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6379 Widget_Data *wd = elm_widget_data_get(obj);
6380 if (!wd) return NULL;
6382 Evas_Object *bg = NULL;
6383 Evas_Coord ox, oy, ow, oh;
6385 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6386 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6387 evas_object_color_set(bg,0,0,0,0);
6388 evas_object_resize(bg , ow, oh);
6389 evas_object_move(bg , ox, oy);
6394 _item_contract_emit(Elm_Gen_Item *it)
6399 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6400 it->item->tree_effect_finished = EINA_FALSE;
6402 EINA_LIST_FOREACH(it->item->items, l, it2)
6403 if (it2) _item_contract_emit(it2);
6407 _item_tree_effect_before(Elm_Gen_Item *it)
6412 EINA_LIST_FOREACH(it->item->items, l, it2)
6414 if (it2->parent && (it == it2->parent))
6417 it2->item->tree_effect_hideme = EINA_TRUE;
6418 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6419 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6420 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6421 _item_contract_emit(it2);
6424 return ECORE_CALLBACK_CANCEL;
6428 _item_tree_effect(Widget_Data *wd, int y)
6430 Elm_Gen_Item *it = NULL, *expanded_next_it;
6432 expanded_next_it = wd->expanded_next_item;
6434 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6436 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6439 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6440 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6441 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6443 if (!it->item->tree_effect_finished)
6445 edje_object_signal_emit(VIEW(it), "flip_item", "");
6446 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6447 it->item->tree_effect_finished = EINA_TRUE;
6450 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6453 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6455 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6458 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6459 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6461 if (!it->item->tree_effect_finished)
6463 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6464 it->item->tree_effect_finished = EINA_TRUE;
6469 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6475 _item_tree_effect_finish(Widget_Data *wd)
6477 Elm_Gen_Item *it = NULL;
6480 if (wd->tree_effect_animator)
6482 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6483 _item_subitems_clear(wd->expanded_item);
6484 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6486 it->item->tree_effect_finished = EINA_TRUE;
6487 it->item->old_scrl_y = it->item->scrl_y;
6488 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6489 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6492 _item_auto_scroll(wd);
6493 evas_object_lower(wd->alpha_bg);
6494 evas_object_hide(wd->alpha_bg);
6495 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6496 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6498 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6499 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6500 evas_object_smart_changed(wd->pan_smart);
6502 wd->tree_effect_animator = NULL;
6506 _tree_effect_animator_cb(void *data)
6508 Widget_Data *wd = data;
6509 if (!wd) return ECORE_CALLBACK_CANCEL;
6510 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6511 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6513 double effect_duration = 0.3, t;
6514 int y = 0, dy = 0, dh = 0;
6515 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6518 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6519 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6520 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6521 if (t > effect_duration) end = EINA_TRUE;
6523 // Below while statement is needed, when the genlist is resized.
6524 it2 = wd->expanded_item;
6527 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6528 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6529 cvx, cvy, cvw, cvh));
6530 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6533 if (wd->expanded_next_item)
6535 expanded_next_it = wd->expanded_next_item;
6538 EINA_LIST_FOREACH(wd->move_items, l, it)
6540 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6542 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6543 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6544 expanded_next_it->item->scrl_y = cvy + cvh;
6546 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6547 cvy + cvh : expanded_next_it->item->scrl_y) -
6548 expanded_next_it->item->old_scrl_y;
6550 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6552 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6553 expanded_next_it->item->old_scrl_y = cvy + cvh;
6555 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6557 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6559 expanded_next_it->item->old_scrl_y = cvy + cvh;
6563 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6564 expanded_next_it->item->old_scrl_y;
6568 if (t <= effect_duration)
6570 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6580 _item_realize(it, in, 0);
6584 if (it != expanded_next_it)
6586 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6590 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6591 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6594 _item_tree_effect(wd, y);
6598 int expanded_item_num = 0;
6601 if (wd->expanded_item)
6602 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6607 expanded_item_num++;
6608 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6614 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6615 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6617 if (!it->item->tree_effect_finished)
6619 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6621 edje_object_signal_emit(VIEW(it), "flip_item", "");
6622 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6623 it->item->tree_effect_finished = EINA_TRUE;
6627 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6633 _item_tree_effect_finish(wd);
6634 return ECORE_CALLBACK_CANCEL;
6636 return ECORE_CALLBACK_RENEW;