3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.h"
9 // internally allocated
10 #define CLASS_ALLOCATED 0x3a70f11f
12 #define MAX_ITEMS_PER_BLOCK 32
13 #define REORDER_EFFECT_TIME 0.5
15 #define ELM_GEN_SETUP(wd) \
16 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
17 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
18 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
32 ERR("Genlist_Item_Class(itc) is NULL"); \
35 if ((itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) && \
36 (itc->version != CLASS_ALLOCATED)) \
38 ERR("Genlist_Item_Class version mismatched! current = (%d), required = (%d) or (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION, CLASS_ALLOCATED); \
44 typedef struct _Item_Block Item_Block;
45 typedef struct _Item_Cache Item_Cache;
47 struct Elm_Gen_Item_Type
52 Evas_Coord w, h, minw, minh;
53 Elm_Gen_Item *group_item;
54 Elm_Genlist_Item_Type type;
55 Eina_List *mode_texts, *mode_contents, *mode_states, *mode_content_objs;
56 Eina_List *edit_texts, *edit_contents, *edit_states, *edit_content_objs;
57 Ecore_Timer *swipe_timer;
58 Evas_Coord scrl_x, scrl_y, old_scrl_y;
61 Evas_Object *mode_view;
67 Eina_Bool want_realize : 1;
68 Eina_Bool expanded : 1;
69 Eina_Bool mincalcd : 1;
72 Eina_Bool updateme : 1;
73 Eina_Bool nocache : 1; /* do not use cache for this item */
74 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
75 Eina_Bool stacking_even : 1;
76 Eina_Bool nostacking : 1;
77 Eina_Bool move_effect_enabled : 1;
78 Eina_Bool decorate_mode_item_realized : 1;
79 Eina_Bool tree_effect_finished : 1; /* tree effect */
80 Eina_Bool tree_effect_hideme : 1; /* item hide for tree effect */
91 Evas_Coord x, y, w, h, minw, minh;
93 int item_position_stamp;
95 Eina_Bool position_update : 1;
96 Eina_Bool want_unrealize : 1;
97 Eina_Bool realized : 1;
98 Eina_Bool changed : 1;
99 Eina_Bool updateme : 1;
100 Eina_Bool changeme : 1;
101 Eina_Bool showme : 1;
102 Eina_Bool must_recalc : 1;
109 Evas_Object *base_view, *spacer;
111 const char *item_style; // it->itc->item_style
112 Eina_Bool tree : 1; // it->group
114 Eina_Bool selected : 1; // it->selected
115 Eina_Bool disabled : 1; // it->disabled
116 Eina_Bool expanded : 1; // it->item->expanded
119 static const char *widtype = NULL;
120 static void _item_cache_zero(Widget_Data *wd);
121 static void _del_hook(Evas_Object *obj);
122 static void _mirrored_set(Evas_Object *obj,
124 static void _theme_hook(Evas_Object *obj);
125 static void _show_region_hook(void *data,
127 static void _sizing_eval(Evas_Object *obj);
128 static void _item_realize(Elm_Gen_Item *it,
131 static void _item_unrealize_cb(Elm_Gen_Item *it);
132 static void _item_block_unrealize(Item_Block *itb);
133 static void _calc_job(void *data);
134 static void _on_focus_hook(void *data,
136 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
137 static void _changed_job(void *data);
138 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
139 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
140 static Eina_Bool _item_single_select_up(Widget_Data *wd);
141 static Eina_Bool _item_single_select_down(Widget_Data *wd);
142 static Eina_Bool _event_hook(Evas_Object *obj,
144 Evas_Callback_Type type,
146 static void _signal_emit_hook(Evas_Object *obj,
147 const char *emission,
149 static Eina_Bool _deselect_all_items(Widget_Data *wd);
150 static void _pan_calculate(Evas_Object *obj);
151 static void _pan_max_get(Evas_Object *obj,
154 static void _item_position(Elm_Gen_Item *it,
158 static void _mode_item_realize(Elm_Gen_Item *it);
159 static void _mode_item_unrealize(Elm_Gen_Item *it);
160 static void _item_mode_set(Elm_Gen_Item *it);
161 static void _item_mode_unset(Widget_Data *wd);
162 static void _decorate_mode_item_position(Elm_Gen_Item *it, int itx, int ity);
163 static void _decorate_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
164 static void _decorate_mode_item_unrealize(Elm_Gen_Item *it);
167 static void _group_items_recalc(void *data);
169 static void _item_move_after(Elm_Gen_Item *it,
170 Elm_Gen_Item *after);
171 static void _item_move_before(Elm_Gen_Item *it,
172 Elm_Gen_Item *before);
173 static void _item_auto_scroll(Widget_Data *wd);
174 static void _elm_genlist_clear(Evas_Object *obj,
176 static void _pan_child_size_get(Evas_Object *obj,
179 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
180 static void _item_contract_emit(Elm_Gen_Item *it);
181 static int _item_tree_effect_before(Elm_Gen_Item *it);
182 static void _item_tree_effect(Widget_Data *wd, int y);
183 static void _item_tree_effect_finish(Widget_Data *wd);
184 static Eina_Bool _tree_effect_animator_cb(void *data);
186 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
188 static const char SIG_ACTIVATED[] = "activated";
189 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
190 static const char SIG_SELECTED[] = "selected";
191 static const char SIG_UNSELECTED[] = "unselected";
192 static const char SIG_EXPANDED[] = "expanded";
193 static const char SIG_CONTRACTED[] = "contracted";
194 static const char SIG_EXPAND_REQUEST[] = "expand,request";
195 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
196 static const char SIG_REALIZED[] = "realized";
197 static const char SIG_UNREALIZED[] = "unrealized";
198 static const char SIG_DRAG_START_UP[] = "drag,start,up";
199 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
200 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
201 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
202 static const char SIG_DRAG_STOP[] = "drag,stop";
203 static const char SIG_DRAG[] = "drag";
204 static const char SIG_LONGPRESSED[] = "longpressed";
205 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
206 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
207 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
208 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
209 static const char SIG_EDGE_TOP[] = "edge,top";
210 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
211 static const char SIG_EDGE_LEFT[] = "edge,left";
212 static const char SIG_EDGE_RIGHT[] = "edge,right";
213 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
214 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
215 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
216 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
217 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
218 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
219 static const char SIG_SWIPE[] = "swipe";
220 static const char SIG_MOVED[] = "moved";
221 static const char SIG_MOVED_AFTER[] = "moved,after";
222 static const char SIG_MOVED_BEFORE[] = "moved,before";
223 static const char SIG_INDEX_UPDATE[] = "index,update";
224 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
226 static const Evas_Smart_Cb_Description _signals[] = {
227 {SIG_CLICKED_DOUBLE, ""},
230 {SIG_UNSELECTED, ""},
232 {SIG_CONTRACTED, ""},
233 {SIG_EXPAND_REQUEST, ""},
234 {SIG_CONTRACT_REQUEST, ""},
236 {SIG_UNREALIZED, ""},
237 {SIG_DRAG_START_UP, ""},
238 {SIG_DRAG_START_DOWN, ""},
239 {SIG_DRAG_START_LEFT, ""},
240 {SIG_DRAG_START_RIGHT, ""},
243 {SIG_LONGPRESSED, ""},
244 {SIG_SCROLL_ANIM_START, ""},
245 {SIG_SCROLL_ANIM_STOP, ""},
246 {SIG_SCROLL_DRAG_START, ""},
247 {SIG_SCROLL_DRAG_STOP, ""},
249 {SIG_EDGE_BOTTOM, ""},
251 {SIG_EDGE_RIGHT, ""},
252 {SIG_MULTI_SWIPE_LEFT, ""},
253 {SIG_MULTI_SWIPE_RIGHT, ""},
254 {SIG_MULTI_SWIPE_UP, ""},
255 {SIG_MULTI_SWIPE_DOWN, ""},
256 {SIG_MULTI_PINCH_OUT, ""},
257 {SIG_MULTI_PINCH_IN, ""},
260 {SIG_MOVED_AFTER, ""},
261 {SIG_MOVED_BEFORE, ""},
262 {SIG_TREE_EFFECT_FINISHED, ""},
267 #undef ELM_CHECK_WIDTYPE
268 #define ELM_CHECK_WIDTYPE(obj, widtype) \
269 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
270 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
271 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
272 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
273 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
275 static const char *_gengrid = NULL;
276 static const char *_genlist = NULL;
278 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
280 elm_genlist_type_check(const Evas_Object *obj,
283 const char *provided, *expected = "(unknown)";
284 static int abort_on_warn = -1;
285 provided = elm_widget_type_get(obj);
286 if (!_genlist) _genlist = eina_stringshare_add("genlist");
287 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
288 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
290 if ((!provided) || (!provided[0]))
292 provided = evas_object_type_get(obj);
293 if ((!provided) || (!provided[0]))
294 provided = "(unknown)";
296 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
297 if (abort_on_warn == -1)
299 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
300 else abort_on_warn = 0;
302 if (abort_on_warn == 1) abort();
307 _event_hook(Evas_Object *obj,
308 Evas_Object *src __UNUSED__,
309 Evas_Callback_Type type,
312 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
313 Evas_Event_Key_Down *ev = event_info;
314 Widget_Data *wd = elm_widget_data_get(obj);
315 Evas_Coord pan_max_x = 0, pan_max_y = 0;
316 if (!wd) return EINA_FALSE;
317 if (!wd->items) return EINA_FALSE;
318 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
319 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
321 Elm_Object_Item *it = NULL;
324 Evas_Coord step_x = 0;
325 Evas_Coord step_y = 0;
328 Evas_Coord page_x = 0;
329 Evas_Coord page_y = 0;
331 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
332 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
333 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
334 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
336 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
340 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
344 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
346 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
347 (_item_multi_select_up(wd)))
348 || (_item_single_select_up(wd)))
350 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
356 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
358 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
359 (_item_multi_select_down(wd)))
360 || (_item_single_select_down(wd)))
362 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
368 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
370 it = elm_genlist_first_item_get(obj);
371 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
372 elm_genlist_item_selected_set(it, EINA_TRUE);
373 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
376 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
378 it = elm_genlist_last_item_get(obj);
379 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
380 elm_genlist_item_selected_set(it, EINA_TRUE);
381 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
384 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
387 y -= -(page_y * v_h) / 100;
391 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
394 y += -(page_y * v_h) / 100;
398 else if (!strcmp(ev->keyname, "Escape"))
400 if (!_deselect_all_items(wd)) return EINA_FALSE;
401 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
404 else if (((!strcmp(ev->keyname, "Return")) ||
405 (!strcmp(ev->keyname, "KP_Enter")) ||
406 (!strcmp(ev->keyname, "space")))
407 && (!wd->multi) && (wd->selected))
409 it = elm_genlist_selected_item_get(obj);
410 elm_genlist_item_expanded_set(it,
411 !elm_genlist_item_expanded_get(it));
412 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
414 else return EINA_FALSE;
416 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
417 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
419 if (x > pan_max_x) x = pan_max_x;
421 if (y > pan_max_y) y = pan_max_y;
422 elm_smart_scroller_child_pos_set(wd->scr, x, y);
427 _deselect_all_items(Widget_Data *wd)
429 if (!wd->selected) return EINA_FALSE;
431 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
437 _item_multi_select_up(Widget_Data *wd)
439 if (!wd->selected) return EINA_FALSE;
440 if (!wd->multi) return EINA_FALSE;
442 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
443 if (!prev) return EINA_TRUE;
445 if (elm_genlist_item_selected_get(prev))
447 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
448 wd->last_selected_item = prev;
449 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
453 elm_genlist_item_selected_set(prev, EINA_TRUE);
454 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
460 _item_multi_select_down(Widget_Data *wd)
462 if (!wd->selected) return EINA_FALSE;
463 if (!wd->multi) return EINA_FALSE;
465 Elm_Object_Item *next;
466 next = elm_genlist_item_next_get(wd->last_selected_item);
467 if (!next) return EINA_TRUE;
469 if (elm_genlist_item_selected_get(next))
471 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
472 wd->last_selected_item = next;
473 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
477 elm_genlist_item_selected_set(next, EINA_TRUE);
478 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
484 _item_single_select_up(Widget_Data *wd)
489 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
490 while ((prev) && (prev->generation < wd->generation))
491 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
493 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
495 if (!prev) return EINA_FALSE;
497 _deselect_all_items(wd);
499 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
500 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
505 _item_single_select_down(Widget_Data *wd)
510 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
511 while ((next) && (next->generation < wd->generation))
512 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
514 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
516 if (!next) return EINA_FALSE;
518 _deselect_all_items(wd);
520 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
521 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
526 _on_focus_hook(void *data __UNUSED__,
529 Widget_Data *wd = elm_widget_data_get(obj);
531 if (elm_widget_focus_get(obj))
533 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
534 evas_object_focus_set(wd->obj, EINA_TRUE);
535 if ((wd->items) && (wd->selected) && (!wd->last_selected_item))
536 wd->last_selected_item = eina_list_data_get(wd->selected);
540 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
541 evas_object_focus_set(wd->obj, EINA_FALSE);
546 _del_hook(Evas_Object *obj)
548 Widget_Data *wd = elm_widget_data_get(obj);
550 _item_cache_zero(wd);
551 if (wd->calc_job) ecore_job_del(wd->calc_job);
552 if (wd->update_job) ecore_job_del(wd->update_job);
553 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
554 if (wd->changed_job) ecore_job_del(wd->changed_job);
555 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
556 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
557 if (wd->decorate_type) eina_stringshare_del(wd->decorate_type);
558 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
563 _del_pre_hook(Evas_Object *obj)
565 Widget_Data *wd = elm_widget_data_get(obj);
567 if (wd->decorate_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
568 elm_genlist_clear(obj);
569 evas_object_del(wd->pan_smart);
570 wd->pan_smart = NULL;
574 _mirrored_set(Evas_Object *obj,
577 Widget_Data *wd = elm_widget_data_get(obj);
579 _item_cache_zero(wd);
580 elm_smart_scroller_mirrored_set(wd->scr, rtl);
584 _theme_hook(Evas_Object *obj)
586 Widget_Data *wd = elm_widget_data_get(obj);
589 evas_event_freeze(evas_object_evas_get(wd->obj));
590 _item_cache_zero(wd);
591 _elm_widget_mirrored_reload(obj);
592 _mirrored_set(obj, elm_widget_mirrored_get(obj));
593 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
594 elm_widget_style_get(obj));
595 //edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
596 wd->item_width = wd->item_height = 0;
597 wd->group_item_width = wd->group_item_height = 0;
598 wd->minw = wd->minh = wd->realminw = 0;
599 EINA_INLIST_FOREACH(wd->blocks, itb)
604 if (itb->realized) _item_block_unrealize(itb);
605 EINA_LIST_FOREACH(itb->items, l, it)
606 it->item->mincalcd = EINA_FALSE;
608 itb->changed = EINA_TRUE;
610 if (wd->calc_job) ecore_job_del(wd->calc_job);
611 wd->calc_job = ecore_job_add(_calc_job, wd);
613 evas_event_thaw(evas_object_evas_get(wd->obj));
614 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
618 _show_region_hook(void *data,
621 Widget_Data *wd = elm_widget_data_get(data);
622 Evas_Coord x, y, w, h;
624 elm_widget_show_region_get(obj, &x, &y, &w, &h);
625 //x & y are screen coordinates, Add with pan coordinates
628 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
632 _translate_hook(Evas_Object *obj)
634 evas_object_smart_callback_call(obj, "language,changed", NULL);
638 _sizing_eval(Evas_Object *obj)
640 Widget_Data *wd = elm_widget_data_get(obj);
641 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
642 Evas_Coord vmw = 0, vmh = 0;
645 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
646 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
648 edje_object_size_min_calc
649 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
651 if (wd->mode == ELM_LIST_COMPRESS)
655 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
656 if ((vw != 0) && (vw != wd->prev_viewport_w))
660 wd->prev_viewport_w = vw;
661 EINA_INLIST_FOREACH(wd->blocks, itb)
663 itb->must_recalc = EINA_TRUE;
665 if (wd->calc_job) ecore_job_del(wd->calc_job);
666 wd->calc_job = ecore_job_add(_calc_job, wd);
668 edje_object_size_min_calc
669 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
673 else if (wd->mode == ELM_LIST_LIMIT)
684 evas_object_size_hint_min_set(obj, minw, minh);
685 evas_object_size_hint_max_set(obj, maxw, maxh);
689 _signal_emit_hook(Evas_Object *obj,
690 const char *emission,
693 Widget_Data *wd = elm_widget_data_get(obj);
694 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
699 _item_highlight(Elm_Gen_Item *it)
701 const char *selectraise;
702 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
703 (!it->wd->highlight) ||
704 (it->generation < it->wd->generation) ||
705 (it->highlighted) || elm_widget_item_disabled_get(it) ||
706 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->mode_view) ||
707 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
709 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
710 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,selected", "elm");
711 selectraise = edje_object_data_get(VIEW(it), "selectraise");
712 if ((selectraise) && (!strcmp(selectraise, "on")))
714 if (it->edit_obj) evas_object_raise(it->edit_obj);
715 else evas_object_raise(VIEW(it));
718 if ((it->item->group_item) && (it->item->group_item->realized))
719 evas_object_raise(it->item->VIEW(group_item));
722 it->highlighted = EINA_TRUE;
726 _item_unhighlight(Elm_Gen_Item *it)
728 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
729 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
730 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,unselected", "elm");
731 if (!it->item->nostacking)
733 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
735 if (it->edit_obj) evas_object_lower(it->edit_obj);
736 else evas_object_lower(VIEW(it));
740 if (it->edit_obj) evas_object_raise(it->edit_obj);
741 else evas_object_raise(VIEW(it));
744 it->highlighted = EINA_FALSE;
748 _item_block_position_update(Eina_Inlist *list, int idx)
752 EINA_INLIST_FOREACH(list, tmp)
754 tmp->position = idx++;
755 tmp->position_update = EINA_TRUE;
760 _item_position_update(Eina_List *list, int idx)
765 EINA_LIST_FOREACH(list, l, it)
767 it->position = idx++;
768 it->position_update = EINA_TRUE;
773 _item_block_del(Elm_Gen_Item *it)
776 Item_Block *itb = it->item->block;
777 Eina_Bool block_changed;
779 itb->items = eina_list_remove(itb->items, it);
781 itb->changed = EINA_TRUE;
782 if (!it->wd->reorder_deleted)
784 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
785 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
789 il = EINA_INLIST_GET(itb);
790 Item_Block *itbn = (Item_Block *)(il->next);
792 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
795 _item_block_position_update(il->next, itb->position);
796 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
799 if (itbn) itbn->changed = EINA_TRUE;
803 if (itb->count < itb->wd->max_items_per_block/2)
805 il = EINA_INLIST_GET(itb);
806 Item_Block *itbp = (Item_Block *)(il->prev);
807 Item_Block *itbn = (Item_Block *)(il->next);
808 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
812 EINA_LIST_FREE(itb->items, it2)
814 it2->item->block = itbp;
815 itbp->items = eina_list_append(itbp->items, it2);
817 itbp->changed = EINA_TRUE;
819 _item_block_position_update(EINA_INLIST_GET(itb)->next,
821 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
822 EINA_INLIST_GET(itb));
824 block_changed = EINA_TRUE;
826 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
830 Eina_List *last = eina_list_last(itb->items);
831 Elm_Gen_Item *it2 = last->data;
833 it2->item->block = itbn;
834 itb->items = eina_list_remove_list(itb->items, last);
835 itbn->items = eina_list_prepend(itbn->items, it2);
837 itbn->changed = EINA_TRUE;
839 _item_block_position_update(EINA_INLIST_GET(itb)->next,
842 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
844 block_changed = EINA_TRUE;
850 it->wd->pan_changed = EINA_TRUE;
851 evas_object_smart_changed(it->wd->pan_smart);
852 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
853 it->wd->calc_job = NULL;
858 _item_subitems_clear(Elm_Gen_Item *it)
860 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
861 Eina_List *tl = NULL, *l;
862 Elm_Object_Item *it2;
864 EINA_LIST_FOREACH(it->item->items, l, it2)
865 tl = eina_list_append(tl, it2);
866 EINA_LIST_FREE(tl, it2)
867 elm_object_item_del(it2);
871 _item_del(Elm_Gen_Item *it)
873 Evas_Object *obj = WIDGET(it);
875 evas_event_freeze(evas_object_evas_get(obj));
876 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
877 if (it->wd->show_item == it) it->wd->show_item = NULL;
878 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
879 if (it->item->decorate_mode_item_realized) _decorate_mode_item_unrealize(it);
880 if (it->item->block) _item_block_del(it);
881 if (it->item->queued)
882 it->wd->queue = eina_list_remove(it->wd->queue, it);
883 if (it->wd->anchor_item == it)
885 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
886 if (!it->wd->anchor_item)
887 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
889 if (it->wd->expanded_item == it) it->wd->expanded_item = NULL;
891 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
892 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
893 _elm_genlist_item_del_serious(it);
894 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
895 evas_event_thaw(evas_object_evas_get(obj));
896 evas_event_thaw_eval(evas_object_evas_get(obj));
900 _clear_cb(Widget_Data *wd)
902 wd->anchor_item = NULL;
905 Item_Block *itb = (Item_Block *)(wd->blocks);
907 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
908 if (itb->items) eina_list_free(itb->items);
911 if (wd->queue_idle_enterer)
913 ecore_idle_enterer_del(wd->queue_idle_enterer);
914 wd->queue_idle_enterer = NULL;
916 if (wd->must_recalc_idler)
918 ecore_idler_del(wd->must_recalc_idler);
919 wd->must_recalc_idler = NULL;
921 if (wd->queue) wd->queue = eina_list_free(wd->queue);
922 if (wd->reorder_move_animator)
924 ecore_animator_del(wd->reorder_move_animator);
925 wd->reorder_move_animator = NULL;
927 wd->show_item = NULL;
928 wd->reorder_old_pan_y = 0;
932 _item_unselect(Elm_Gen_Item *it)
934 if ((it->generation < it->wd->generation) || (!it->selected)) return;
935 it->selected = EINA_FALSE;
936 it->wd->selected = eina_list_remove(it->wd->selected, it);
937 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
941 _mouse_move(void *data,
942 Evas *evas __UNUSED__,
946 Elm_Gen_Item *it = data;
947 Evas_Event_Mouse_Move *ev = event_info;
948 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
949 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
951 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
953 if (!it->wd->on_hold)
955 it->wd->on_hold = EINA_TRUE;
956 if ((!it->wd->wasselected) && (!it->flipped))
958 _item_unhighlight(it);
963 if (it->wd->multitouched)
965 it->wd->cur_x = ev->cur.canvas.x;
966 it->wd->cur_y = ev->cur.canvas.y;
969 if ((it->dragging) && (it->down))
971 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
974 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
975 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
976 if (abs((it->wd->history[it->wd->movements].x -
977 it->wd->history[0].x)) > 40)
978 it->wd->swipe = EINA_TRUE;
984 ecore_timer_del(it->long_timer);
985 it->long_timer = NULL;
987 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
990 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
994 ecore_timer_del(it->long_timer);
995 it->long_timer = NULL;
997 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
999 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
1000 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
1002 if (!it->wd->reorder_start_y)
1003 it->wd->reorder_start_y = it->item->block->y + it->y;
1007 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
1008 y_pos = oy + oh - it->wd->reorder_it->item->h;
1013 _item_position(it, it->edit_obj, it->item->scrl_x, y_pos);
1015 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
1017 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1018 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1022 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1023 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1024 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1025 x = ev->cur.canvas.x - x;
1026 y = ev->cur.canvas.y - y;
1029 if (adx < 0) adx = -dx;
1032 if (ady < 0) ady = -dy;
1035 if ((adx > minw) || (ady > minh))
1037 it->dragging = EINA_TRUE;
1040 ecore_timer_del(it->long_timer);
1041 it->long_timer = NULL;
1043 if ((!it->wd->wasselected) && (!it->flipped))
1045 _item_unhighlight(it);
1050 if ((ady > adx) && (!it->wd->drag_started))
1051 evas_object_smart_callback_call(WIDGET(it),
1052 SIG_DRAG_START_UP, it);
1056 evas_object_smart_callback_call(WIDGET(it),
1057 SIG_DRAG_START_LEFT, it);
1059 evas_object_smart_callback_call(WIDGET(it),
1060 SIG_DRAG_START_RIGHT, it);
1065 if ((ady > adx) && (!it->wd->drag_started))
1066 evas_object_smart_callback_call(WIDGET(it),
1067 SIG_DRAG_START_DOWN, it);
1071 evas_object_smart_callback_call(WIDGET(it),
1072 SIG_DRAG_START_LEFT, it);
1074 evas_object_smart_callback_call(WIDGET(it),
1075 SIG_DRAG_START_RIGHT, it);
1082 _long_press(void *data)
1084 Elm_Gen_Item *it = data, *it_tmp;
1085 Eina_List *list, *l;
1087 it->long_timer = NULL;
1088 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1089 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1090 return ECORE_CALLBACK_CANCEL;
1091 it->wd->longpressed = EINA_TRUE;
1092 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1093 if ((it->wd->reorder_mode) && (!it->group))
1095 it->wd->reorder_it = it;
1096 it->wd->reorder_start_y = 0;
1098 evas_object_raise(it->edit_obj);
1100 evas_object_raise(VIEW(it));
1102 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1103 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1105 list = elm_genlist_realized_items_get(it->wd->obj);
1106 EINA_LIST_FOREACH(list, l, it_tmp)
1108 if (it != it_tmp) _item_unselect(it_tmp);
1110 if (it->item->items)
1112 EINA_LIST_FOREACH(it->item->items, l, it_tmp)
1114 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it_tmp))
1116 elm_genlist_item_expanded_set((Elm_Object_Item *)it_tmp,
1118 return ECORE_CALLBACK_RENEW;
1122 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1124 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1125 return ECORE_CALLBACK_RENEW;
1128 if (!it->wd->decorate_mode)
1129 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1131 return ECORE_CALLBACK_CANCEL;
1135 _swipe(Elm_Gen_Item *it)
1140 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1141 elm_widget_item_disabled_get(it)) return;
1142 it->wd->swipe = EINA_FALSE;
1143 for (i = 0; i < it->wd->movements; i++)
1145 sum += it->wd->history[i].x;
1146 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1149 sum /= it->wd->movements;
1150 if (abs(sum - it->wd->history[0].x) <= 10) return;
1151 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1155 _swipe_cancel(void *data)
1157 Elm_Gen_Item *it = data;
1159 if (!it) return ECORE_CALLBACK_CANCEL;
1160 it->wd->swipe = EINA_FALSE;
1161 it->wd->movements = 0;
1162 return ECORE_CALLBACK_RENEW;
1166 _multi_cancel(void *data)
1168 Widget_Data *wd = data;
1170 if (!wd) return ECORE_CALLBACK_CANCEL;
1171 wd->multi_timeout = EINA_TRUE;
1172 return ECORE_CALLBACK_RENEW;
1176 _multi_touch_gesture_eval(void *data)
1178 Elm_Gen_Item *it = data;
1180 it->wd->multitouched = EINA_FALSE;
1181 if (it->wd->multi_timer)
1183 ecore_timer_del(it->wd->multi_timer);
1184 it->wd->multi_timer = NULL;
1186 if (it->wd->multi_timeout)
1188 it->wd->multi_timeout = EINA_FALSE;
1192 Evas_Coord minw = 0, minh = 0;
1193 Evas_Coord off_x, off_y, off_mx, off_my;
1195 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1196 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1197 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1198 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1199 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1201 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1203 if ((off_x + off_mx) > (off_y + off_my))
1205 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1206 evas_object_smart_callback_call(WIDGET(it),
1207 SIG_MULTI_SWIPE_RIGHT, it);
1208 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1209 evas_object_smart_callback_call(WIDGET(it),
1210 SIG_MULTI_SWIPE_LEFT, it);
1211 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1212 evas_object_smart_callback_call(WIDGET(it),
1213 SIG_MULTI_PINCH_OUT, it);
1215 evas_object_smart_callback_call(WIDGET(it),
1216 SIG_MULTI_PINCH_IN, it);
1220 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1221 evas_object_smart_callback_call(WIDGET(it),
1222 SIG_MULTI_SWIPE_DOWN, it);
1223 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1224 evas_object_smart_callback_call(WIDGET(it),
1225 SIG_MULTI_SWIPE_UP, it);
1226 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1227 evas_object_smart_callback_call(WIDGET(it),
1228 SIG_MULTI_PINCH_OUT, it);
1230 evas_object_smart_callback_call(WIDGET(it),
1231 SIG_MULTI_PINCH_IN, it);
1234 it->wd->multi_timeout = EINA_FALSE;
1238 _multi_down(void *data,
1239 Evas *evas __UNUSED__,
1240 Evas_Object *obj __UNUSED__,
1243 Elm_Gen_Item *it = data;
1244 Evas_Event_Multi_Down *ev = event_info;
1246 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1247 it->wd->multi_device = ev->device;
1248 it->wd->multi_down = EINA_TRUE;
1249 it->wd->multitouched = EINA_TRUE;
1250 it->wd->prev_mx = ev->canvas.x;
1251 it->wd->prev_my = ev->canvas.y;
1252 if (!it->wd->wasselected)
1254 _item_unhighlight(it);
1257 it->wd->wasselected = EINA_FALSE;
1258 it->wd->longpressed = EINA_FALSE;
1261 ecore_timer_del(it->long_timer);
1262 it->long_timer = NULL;
1266 it->dragging = EINA_FALSE;
1267 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1269 if (it->item->swipe_timer)
1271 ecore_timer_del(it->item->swipe_timer);
1272 it->item->swipe_timer = NULL;
1274 if (it->wd->on_hold)
1276 it->wd->swipe = EINA_FALSE;
1277 it->wd->movements = 0;
1278 it->wd->on_hold = EINA_FALSE;
1283 _multi_up(void *data,
1284 Evas *evas __UNUSED__,
1285 Evas_Object *obj __UNUSED__,
1288 Elm_Gen_Item *it = data;
1289 Evas_Event_Multi_Up *ev = event_info;
1291 if (it->wd->multi_device != ev->device) return;
1292 it->wd->multi_device = 0;
1293 it->wd->multi_down = EINA_FALSE;
1294 if (it->wd->mouse_down) return;
1295 _multi_touch_gesture_eval(data);
1299 _multi_move(void *data,
1300 Evas *evas __UNUSED__,
1301 Evas_Object *obj __UNUSED__,
1304 Elm_Gen_Item *it = data;
1305 Evas_Event_Multi_Move *ev = event_info;
1307 if (it->wd->multi_device != ev->device) return;
1308 it->wd->cur_mx = ev->cur.canvas.x;
1309 it->wd->cur_my = ev->cur.canvas.y;
1313 _mouse_down(void *data,
1314 Evas *evas __UNUSED__,
1318 Elm_Gen_Item *it = data;
1319 Evas_Event_Mouse_Down *ev = event_info;
1324 if (ev->button != 1) return;
1327 EINA_LIST_FOREACH(it->content_objs, l, iobj)
1329 elm_widget_tree_unfocusable_set(iobj, EINA_FALSE);
1331 it->can_focus = EINA_TRUE;
1333 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1335 it->wd->on_hold = EINA_TRUE;
1338 it->down = EINA_TRUE;
1339 it->dragging = EINA_FALSE;
1340 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1341 it->dx = ev->canvas.x - x;
1342 it->dy = ev->canvas.y - y;
1343 it->wd->mouse_down = EINA_TRUE;
1344 if (!it->wd->multitouched)
1346 it->wd->prev_x = ev->canvas.x;
1347 it->wd->prev_y = ev->canvas.y;
1348 it->wd->multi_timeout = EINA_FALSE;
1349 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1350 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1352 it->wd->longpressed = EINA_FALSE;
1353 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1354 else it->wd->on_hold = EINA_FALSE;
1355 if (it->wd->on_hold) return;
1356 it->wd->wasselected = it->selected;
1357 _item_highlight(it);
1358 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1359 if ((!elm_widget_item_disabled_get(it)) &&
1360 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1362 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1363 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1365 if (it->long_timer) ecore_timer_del(it->long_timer);
1366 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1367 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1369 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1372 it->long_timer = NULL;
1373 it->wd->swipe = EINA_FALSE;
1374 it->wd->movements = 0;
1378 _mouse_up(void *data,
1379 Evas *evas __UNUSED__,
1380 Evas_Object *obj __UNUSED__,
1383 Elm_Gen_Item *it = data;
1384 Evas_Event_Mouse_Up *ev = event_info;
1385 Eina_Bool dragged = EINA_FALSE;
1387 if (ev->button != 1) return;
1388 it->down = EINA_FALSE;
1389 it->wd->mouse_down = EINA_FALSE;
1390 if (it->wd->multitouched)
1392 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1393 if (it->wd->multi_down) return;
1394 _multi_touch_gesture_eval(data);
1397 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1398 else it->wd->on_hold = EINA_FALSE;
1401 ecore_timer_del(it->long_timer);
1402 it->long_timer = NULL;
1406 it->dragging = EINA_FALSE;
1407 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1410 if (it->item->swipe_timer)
1412 ecore_timer_del(it->item->swipe_timer);
1413 it->item->swipe_timer = NULL;
1415 if (it->wd->multi_timer)
1417 ecore_timer_del(it->wd->multi_timer);
1418 it->wd->multi_timer = NULL;
1419 it->wd->multi_timeout = EINA_FALSE;
1421 if (it->wd->on_hold)
1423 if (it->wd->swipe) _swipe(data);
1424 it->wd->longpressed = EINA_FALSE;
1425 it->wd->on_hold = EINA_FALSE;
1428 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1430 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1432 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1434 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1435 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1437 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1438 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
1442 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1443 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1445 it->wd->reorder_deleted = EINA_FALSE;
1446 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1447 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1448 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1449 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1451 if (it->wd->longpressed)
1453 it->wd->longpressed = EINA_FALSE;
1454 if ((!it->wd->wasselected) && (!it->flipped))
1456 _item_unhighlight(it);
1459 it->wd->wasselected = EINA_FALSE;
1464 if (it->want_unrealize)
1466 _elm_genlist_item_unrealize(it, EINA_FALSE);
1467 if (it->item->block->want_unrealize)
1468 _item_block_unrealize(it->item->block);
1471 if (elm_widget_item_disabled_get(it) || (dragged) ||
1472 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1474 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1479 _item_highlight(it);
1484 _item_unhighlight(it);
1492 Widget_Data *wd = it->wd;
1495 while (wd->selected)
1497 _item_unhighlight(wd->selected->data);
1498 _item_unselect(wd->selected->data);
1504 const Eina_List *l, *l_next;
1507 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1510 _item_unhighlight(it2);
1511 _item_unselect(it2);
1513 //_item_highlight(it);
1516 _item_highlight(it);
1522 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1524 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1526 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1528 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1530 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1532 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1534 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1539 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1541 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1543 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1545 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1547 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1549 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1551 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1557 _mouse_down_scroller(void *data,
1558 Evas *evas __UNUSED__,
1559 Evas_Object *obj __UNUSED__,
1560 void *event_info __UNUSED__)
1562 Widget_Data *wd = elm_widget_data_get(data);
1565 wd->drag_started = EINA_FALSE;
1569 _mouse_up_scroller(void *data,
1570 Evas *evas __UNUSED__,
1571 Evas_Object *obj __UNUSED__,
1572 void *event_info __UNUSED__)
1574 Widget_Data *wd = elm_widget_data_get(data);
1577 wd->drag_started = EINA_FALSE;
1581 _mouse_move_scroller(void *data,
1582 Evas *evas __UNUSED__,
1583 Evas_Object *obj __UNUSED__,
1586 Widget_Data *wd = elm_widget_data_get(data);
1587 Evas_Event_Mouse_Move *ev = event_info;
1588 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
1591 if (wd->drag_started) return;
1593 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1594 dx = ev->cur.canvas.x - ev->prev.canvas.x;
1595 dy = ev->cur.canvas.y - ev->prev.canvas.y;
1598 if (adx < 0) adx = -dx;
1599 if (ady < 0) ady = -dy;
1600 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
1604 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
1605 wd->drag_started = EINA_TRUE;
1609 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
1610 wd->drag_started = EINA_TRUE;
1616 _signal_expand_toggle(void *data,
1617 Evas_Object *obj __UNUSED__,
1618 const char *emission __UNUSED__,
1619 const char *source __UNUSED__)
1621 Elm_Gen_Item *it = data;
1623 if (it->item->expanded)
1624 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1626 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1630 _signal_expand(void *data,
1631 Evas_Object *obj __UNUSED__,
1632 const char *emission __UNUSED__,
1633 const char *source __UNUSED__)
1635 Elm_Gen_Item *it = data;
1637 if (!it->item->expanded)
1638 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1642 _signal_contract(void *data,
1643 Evas_Object *obj __UNUSED__,
1644 const char *emission __UNUSED__,
1645 const char *source __UNUSED__)
1647 Elm_Gen_Item *it = data;
1649 if (it->item->expanded)
1650 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1654 _scr_hold_timer_cb(void *data)
1656 if (!data) return ECORE_CALLBACK_CANCEL;
1657 Widget_Data *wd = data;
1658 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1659 wd->scr_hold_timer = NULL;
1660 return ECORE_CALLBACK_CANCEL;
1664 _mode_finished_signal_cb(void *data,
1666 const char *emission __UNUSED__,
1667 const char *source __UNUSED__)
1671 Elm_Gen_Item *it = data;
1672 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1674 Evas *te = evas_object_evas_get(obj);
1676 evas_event_freeze(te);
1677 it->item->nocache_once = EINA_FALSE;
1678 _mode_item_unrealize(it);
1679 //FIXME: group raise
1681 if (it->item->group_item)
1682 evas_object_raise(it->item->VIEW(group_item));
1684 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_type);
1685 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1686 evas_event_thaw(te);
1687 evas_event_thaw_eval(te);
1691 _item_cache_clean(Widget_Data *wd)
1693 evas_event_freeze(evas_object_evas_get(wd->obj));
1694 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1698 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1699 wd->item_cache = eina_inlist_remove(wd->item_cache,
1700 wd->item_cache->last);
1701 wd->item_cache_count--;
1702 if (itc->spacer) evas_object_del(itc->spacer);
1703 if (itc->base_view) evas_object_del(itc->base_view);
1704 eina_stringshare_del(itc->item_style);
1707 evas_event_thaw(evas_object_evas_get(wd->obj));
1708 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1712 _item_cache_zero(Widget_Data *wd)
1714 int pmax = wd->item_cache_max;
1715 wd->item_cache_max = 0;
1716 _item_cache_clean(wd);
1717 wd->item_cache_max = pmax;
1721 _item_cache_add(Elm_Gen_Item *it)
1725 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1726 if (it->wd->item_cache_max <= 0)
1728 evas_object_del(VIEW(it));
1732 evas_object_del(it->spacer);
1735 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1736 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1740 it->wd->item_cache_count++;
1741 itc = calloc(1, sizeof(Item_Cache));
1744 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1745 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1748 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1749 EINA_INLIST_GET(itc));
1750 itc->spacer = it->spacer;
1752 itc->base_view = VIEW(it);
1754 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1755 evas_object_hide(itc->base_view);
1756 evas_object_move(itc->base_view, -9999, -9999);
1757 itc->item_style = eina_stringshare_add(it->itc->item_style);
1758 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1759 itc->selected = it->selected;
1760 itc->disabled = elm_widget_item_disabled_get(it);
1761 itc->expanded = it->item->expanded;
1764 ecore_timer_del(it->long_timer);
1765 it->long_timer = NULL;
1767 if (it->item->swipe_timer)
1769 ecore_timer_del(it->item->swipe_timer);
1770 it->item->swipe_timer = NULL;
1772 // FIXME: other callbacks?
1773 edje_object_signal_callback_del_full(itc->base_view,
1774 "elm,action,expand,toggle",
1775 "elm", _signal_expand_toggle, it);
1776 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1778 _signal_expand, it);
1779 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1780 "elm", _signal_contract, it);
1781 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1783 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1785 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1787 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1789 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1791 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1793 _item_cache_clean(it->wd);
1794 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1795 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1799 _item_cache_find(Elm_Gen_Item *it)
1804 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1805 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1807 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1809 if ((itc->tree == tree) &&
1810 (((!it->itc->item_style) && (!itc->item_style)) ||
1811 (it->itc->item_style && itc->item_style &&
1812 (!strcmp(it->itc->item_style, itc->item_style)))))
1814 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1815 EINA_INLIST_GET(itc));
1816 it->wd->item_cache_count--;
1824 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1826 if (it->position_update || it->item->block->position_update)
1828 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1829 it->position_update = EINA_FALSE;
1834 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1836 if (!it->item->nostacking)
1838 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1840 if (it->edit_obj) evas_object_lower(it->edit_obj);
1841 else evas_object_lower(VIEW(it));
1845 if (it->edit_obj) evas_object_raise(it->edit_obj);
1846 else evas_object_raise(VIEW(it));
1850 if (it->item->order_num_in & 0x1)
1852 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1853 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,odd", "elm");
1857 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1858 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,even", "elm");
1863 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1867 if (it->selected != itc->selected)
1871 edje_object_signal_emit(VIEW(it),
1872 "elm,state,selected", "elm");
1875 edje_object_signal_emit(it->edit_obj,
1876 "elm,state,selected", "elm");
1879 if (elm_widget_item_disabled_get(it) != itc->disabled)
1881 if (elm_widget_item_disabled_get(it))
1882 edje_object_signal_emit(VIEW(it),
1883 "elm,state,disabled", "elm");
1885 edje_object_signal_emit(it->edit_obj,
1886 "elm,state,disabled", "elm");
1888 if (it->item->expanded != itc->expanded)
1890 if (it->item->expanded)
1891 edje_object_signal_emit(VIEW(it),
1892 "elm,state,expanded", "elm");
1894 edje_object_signal_emit(it->edit_obj,
1895 "elm,state,expanded", "elm");
1902 edje_object_signal_emit(VIEW(it),
1903 "elm,state,selected", "elm");
1905 edje_object_signal_emit(it->edit_obj,
1906 "elm,state,selected", "elm");
1908 if (elm_widget_item_disabled_get(it))
1910 edje_object_signal_emit(VIEW(it),
1911 "elm,state,disabled", "elm");
1913 edje_object_signal_emit(it->edit_obj,
1914 "elm,state,disabled", "elm");
1916 if (it->item->expanded)
1918 edje_object_signal_emit(VIEW(it),
1919 "elm,state,expanded", "elm");
1921 edje_object_signal_emit(it->edit_obj,
1922 "elm,state,expanded", "elm");
1928 _content_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1930 Elm_Gen_Item *it = data;
1931 if (it) it->defer_unrealize = EINA_TRUE;
1935 _content_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1937 Elm_Gen_Item *it = data;
1938 if (it) it->defer_unrealize = EINA_FALSE;
1943 _item_mode_content_realize(Elm_Gen_Item *it,
1944 Evas_Object *target,
1947 Eina_List **contents_list,
1948 const char *contents_part)
1951 Eina_List *res = NULL;
1953 if (it->itc->func.content_get)
1957 Eina_List *cons = NULL;
1959 cons = elm_widget_stringlist_get(edje_object_data_get(target, contents_part));
1961 if (parts && (eina_list_count(*source) != eina_list_count(*contents_list)))
1962 res = *contents_list;
1963 EINA_LIST_FOREACH(cons, l, key)
1965 if (parts && fnmatch(parts, key, FNM_PERIOD))
1968 Evas_Object *ic = it->itc->func.content_get
1969 ((void *)it->base.data, WIDGET(it), l->data);
1973 res = eina_list_append(res, ic);
1974 edje_object_part_swallow(target, key, ic);
1975 evas_object_show(ic);
1976 elm_widget_sub_object_add(WIDGET(it), ic);
1977 if (it->item->mode_view || it->wd->decorate_mode)
1979 if (elm_widget_item_disabled_get(it))
1980 elm_widget_disabled_set(ic, EINA_TRUE);
1982 else if (it->flipped)
1984 // FIXME: if entry calcuates its cursor position correctly and conformant works,
1985 // genlist does not need to handle this focus thing.
1986 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
1987 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
1991 *source = eina_list_merge(*source, cons);
1998 _item_mode_content_unrealize(Elm_Gen_Item *it,
1999 Evas_Object *target,
2002 Eina_List **contents_list,
2003 const char *contents_part)
2005 Eina_List *res = *contents_list;
2007 if (it->itc->func.content_get)
2011 Evas_Object *ic = NULL;
2013 EINA_LIST_FOREACH(*source, l, key)
2015 if (parts && fnmatch(parts, key, FNM_PERIOD))
2018 ic = edje_object_part_swallow_get(target, key);
2021 res = eina_list_remove(res, ic);
2022 edje_object_part_unswallow(target, ic);
2023 evas_object_del(ic);
2032 _item_cache_free(Item_Cache *itc)
2034 if (itc->spacer) evas_object_del(itc->spacer);
2035 if (itc->base_view) evas_object_del(itc->base_view);
2036 eina_stringshare_del(itc->item_style);
2041 _item_text_realize(Elm_Gen_Item *it,
2042 Evas_Object *target,
2046 if (it->itc->func.text_get)
2051 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
2052 EINA_LIST_FOREACH(*source, l, key)
2054 if (parts && fnmatch(parts, key, FNM_PERIOD))
2057 char *s = it->itc->func.text_get
2058 ((void *)it->base.data, WIDGET(it), key);
2062 edje_object_part_text_set(target, key, s);
2067 edje_object_part_text_set(target, key, "");
2074 _item_content_unrealize(Elm_Gen_Item *it,
2075 Evas_Object *target,
2079 Eina_List *res = it->content_objs;
2081 if (it->itc->func.content_get)
2085 Evas_Object *ic = NULL;
2087 EINA_LIST_FOREACH(*source, l, key)
2089 if (parts && fnmatch(parts, key, FNM_PERIOD))
2092 ic = edje_object_part_swallow_get(target, key);
2095 res = eina_list_remove(res, ic);
2096 edje_object_part_unswallow(target, ic);
2097 evas_object_del(ic);
2106 _item_content_realize(Elm_Gen_Item *it,
2107 Evas_Object *target,
2111 Eina_List *res = NULL;
2113 if (it->itc->func.content_get)
2117 Evas_Object *ic = NULL;
2118 Eina_List *cons = NULL;
2120 cons = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
2122 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
2123 res = it->content_objs;
2125 EINA_LIST_FOREACH(cons, l, key)
2127 if (parts && fnmatch(parts, key, FNM_PERIOD))
2130 if (it->itc->func.content_get)
2131 ic = it->itc->func.content_get
2132 ((void *)it->base.data, WIDGET(it), key);
2135 res = eina_list_append(res, ic);
2136 edje_object_part_swallow(target, key, ic);
2137 evas_object_show(ic);
2138 elm_widget_sub_object_add(WIDGET(it), ic);
2139 evas_object_event_callback_add(ic,
2140 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2141 _changed_size_hints, it);
2144 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2145 // genlist does not need to handle this focus thing.
2146 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2147 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2150 if (elm_widget_item_disabled_get(it))
2151 elm_widget_disabled_set(ic, EINA_TRUE);
2154 *source = eina_list_merge(*source, cons);
2161 _item_state_realize(Elm_Gen_Item *it,
2162 Evas_Object *target,
2166 if (it->itc->func.state_get)
2172 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
2173 EINA_LIST_FOREACH(*source, l, key)
2175 if (parts && fnmatch(parts, key, FNM_PERIOD))
2178 Eina_Bool on = it->itc->func.state_get
2179 ((void *)it->base.data, WIDGET(it), key);
2183 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
2184 edje_object_signal_emit(target, buf, "elm");
2188 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
2189 edje_object_signal_emit(target, buf, "elm");
2196 _item_flips_realize(Elm_Gen_Item *it,
2197 Evas_Object *target,
2200 Eina_List *res = NULL;
2202 if (it->itc->func.content_get)
2206 Evas_Object *ic = NULL;
2207 Eina_List *cons = NULL;
2209 cons = elm_widget_stringlist_get(edje_object_data_get(target, "flips"));
2211 EINA_LIST_FOREACH(cons, l, key)
2213 if (it->itc->func.content_get)
2214 ic = it->itc->func.content_get
2215 ((void *)it->base.data, WIDGET(it), key);
2218 res = eina_list_append(res, ic);
2219 edje_object_part_swallow(target, key, ic);
2220 evas_object_show(ic);
2221 elm_widget_sub_object_add(WIDGET(it), ic);
2222 // FIXME: if entry calcuates its cursor position correctly and conformant works,
2223 // genlist does not need to handle this focus thing.
2224 evas_object_smart_callback_add(ic, "focused", _content_focused, it);
2225 evas_object_smart_callback_add(ic, "unfocused", _content_unfocused, it);
2226 if (elm_widget_item_disabled_get(it))
2227 elm_widget_disabled_set(ic, EINA_TRUE);
2230 *source = eina_list_merge(*source, cons);
2237 _item_realize(Elm_Gen_Item *it,
2241 const char *treesize;
2244 Item_Cache *itc = NULL;
2246 if (it->generation < it->wd->generation) return;
2247 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2250 if (it->item->order_num_in != in)
2252 it->item->order_num_in = in;
2253 _elm_genlist_item_odd_even_update(it);
2254 _elm_genlist_item_state_update(it, NULL);
2255 _elm_genlist_item_index_update(it);
2257 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2258 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2261 it->item->order_num_in = in;
2263 if ((it->item->nocache_once) && (!it->flipped))
2264 it->item->nocache_once = EINA_FALSE;
2265 else if (!it->item->nocache)
2266 itc = _item_cache_find(it);
2267 if (itc && (!it->wd->tree_effect_enabled))
2269 VIEW(it) = itc->base_view;
2270 itc->base_view = NULL;
2271 it->spacer = itc->spacer;
2276 const char *stacking_even;
2277 const char *stacking;
2279 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2280 edje_object_scale_set(VIEW(it),
2281 elm_widget_scale_get(WIDGET(it)) *
2282 _elm_config->scale);
2283 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2284 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2286 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2287 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2289 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2291 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2292 elm_widget_style_get(WIDGET(it)));
2294 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2295 if (!stacking_even) stacking_even = "above";
2296 it->item->stacking_even = !!strcmp("above", stacking_even);
2298 stacking = edje_object_data_get(VIEW(it), "stacking");
2299 if (!stacking) stacking = "yes";
2300 it->item->nostacking = !!strcmp("yes", stacking);
2302 edje_object_mirrored_set(VIEW(it),
2303 elm_widget_mirrored_get(WIDGET(it)));
2306 _elm_genlist_item_odd_even_update(it);
2308 treesize = edje_object_data_get(VIEW(it), "treesize");
2309 if (treesize) tsize = atoi(treesize);
2310 if (!it->spacer && treesize)
2313 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2314 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2315 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2319 evas_object_size_hint_min_set(it->spacer,
2320 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2321 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2325 edje_object_signal_callback_add(VIEW(it),
2326 "elm,action,expand,toggle",
2327 "elm", _signal_expand_toggle, it);
2328 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2329 "elm", _signal_expand, it);
2330 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2331 "elm", _signal_contract, it);
2332 _item_mouse_callbacks_add(it, VIEW(it));
2334 if ((it->wd->decorate_mode) && (!it->edit_obj) &&
2335 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2336 _decorate_mode_item_realize(it, EINA_FALSE);
2338 _elm_genlist_item_state_update(it, itc);
2339 _elm_genlist_item_index_update(it);
2342 if ((calc) && (it->wd->homogeneous) &&
2343 ((it->wd->item_width) ||
2344 ((it->wd->item_width) && (it->wd->group_item_width))))
2346 /* homogenous genlist shortcut */
2347 if (!it->item->mincalcd)
2351 it->item->w = it->item->minw = it->wd->group_item_width;
2352 it->item->h = it->item->minh = it->wd->group_item_height;
2356 it->item->w = it->item->minw = it->wd->item_width;
2357 it->item->h = it->item->minh = it->wd->item_height;
2359 it->item->mincalcd = EINA_TRUE;
2364 /* FIXME: If you see that assert, please notify us and we
2365 will clean our mess */
2366 assert(eina_list_count(it->content_objs) == 0);
2368 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2369 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2370 _item_state_realize(it, VIEW(it), &it->states, NULL);
2373 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2374 it->content_objs = _item_flips_realize(it, VIEW(it), &it->contents);
2377 if (!it->item->mincalcd || ((it->wd->mode == ELM_LIST_COMPRESS) && (it->item->w != it->item->minw)))
2379 Evas_Coord mw = -1, mh = -1;
2381 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2382 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2383 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2384 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2386 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2387 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2388 it->item->w = it->item->minw = mw;
2389 it->item->h = it->item->minh = mh;
2390 it->item->mincalcd = EINA_TRUE;
2392 if ((!it->wd->group_item_width) && (it->group))
2394 it->wd->group_item_width = mw;
2395 it->wd->group_item_height = mh;
2397 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2399 it->wd->item_width = mw;
2400 it->wd->item_height = mh;
2403 if (!calc) evas_object_show(VIEW(it));
2406 if (it->tooltip.content_cb)
2408 elm_widget_item_tooltip_content_cb_set(it,
2409 it->tooltip.content_cb,
2410 it->tooltip.data, NULL);
2411 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2412 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2415 if (it->mouse_cursor)
2416 elm_widget_item_cursor_set(it, it->mouse_cursor);
2418 it->realized = EINA_TRUE;
2419 it->want_unrealize = EINA_FALSE;
2421 if (itc) _item_cache_free(itc);
2422 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2423 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2426 if (it->item->tree_effect_hideme)
2428 if (it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE)
2429 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
2430 it->item->tree_effect_hideme = EINA_FALSE;
2432 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2435 if ((!calc) && (it->wd->decorate_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2437 if (it->itc->decorate_all_item_style)
2439 if (!it->edit_obj) _decorate_mode_item_realize(it, EINA_FALSE);
2440 edje_object_message_signal_process(it->edit_obj);
2443 edje_object_message_signal_process(VIEW(it));
2447 _item_unrealize_cb(Elm_Gen_Item *it)
2449 if (it->item->nocache_once || it->item->nocache)
2451 evas_object_del(VIEW(it));
2455 evas_object_del(it->spacer);
2461 edje_object_mirrored_set(VIEW(it),
2462 elm_widget_mirrored_get(WIDGET(it)));
2463 edje_object_scale_set(VIEW(it),
2464 elm_widget_scale_get(WIDGET(it))
2465 * _elm_config->scale);
2466 _item_cache_add(it);
2469 _mode_item_unrealize(it);
2471 it->realized = EINA_FALSE;
2472 it->want_unrealize = EINA_FALSE;
2473 if (it->wd->decorate_mode) _decorate_mode_item_unrealize(it);
2477 _item_block_recalc(Item_Block *itb,
2483 Evas_Coord minw = 0, minh = 0;
2484 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2487 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2489 EINA_LIST_FOREACH(itb->items, l, it)
2491 if (it->generation < it->wd->generation) continue;
2492 showme |= it->item->showme;
2497 if (!it->item->mincalcd) changed = EINA_TRUE;
2500 _item_realize(it, in, EINA_TRUE);
2501 _elm_genlist_item_unrealize(it, EINA_TRUE);
2506 _item_realize(it, in, EINA_TRUE);
2507 _elm_genlist_item_unrealize(it, EINA_TRUE);
2511 _item_realize(it, in, EINA_FALSE);
2512 minh += it->item->minh;
2513 if (minw < it->item->minw) minw = it->item->minw;
2521 itb->changed = EINA_FALSE;
2522 itb->position_update = EINA_FALSE;
2523 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2524 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2529 _item_block_realize(Item_Block *itb)
2531 if (itb->realized) return;
2532 itb->realized = EINA_TRUE;
2533 itb->want_unrealize = EINA_FALSE;
2537 _item_block_unrealize(Item_Block *itb)
2541 Eina_Bool dragging = EINA_FALSE;
2543 if (!itb->realized) return;
2544 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2545 EINA_LIST_FOREACH(itb->items, l, it)
2547 if (itb->must_recalc || !it->group)
2551 dragging = EINA_TRUE;
2552 it->want_unrealize = EINA_TRUE;
2555 _elm_genlist_item_unrealize(it, EINA_FALSE);
2560 itb->realized = EINA_FALSE;
2561 itb->want_unrealize = EINA_TRUE;
2564 itb->want_unrealize = EINA_FALSE;
2565 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2566 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2570 _get_space_for_reorder_item(Elm_Gen_Item *it)
2572 Evas_Coord rox, roy, row, roh, oy, oh;
2573 Eina_Bool top = EINA_FALSE;
2574 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2575 if (!reorder_it) return 0;
2577 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2578 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2580 if ((it->wd->reorder_start_y < it->item->block->y) &&
2581 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2583 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2584 if (it->item->block->count == 1)
2585 it->wd->reorder_rel = it;
2587 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2588 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2590 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2593 it->item->block->reorder_offset = 0;
2595 it->item->scrl_y += it->item->block->reorder_offset;
2597 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2598 rox, roy + (roh / 2), row, 1));
2601 it->wd->reorder_rel = it;
2602 it->item->scrl_y += it->wd->reorder_it->item->h;
2603 return it->wd->reorder_it->item->h;
2610 _reorder_move_animator_cb(void *data)
2612 Elm_Gen_Item *it = data;
2613 Eina_Bool down = EINA_FALSE;
2615 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2617 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2619 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2622 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2623 if (diff > it->item->h) y = diff / 2;
2625 if (it->item->old_scrl_y < it->item->scrl_y)
2627 it->item->old_scrl_y += y;
2630 else if (it->item->old_scrl_y > it->item->scrl_y)
2632 it->item->old_scrl_y -= y;
2637 _item_position(it, it->edit_obj, it->item->scrl_x, it->item->old_scrl_y);
2639 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2640 //FIXME : group raise
2642 _group_items_recalc(it->wd);
2645 if ((it->wd->reorder_pan_move) ||
2646 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2647 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2649 it->item->old_scrl_y = it->item->scrl_y;
2650 it->item->move_effect_enabled = EINA_FALSE;
2651 it->wd->reorder_move_animator = NULL;
2652 return ECORE_CALLBACK_CANCEL;
2654 return ECORE_CALLBACK_RENEW;
2658 _item_position(Elm_Gen_Item *it,
2666 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2667 evas_object_resize(view, it->item->w, it->item->h);
2668 evas_object_move(view, it_x, it_y);
2669 evas_object_show(view);
2670 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2671 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2675 _item_block_position(Item_Block *itb,
2680 //FIXME : group raise
2684 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2685 Eina_Bool vis = EINA_FALSE;
2686 Evas_Coord minh = 0;
2688 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2689 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2690 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2692 EINA_LIST_FOREACH(itb->items, l, it)
2694 if (it->generation < it->wd->generation) continue;
2695 else if (it->wd->reorder_it == it) continue;
2698 it->item->w = itb->w;
2699 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2700 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2702 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2703 cvx, cvy, cvw, cvh));
2704 //FIXME : group raise
2709 if ((itb->realized) && (!it->realized))
2711 if (vis) _item_realize(it, in, EINA_FALSE);
2715 if (vis || it->dragging)
2717 if (it->wd->reorder_mode)
2718 y += _get_space_for_reorder_item(it);
2719 //FIXME : group raise
2721 git = it->item->group_item;
2724 if (git->item->scrl_y < oy)
2725 git->item->scrl_y = oy;
2726 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2727 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2728 git->item->want_realize = EINA_TRUE;
2731 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2733 if (!it->item->move_effect_enabled)
2735 it->item->move_effect_enabled = EINA_TRUE;
2736 it->wd->reorder_move_animator =
2738 _reorder_move_animator_cb, it);
2741 if (!it->item->move_effect_enabled)
2743 if ((it->wd->decorate_mode) && (it->itc->decorate_all_item_style))
2744 _decorate_mode_item_position(it, it->item->scrl_x,
2748 if (!it->wd->tree_effect_enabled ||
2749 (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE) ||
2750 ((it->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE) &&
2751 (it->item->old_scrl_y == it->item->scrl_y)))
2753 if (it->item->mode_view)
2754 _item_position(it, it->item->mode_view,
2758 _item_position(it, VIEW(it), it->item->scrl_x,
2762 it->item->old_scrl_y = it->item->scrl_y;
2767 if (!it->wd->tree_effect_animator)
2768 _elm_genlist_item_unrealize(it, EINA_FALSE);
2773 //FIXME : group raise
2777 if (vis) it->item->want_realize = EINA_TRUE;
2781 minh += it->item->minh;
2783 if (!itb->wd->reorder_it) itb->minh = minh;
2784 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2785 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2788 //FIXME: group raise
2791 _group_items_recalc(void *data)
2793 Widget_Data *wd = data;
2797 evas_event_freeze(evas_object_evas_get(wd->obj));
2798 EINA_LIST_FOREACH(wd->group_items, l, git)
2800 if (git->item->want_realize)
2803 _item_realize(git, 0, EINA_FALSE);
2804 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2805 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2806 evas_object_show(VIEW(git));
2807 evas_object_raise(VIEW(git));
2809 else if (!git->item->want_realize && git->realized)
2812 _elm_genlist_item_unrealize(git, EINA_FALSE);
2815 evas_event_thaw(evas_object_evas_get(wd->obj));
2816 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2821 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2823 Elm_Gen_Item *it = data;
2825 it->item->mincalcd = EINA_FALSE;
2826 it->item->block->changeme = EINA_TRUE;
2827 if (it->wd->changed_job) ecore_job_del(it->wd->changed_job);
2828 it->wd->changed_job = ecore_job_add(_changed_job, it->wd);
2832 _must_recalc_idler(void *data)
2834 Widget_Data *wd = data;
2835 if (wd->calc_job) ecore_job_del(wd->calc_job);
2836 wd->calc_job = ecore_job_add(_calc_job, wd);
2837 wd->must_recalc_idler = NULL;
2838 return ECORE_CALLBACK_CANCEL;
2842 _scroll_item(Widget_Data *wd)
2844 Elm_Gen_Item *it = NULL;
2845 //FIXME: group raise
2847 Evas_Coord gith = 0;
2849 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2850 if (!wd->show_item) return;
2852 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2854 dx = it->x + it->item->block->x;
2855 dy = it->y + it->item->block->y;
2856 dw = it->item->block->w;
2858 switch (wd->scrollto_type)
2860 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2861 //FIXME: group raise
2863 if (it->item->group_item) gith = it->item->group_item->item->h;
2867 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2868 dy += (it->item->h / 2 - oh / 2);
2870 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2872 if ((wd->expanded_item) &&
2873 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2874 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2876 it = wd->expanded_item;
2877 dx = it->x + it->item->block->x;
2878 dy = it->y + it->item->block->y;
2879 //FIXME: group raise
2881 if (it->item->group_item) gith = it->item->group_item->item->h;
2882 dx = it->x + it->item->block->x;
2883 dy = it->y + it->item->block->y - gith;
2885 dw = it->item->block->w;
2889 //FIXME: group raise
2891 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2892 gith = it->item->group_item->item->h;
2900 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2902 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2904 it->item->showme = EINA_FALSE;
2905 wd->show_item = NULL;
2906 wd->auto_scroll_enabled = EINA_FALSE;
2907 wd->check_scroll = EINA_FALSE;
2911 _calc_job(void *data)
2913 Widget_Data *wd = data;
2914 Item_Block *itb, *chb = NULL;
2915 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2916 Evas_Coord pan_w = 0, pan_h = 0;
2918 Eina_Bool minw_change = EINA_FALSE;
2919 Eina_Bool did_must_recalc = EINA_FALSE;
2922 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2923 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2928 evas_event_freeze(evas_object_evas_get(wd->obj));
2929 EINA_INLIST_FOREACH(wd->blocks, itb)
2931 Eina_Bool showme = EINA_FALSE;
2934 showme = itb->showme;
2935 itb->showme = EINA_FALSE;
2938 if (itb->realized) _item_block_unrealize(itb);
2940 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2942 if (itb->must_recalc)
2946 EINA_LIST_FOREACH(itb->items, l, it)
2947 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2948 itb->changed = EINA_TRUE;
2949 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2950 if (itb->realized) _item_block_unrealize(itb);
2951 itb->must_recalc = EINA_FALSE;
2953 showme = _item_block_recalc(itb, in, EINA_FALSE);
2959 if (minw == -1) minw = itb->minw;
2960 else if ((!itb->must_recalc) && (minw < itb->minw))
2963 minw_change = EINA_TRUE;
2968 minw_change = EINA_TRUE;
2974 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2975 wd->check_scroll = EINA_TRUE;
2979 EINA_INLIST_FOREACH(wd->blocks, itb)
2985 if ((chb) && (EINA_INLIST_GET(chb)->next))
2987 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2989 if (itb->realized) _item_block_unrealize(itb);
2992 wd->realminw = minw;
2993 if (minw < wd->w) minw = wd->w;
2994 if ((minw != wd->minw) || (minh != wd->minh))
2998 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2999 _sizing_eval(wd->obj);
3000 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
3005 it = wd->anchor_item;
3006 it_y = wd->anchor_y;
3007 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
3008 it->item->block->y + it->y + it_y);
3009 wd->anchor_item = it;
3010 wd->anchor_y = it_y;
3013 if (did_must_recalc)
3015 if (!wd->must_recalc_idler)
3016 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
3018 if (wd->check_scroll)
3020 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
3021 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
3022 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3023 switch (wd->scrollto_type)
3025 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
3028 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
3031 case ELM_GENLIST_ITEM_SCROLLTO_IN:
3038 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
3039 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
3045 wd->calc_job = NULL;
3046 evas_object_smart_changed(wd->pan_smart);
3047 evas_event_thaw(evas_object_evas_get(wd->obj));
3048 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3052 _update_job(void *data)
3054 Widget_Data *wd = data;
3058 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
3060 wd->update_job = NULL;
3063 evas_event_freeze(evas_object_evas_get(wd->obj));
3064 EINA_INLIST_FOREACH(wd->blocks, itb)
3066 Evas_Coord itminw, itminh;
3073 _item_block_position(itb, num);
3077 recalc = EINA_FALSE;
3078 EINA_LIST_FOREACH(itb->items, l2, it)
3080 if (it->item->updateme)
3082 itminw = it->item->minw;
3083 itminh = it->item->minh;
3087 _elm_genlist_item_unrealize(it, EINA_FALSE);
3088 _item_realize(it, num, EINA_FALSE);
3089 position = EINA_TRUE;
3093 _item_realize(it, num, EINA_TRUE);
3094 _elm_genlist_item_unrealize(it, EINA_TRUE);
3096 if ((it->item->minw != itminw) || (it->item->minh != itminh))
3098 it->item->updateme = EINA_FALSE;
3102 itb->updateme = EINA_FALSE;
3105 position = EINA_TRUE;
3106 itb->changed = EINA_TRUE;
3107 _item_block_recalc(itb, num0, EINA_FALSE);
3108 _item_block_position(itb, num0);
3113 if (wd->calc_job) ecore_job_del(wd->calc_job);
3114 wd->calc_job = ecore_job_add(_calc_job, wd);
3116 evas_event_thaw(evas_object_evas_get(wd->obj));
3117 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3121 _changed_job(void *data)
3123 Widget_Data *wd = data; Eina_List *l2;
3125 int num, num0, position = 0;
3126 Eina_Bool width_changed = EINA_FALSE, height_changed = EINA_FALSE;
3128 wd->changed_job = NULL;
3130 EINA_INLIST_FOREACH(wd->blocks, itb)
3132 Evas_Coord itminw, itminh;
3139 _item_block_position(itb, num);
3143 width_changed = height_changed = EINA_FALSE;
3144 EINA_LIST_FOREACH(itb->items, l2, it)
3146 if ((!it->item->mincalcd) && (it->realized))
3148 Evas_Coord mw = -1, mh = -1;
3149 itminw = it->item->minw;
3150 itminh = it->item->minh;
3152 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->w;
3153 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3154 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3155 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
3156 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
3157 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3158 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3160 width_changed = EINA_TRUE;
3163 it->item->w = it->item->minw = mw;
3164 it->item->h = it->item->minh = mh;
3165 it->item->mincalcd = EINA_TRUE;
3167 //if ((it->item->minw != itminw) || (it->item->minh != itminh))
3168 //if ((it->item->minh != itminh))
3170 if ((it->item->minw != itminw))
3171 width_changed = EINA_TRUE;
3172 if ((it->item->minh != itminh))
3173 height_changed = EINA_TRUE;
3175 if ((!it->wd->group_item_width) && (it->group))
3177 it->wd->group_item_width = mw;
3178 it->wd->group_item_height = mh;
3180 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
3182 it->wd->item_width = mw;
3183 it->wd->item_height = mh;
3188 itb->changeme = EINA_FALSE;
3189 // TODO: why this is separated.
3193 itb->changed = EINA_TRUE;
3194 _item_block_recalc(itb, num0, 0);
3195 _item_block_position(itb, num0);
3197 else if (width_changed)
3199 _item_block_position(itb, num0);
3204 if (wd->calc_job) ecore_job_del(wd->calc_job);
3205 wd->calc_job = ecore_job_add(_calc_job, wd);
3210 _pan_set(Evas_Object *obj,
3214 Pan *sd = evas_object_smart_data_get(obj);
3218 // Evas_Coord ow, oh;
3219 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3220 // ow = sd->wd->minw - ow;
3221 // if (ow < 0) ow = 0;
3222 // oh = sd->wd->minh - oh;
3223 // if (oh < 0) oh = 0;
3224 // if (x < 0) x = 0;
3225 // if (y < 0) y = 0;
3226 // if (x > ow) x = ow;
3227 // if (y > oh) y = oh;
3228 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
3232 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3234 if ((itb->y + itb->h) > y)
3239 EINA_LIST_FOREACH(itb->items, l2, it)
3241 if ((itb->y + it->y) >= y)
3243 sd->wd->anchor_item = it;
3244 sd->wd->anchor_y = -(itb->y + it->y - y);
3251 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
3255 _pan_get(Evas_Object *obj,
3259 Pan *sd = evas_object_smart_data_get(obj);
3262 if (x) *x = sd->wd->pan_x;
3263 if (y) *y = sd->wd->pan_y;
3267 _pan_max_get(Evas_Object *obj,
3271 Pan *sd = evas_object_smart_data_get(obj);
3275 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3276 ow = sd->wd->minw - ow;
3278 oh = sd->wd->minh - oh;
3285 _pan_min_get(Evas_Object *obj __UNUSED__,
3294 _pan_child_size_get(Evas_Object *obj,
3298 Pan *sd = evas_object_smart_data_get(obj);
3301 if (w) *w = sd->wd->minw;
3302 if (h) *h = sd->wd->minh;
3306 _pan_add(Evas_Object *obj)
3309 Evas_Object_Smart_Clipped_Data *cd;
3312 cd = evas_object_smart_data_get(obj);
3315 sd->__clipped_data = *cd;
3317 evas_object_smart_data_set(obj, sd);
3321 _pan_del(Evas_Object *obj)
3323 Pan *sd = evas_object_smart_data_get(obj);
3328 ecore_job_del(sd->resize_job);
3329 sd->resize_job = NULL;
3335 _pan_resize_job(void *data)
3339 _sizing_eval(sd->wd->obj);
3340 sd->resize_job = NULL;
3344 _pan_resize(Evas_Object *obj,
3348 Pan *sd = evas_object_smart_data_get(obj);
3352 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3353 if ((ow == w) && (oh == h)) return;
3354 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
3357 if (sd->resize_job) ecore_job_del(sd->resize_job);
3358 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
3360 sd->wd->pan_changed = EINA_TRUE;
3361 evas_object_smart_changed(obj);
3362 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3363 sd->wd->calc_job = NULL;
3367 _pan_calculate(Evas_Object *obj)
3369 Pan *sd = evas_object_smart_data_get(obj);
3371 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
3373 //FIXME: group raise
3380 evas_event_freeze(evas_object_evas_get(obj));
3382 if (sd->wd->pan_changed)
3385 sd->wd->pan_changed = EINA_FALSE;
3388 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3389 sd->wd->prev_viewport_w = ow;
3390 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
3391 //FIXME: group raise
3393 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
3395 git->item->want_realize = EINA_FALSE;
3399 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3401 if (!sd->wd->tree_effect_animator)
3403 _item_tree_effect_before(sd->wd->expanded_item);
3404 evas_object_raise(sd->wd->alpha_bg);
3405 evas_object_show(sd->wd->alpha_bg);
3406 sd->wd->start_time = ecore_time_get();
3407 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3411 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
3413 itb->w = sd->wd->minw;
3414 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3415 itb->y - sd->wd->pan_y + oy,
3417 cvx, cvy, cvw, cvh))
3419 if ((!itb->realized) || (itb->changed))
3421 _item_block_realize(itb);
3423 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3424 sd->wd->calc_job = NULL;
3427 _item_block_position(itb, in);
3431 if (itb->realized) _item_block_unrealize(itb);
3435 //FIXME: group raise
3437 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3438 _group_items_recalc(sd->wd);
3440 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3442 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3443 sd->wd->reorder_pan_move = EINA_TRUE;
3444 else sd->wd->reorder_pan_move = EINA_FALSE;
3445 evas_object_raise(sd->wd->VIEW(reorder_it));
3446 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3447 sd->wd->start_time = ecore_loop_time_get();
3450 if (!sd->wd->tree_effect_enabled || (sd->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
3451 _item_auto_scroll(sd->wd);
3453 evas_event_thaw(evas_object_evas_get(obj));
3454 evas_event_thaw_eval(evas_object_evas_get(obj));
3458 _pan_move(Evas_Object *obj,
3459 Evas_Coord x __UNUSED__,
3460 Evas_Coord y __UNUSED__)
3462 Pan *sd = evas_object_smart_data_get(obj);
3466 sd->wd->pan_changed = EINA_TRUE;
3467 evas_object_smart_changed(obj);
3468 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3469 sd->wd->calc_job = NULL;
3473 _hold_on(void *data __UNUSED__,
3475 void *event_info __UNUSED__)
3477 Widget_Data *wd = elm_widget_data_get(obj);
3479 elm_smart_scroller_hold_set(wd->scr, 1);
3483 _hold_off(void *data __UNUSED__,
3485 void *event_info __UNUSED__)
3487 Widget_Data *wd = elm_widget_data_get(obj);
3489 elm_smart_scroller_hold_set(wd->scr, 0);
3493 _freeze_on(void *data __UNUSED__,
3495 void *event_info __UNUSED__)
3497 Widget_Data *wd = elm_widget_data_get(obj);
3499 elm_smart_scroller_freeze_set(wd->scr, 1);
3503 _freeze_off(void *data __UNUSED__,
3505 void *event_info __UNUSED__)
3507 Widget_Data *wd = elm_widget_data_get(obj);
3509 elm_smart_scroller_freeze_set(wd->scr, 0);
3513 _scr_anim_start(void *data,
3514 Evas_Object *obj __UNUSED__,
3515 void *event_info __UNUSED__)
3517 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3521 _scr_anim_stop(void *data,
3522 Evas_Object *obj __UNUSED__,
3523 void *event_info __UNUSED__)
3525 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3529 _scr_drag_start(void *data,
3530 Evas_Object *obj __UNUSED__,
3531 void *event_info __UNUSED__)
3533 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3537 _scr_drag_stop(void *data,
3538 Evas_Object *obj __UNUSED__,
3539 void *event_info __UNUSED__)
3541 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3545 _edge_left(void *data,
3546 Evas_Object *scr __UNUSED__,
3547 void *event_info __UNUSED__)
3549 Evas_Object *obj = data;
3550 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3554 _edge_right(void *data,
3555 Evas_Object *scr __UNUSED__,
3556 void *event_info __UNUSED__)
3558 Evas_Object *obj = data;
3559 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3563 _edge_top(void *data,
3564 Evas_Object *scr __UNUSED__,
3565 void *event_info __UNUSED__)
3567 Evas_Object *obj = data;
3568 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3572 _edge_bottom(void *data,
3573 Evas_Object *scr __UNUSED__,
3574 void *event_info __UNUSED__)
3576 Evas_Object *obj = data;
3577 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3581 _mode_item_realize(Elm_Gen_Item *it)
3585 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
3587 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3588 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3589 edje_object_scale_set(it->item->mode_view,
3590 elm_widget_scale_get(WIDGET(it)) *
3591 _elm_config->scale);
3592 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
3593 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
3595 strncpy(buf, "item", sizeof(buf));
3596 if (it->wd->mode == ELM_LIST_COMPRESS)
3597 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3599 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3600 strncat(buf, "/", sizeof(buf) - strlen(buf));
3601 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3603 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
3604 elm_widget_style_get(WIDGET(it)));
3605 edje_object_mirrored_set(it->item->mode_view,
3606 elm_widget_mirrored_get(WIDGET(it)));
3608 /* signal callback add */
3609 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
3611 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
3613 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
3616 /* text_get, content_get, state_get */
3617 /* FIXME: If you see that assert, please notify us and we
3618 will clean our mess */
3619 assert(eina_list_count(it->item->mode_content_objs) == 0);
3621 _item_text_realize(it, it->item->mode_view, &it->item->mode_texts, NULL);
3622 it->item->mode_content_objs =
3623 _item_content_realize(it, it->item->mode_view,
3624 &it->item->mode_contents, NULL);
3625 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
3627 edje_object_part_swallow(it->item->mode_view,
3628 edje_object_data_get(it->item->mode_view, "mode_part"),
3631 it->want_unrealize = EINA_FALSE;
3632 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3633 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3637 _mode_item_unrealize(Elm_Gen_Item *it)
3639 Widget_Data *wd = it->wd;
3640 Evas_Object *content;
3641 if (!it->item->mode_view) return;
3643 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3644 elm_widget_stringlist_free(it->item->mode_texts);
3645 it->item->mode_texts = NULL;
3646 elm_widget_stringlist_free(it->item->mode_contents);
3647 it->item->mode_contents = NULL;
3648 elm_widget_stringlist_free(it->item->mode_states);
3650 EINA_LIST_FREE(it->item->mode_content_objs, content)
3651 evas_object_del(content);
3653 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
3654 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3655 evas_object_del(it->item->mode_view);
3656 it->item->mode_view = NULL;
3658 if (wd->mode_item == it)
3659 wd->mode_item = NULL;
3660 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3661 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3665 _item_mode_set(Elm_Gen_Item *it)
3668 Widget_Data *wd = it->wd;
3673 it->item->nocache_once = EINA_TRUE;
3675 if (wd->scr_hold_timer)
3677 ecore_timer_del(wd->scr_hold_timer);
3678 wd->scr_hold_timer = NULL;
3680 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3681 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3683 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3684 _mode_item_realize(it);
3685 if (it->item->group_item)
3686 evas_object_raise(it->item->VIEW(group_item));
3687 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
3688 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3689 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3691 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_type);
3692 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3696 _item_mode_unset(Widget_Data *wd)
3699 if (!wd->mode_item) return;
3700 char buf[1024], buf2[1024];
3704 it->item->nocache_once = EINA_TRUE;
3706 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_type);
3707 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_type);
3709 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3710 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
3712 wd->mode_item = NULL;
3716 _decorate_mode_item_position(Elm_Gen_Item *it, int itx, int ity)
3718 if ((!it) || (!it->wd->decorate_mode)) return;
3719 evas_object_resize(it->edit_obj, it->item->w, it->item->h);
3720 evas_object_move(it->edit_obj, itx, ity);
3724 _decorate_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3727 const char *stacking_even;
3728 const char *stacking;
3730 if ((!it) || (it->item->decorate_mode_item_realized) ||
3731 (it->generation < it->wd->generation))
3734 it->edit_obj = edje_object_add(evas_object_evas_get(WIDGET(it)));
3735 edje_object_scale_set(it->edit_obj, elm_widget_scale_get(WIDGET(it)) *
3736 _elm_config->scale);
3737 evas_object_smart_member_add(it->edit_obj, it->wd->pan_smart);
3738 elm_widget_sub_object_add(WIDGET(it), it->edit_obj);
3740 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3741 strncpy(buf, "tree", sizeof(buf));
3742 else strncpy(buf, "item", sizeof(buf));
3743 if (it->wd->mode == ELM_LIST_COMPRESS)
3744 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3746 strncat(buf, "/", sizeof(buf) - strlen(buf));
3747 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3749 _elm_theme_object_set(WIDGET(it), it->edit_obj, "genlist", buf,
3750 elm_widget_style_get(WIDGET(it)));
3752 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3753 if (!stacking_even) stacking_even = "above";
3754 it->item->stacking_even = !!strcmp("above", stacking_even);
3756 stacking = edje_object_data_get(VIEW(it), "stacking");
3757 if (!stacking) stacking = "yes";
3758 it->item->nostacking = !!strcmp("yes", stacking);
3760 edje_object_mirrored_set(it->edit_obj,
3761 elm_widget_mirrored_get(WIDGET(it)));
3763 _elm_genlist_item_odd_even_update(it);
3764 _elm_genlist_item_state_update(it, NULL);
3766 if (effect_on) edje_object_signal_emit(it->edit_obj, "elm,state,decorate,enabled,effect", "elm");
3767 else edje_object_signal_emit(it->edit_obj, "elm,state,decorate,enabled", "elm");
3769 _item_mouse_callbacks_del(it, VIEW(it));
3770 _item_mouse_callbacks_add(it, it->edit_obj);
3772 _item_text_realize(it, it->edit_obj, &it->item->edit_texts, NULL);
3773 if (it->flipped) edje_object_signal_emit(it->edit_obj, "elm,state,flip,enabled", "elm");
3774 it->item->edit_content_objs =
3775 _item_mode_content_realize(it, it->edit_obj, &it->contents,
3776 NULL, &it->item->edit_content_objs,
3777 "decorate_contents"); //FIXME
3778 _item_state_realize(it, it->edit_obj, &it->item->edit_states, NULL);
3779 edje_object_part_swallow(it->edit_obj, "elm.swallow.decorate.content", VIEW(it));
3781 _decorate_mode_item_position(it, it->item->scrl_x, it->item->scrl_y);
3782 evas_object_show(it->edit_obj);
3784 it->item->decorate_mode_item_realized = EINA_TRUE;
3785 it->want_unrealize = EINA_FALSE;
3789 _decorate_mode_item_unrealize(Elm_Gen_Item *it)
3792 if ((!it) || (!it->item->decorate_mode_item_realized)) return;
3794 edje_object_part_unswallow(it->edit_obj, VIEW(it));
3795 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3796 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3797 _elm_genlist_item_odd_even_update(it);
3798 _elm_genlist_item_state_update(it, NULL);
3800 evas_object_del(it->edit_obj);
3801 it->edit_obj = NULL;
3802 elm_widget_stringlist_free(it->item->edit_texts);
3803 it->item->edit_texts = NULL;
3804 elm_widget_stringlist_free(it->item->edit_contents);
3805 it->item->edit_contents = NULL;
3806 elm_widget_stringlist_free(it->item->edit_states);
3807 it->item->edit_states = NULL;
3808 EINA_LIST_FREE(it->item->edit_content_objs, icon)
3809 evas_object_del(icon);
3810 edje_object_message_signal_process(it->edit_obj);
3811 _item_mouse_callbacks_del(it, it->edit_obj);
3812 _item_mouse_callbacks_add(it, VIEW(it));
3814 it->item->decorate_mode_item_realized = EINA_FALSE;
3818 _item_auto_scroll(Widget_Data *wd)
3821 Elm_Gen_Item *tmp_item = NULL;
3823 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3825 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3826 if (!tmp_item) return;
3827 wd->show_item = tmp_item;
3828 wd->bring_in = EINA_TRUE;
3829 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3830 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3832 wd->show_item->item->showme = EINA_TRUE;
3833 wd->auto_scroll_enabled = EINA_FALSE;
3841 elm_genlist_add(Evas_Object *parent)
3846 Evas_Coord minw, minh;
3847 static Evas_Smart *smart = NULL;
3851 static Evas_Smart_Class sc;
3853 evas_object_smart_clipped_smart_set(&_pan_sc);
3855 sc.name = "elm_genlist_pan";
3856 sc.version = EVAS_SMART_CLASS_VERSION;
3859 sc.resize = _pan_resize;
3860 sc.move = _pan_move;
3861 sc.calculate = _pan_calculate;
3862 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3865 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3867 ELM_SET_WIDTYPE(widtype, "genlist");
3869 elm_widget_type_set(obj, "genlist");
3870 elm_widget_sub_object_add(parent, obj);
3871 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3872 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3873 elm_widget_data_set(obj, wd);
3874 elm_widget_del_hook_set(obj, _del_hook);
3875 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3876 elm_widget_theme_hook_set(obj, _theme_hook);
3877 elm_widget_can_focus_set(obj, EINA_TRUE);
3878 elm_widget_event_hook_set(obj, _event_hook);
3879 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3880 elm_widget_translate_hook_set(obj, _translate_hook);
3883 wd->scr = elm_smart_scroller_add(e);
3884 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_DOWN,
3885 _mouse_down_scroller, obj);
3886 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_UP,
3887 _mouse_up_scroller, obj);
3888 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_MOVE,
3889 _mouse_move_scroller, obj);
3890 elm_smart_scroller_widget_set(wd->scr, obj);
3891 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3892 elm_widget_style_get(obj));
3893 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3894 _elm_config->thumbscroll_bounce_enable);
3895 elm_widget_resize_object_set(obj, wd->scr);
3897 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3898 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3899 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3900 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3901 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3902 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3903 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3904 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3907 wd->mode = ELM_LIST_SCROLL;
3908 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3909 wd->item_cache_max = wd->max_items_per_block * 2;
3910 wd->longpress_timeout = _elm_config->longpress_timeout;
3911 wd->highlight = EINA_TRUE;
3912 wd->tree_effect_enabled = _elm_config->effect_enable;
3914 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3915 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3916 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3917 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3919 wd->pan_smart = evas_object_smart_add(e, smart);
3920 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3923 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3924 _pan_set, _pan_get, _pan_max_get,
3925 _pan_min_get, _pan_child_size_get);
3927 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3929 evas_object_size_hint_min_set(obj, minw, minh);
3931 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3933 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3939 _item_select(Elm_Gen_Item *it)
3944 if ((it->generation < it->wd->generation) || (it->mode_set) ||
3945 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3946 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3950 it->selected = EINA_TRUE;
3951 it->wd->selected = eina_list_append(it->wd->selected, it);
3953 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3955 evas_object_ref(WIDGET(it));
3958 if (it->wd->last_selected_item &&
3959 (it != (Elm_Gen_Item *) it->wd->last_selected_item))
3961 EINA_LIST_FOREACH(((Elm_Gen_Item *)it->wd->last_selected_item)->content_objs, l, obj)
3963 elm_widget_focused_object_clear(obj);
3964 elm_widget_tree_unfocusable_set(obj, EINA_TRUE);
3966 ((Elm_Gen_Item *)it->wd->last_selected_item)->can_focus = EINA_FALSE;
3968 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3969 if (it->generation == it->wd->generation)
3970 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3973 if ((it->wd->clear_me) && (!it->wd->walking))
3974 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3977 if ((!it->walking) && (it->generation < it->wd->generation))
3982 elm_widget_item_free(it);
3986 it->wd->last_selected_item = (Elm_Object_Item *)it;
3988 evas_object_unref(WIDGET(it));
3991 static Evas_Object *
3992 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3994 return edje_object_part_swallow_get(VIEW(it), part);
3998 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
4000 if (content && part)
4002 it->content_objs = eina_list_append(it->content_objs, content);
4003 edje_object_part_swallow(VIEW(it), part, content);
4007 static Evas_Object *
4008 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
4011 obj = edje_object_part_swallow_get(VIEW(it), part);
4012 if (!obj) return NULL;
4013 it->content_objs = eina_list_remove(it->content_objs, obj);
4014 edje_object_part_unswallow(VIEW(it), obj);
4019 _item_text_hook(Elm_Gen_Item *it, const char *part)
4021 if (!it->itc->func.text_get) return NULL;
4022 return edje_object_part_text_get(VIEW(it), part);
4026 _item_disable_hook(Elm_Object_Item *it)
4030 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4032 if (_it->generation < _it->wd->generation) return;
4035 elm_genlist_item_selected_set(it, EINA_FALSE);
4039 if (elm_widget_item_disabled_get(it))
4041 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
4043 edje_object_signal_emit(_it->edit_obj, "elm,state,disabled", "elm");
4047 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
4049 edje_object_signal_emit(_it->edit_obj, "elm,state,enabled", "elm");
4051 EINA_LIST_FOREACH(_it->content_objs, l, obj)
4052 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
4057 _item_del_pre_hook(Elm_Object_Item *it)
4059 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4061 if ((_it->relcount > 0) || (_it->walking > 0))
4063 elm_genlist_item_subitems_clear(it);
4064 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
4065 _elm_genlist_item_del_notserious(_it);
4066 if (_it->item->block)
4068 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
4069 _it->item->block->changed = EINA_TRUE;
4070 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
4071 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
4075 _it->parent->item->items =
4076 eina_list_remove(_it->parent->item->items, it);
4086 _item_signal_emit_hook(Elm_Object_Item *it,
4087 const char *emission,
4090 edje_object_signal_emit(VIEW(it), emission, source);
4094 _elm_genlist_item_new(Widget_Data *wd,
4095 const Elm_Gen_Item_Class *itc,
4097 Elm_Gen_Item *parent,
4099 const void *func_data)
4103 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
4104 if (!it) return NULL;
4106 it->generation = wd->generation;
4108 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
4109 it->base.data = data;
4110 it->parent = parent;
4111 it->func.func = func;
4112 it->func.data = func_data;
4113 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
4114 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
4115 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
4116 elm_widget_item_text_get_hook_set(it, _item_text_hook);
4117 elm_widget_item_disable_hook_set(it, _item_disable_hook);
4118 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
4119 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
4122 it->sel_cb = (Ecore_Cb)_item_select;
4127 static Elm_Gen_Item *
4128 _item_new(Widget_Data *wd,
4129 const Elm_Genlist_Item_Class *itc,
4131 Elm_Gen_Item *parent,
4132 Elm_Genlist_Item_Type type,
4134 const void *func_data)
4136 Elm_Gen_Item *it, *it2;
4139 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
4140 if (!it) return NULL;
4141 it->item = ELM_NEW(Elm_Gen_Item_Type);
4142 it->item->type = type;
4143 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
4144 it->item->expanded_depth = 0;
4145 ELM_GEN_ITEM_SETUP(it);
4146 it->mouse_cursor = NULL;
4147 it->can_focus = EINA_TRUE;
4150 if (it->parent->group)
4151 it->item->group_item = parent;
4152 else if (it->parent->item->group_item)
4153 it->item->group_item = it->parent->item->group_item;
4155 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
4157 if (!it2->parent->group) depth += 1;
4159 it->item->expanded_depth = depth;
4165 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
4169 itb = calloc(1, sizeof(Item_Block));
4170 if (!itb) return NULL;
4174 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
4175 _item_block_position_update(wd->blocks, 0);
4179 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4180 itb->position_update = EINA_TRUE;
4181 if (wd->blocks != EINA_INLIST_GET(itb))
4183 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4194 _item_block_add(Widget_Data *wd,
4197 Item_Block *itb = NULL;
4204 itb = calloc(1, sizeof(Item_Block));
4205 if (!itb) return EINA_FALSE;
4207 if (!it->item->rel->item->block)
4210 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
4211 itb->items = eina_list_append(itb->items, it);
4212 itb->position_update = EINA_TRUE;
4213 it->position = eina_list_count(itb->items);
4214 it->position_update = EINA_TRUE;
4216 if (wd->blocks != EINA_INLIST_GET(itb))
4218 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
4229 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4230 if (it->item->before)
4232 wd->blocks = eina_inlist_prepend_relative
4233 (wd->blocks, EINA_INLIST_GET(itb),
4234 EINA_INLIST_GET(it->item->rel->item->block));
4236 eina_list_prepend_relative_list(itb->items, it, tmp);
4238 /* Update index from where we prepended */
4239 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4240 _item_block_position_update(EINA_INLIST_GET(itb),
4241 it->item->rel->item->block->position);
4245 wd->blocks = eina_inlist_append_relative
4246 (wd->blocks, EINA_INLIST_GET(itb),
4247 EINA_INLIST_GET(it->item->rel->item->block));
4249 eina_list_append_relative_list(itb->items, it, tmp);
4251 /* Update block index from where we appended */
4252 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4253 _item_block_position_update(EINA_INLIST_GET(itb),
4254 it->item->rel->item->block->position + 1);
4260 if (it->item->before)
4264 itb = (Item_Block *)(wd->blocks);
4265 if (itb->count >= wd->max_items_per_block)
4267 itb = _item_block_new(wd, EINA_TRUE);
4268 if (!itb) return EINA_FALSE;
4273 itb = _item_block_new(wd, EINA_TRUE);
4274 if (!itb) return EINA_FALSE;
4276 itb->items = eina_list_prepend(itb->items, it);
4278 _item_position_update(itb->items, 0);
4284 itb = (Item_Block *)(wd->blocks->last);
4285 if (itb->count >= wd->max_items_per_block)
4287 itb = _item_block_new(wd, EINA_FALSE);
4288 if (!itb) return EINA_FALSE;
4293 itb = _item_block_new(wd, EINA_FALSE);
4294 if (!itb) return EINA_FALSE;
4296 itb->items = eina_list_append(itb->items, it);
4297 it->position = eina_list_count(itb->items);
4305 if (it->item->rel->item->queued)
4307 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
4308 on sorted insertion order, so the queue is not always ordered like the item list.
4309 This lead to issue where we depend on an item that is not yet created. As a quick
4310 work around, we reschedule the calc of the item and stop reordering the list to
4311 prevent any nasty issue to show up here.
4313 wd->queue = eina_list_append(wd->queue, it);
4314 wd->requeued = EINA_TRUE;
4315 it->item->queued = EINA_TRUE;
4318 itb = it->item->rel->item->block;
4319 if (!itb) goto newblock;
4320 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4321 if (it->item->before)
4323 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4324 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
4328 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4329 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
4333 itb->changed = EINA_TRUE;
4334 it->item->block = itb;
4335 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
4336 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
4339 it->item->rel->relcount--;
4340 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
4342 _item_del(it->item->rel);
4343 elm_widget_item_free(it->item->rel);
4345 it->item->rel = NULL;
4347 if (itb->count > itb->wd->max_items_per_block)
4352 Eina_Bool done = EINA_FALSE;
4354 newc = itb->count / 2;
4356 if (EINA_INLIST_GET(itb)->prev)
4358 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4360 if (itbp->count + newc < wd->max_items_per_block / 2)
4362 /* moving items to previous block */
4363 while ((itb->count > newc) && (itb->items))
4365 it2 = eina_list_data_get(itb->items);
4366 itb->items = eina_list_remove_list(itb->items, itb->items);
4369 itbp->items = eina_list_append(itbp->items, it2);
4370 it2->item->block = itbp;
4378 if (!done && EINA_INLIST_GET(itb)->next)
4380 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4382 if (itbn->count + newc < wd->max_items_per_block / 2)
4384 /* moving items to next block */
4385 while ((itb->count > newc) && (itb->items))
4389 l = eina_list_last(itb->items);
4390 it2 = eina_list_data_get(l);
4391 itb->items = eina_list_remove_list(itb->items, l);
4394 itbn->items = eina_list_prepend(itbn->items, it2);
4395 it2->item->block = itbn;
4405 /* moving items to new block */
4406 itb2 = calloc(1, sizeof(Item_Block));
4407 if (!itb2) return EINA_FALSE;
4410 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
4411 EINA_INLIST_GET(itb));
4412 itb2->changed = EINA_TRUE;
4413 while ((itb->count > newc) && (itb->items))
4417 l = eina_list_last(itb->items);
4419 itb->items = eina_list_remove_list(itb->items, l);
4422 itb2->items = eina_list_prepend(itb2->items, it2);
4423 it2->item->block = itb2;
4433 _queue_process(Widget_Data *wd)
4436 Eina_Bool showme = EINA_FALSE;
4439 t0 = ecore_loop_time_get();
4440 //evas_event_freeze(evas_object_evas_get(wd->obj));
4441 for (n = 0; (wd->queue) && (n < 128); n++)
4445 it = eina_list_data_get(wd->queue);
4446 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4447 it->item->queued = EINA_FALSE;
4448 if (!_item_block_add(wd, it)) continue;
4450 _item_block_realize(it->item->block);
4451 t = ecore_time_get();
4452 if (it->item->block->changed)
4454 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4455 it->item->block->changed = 0;
4456 if (wd->pan_changed)
4458 if (wd->calc_job) ecore_job_del(wd->calc_job);
4459 wd->calc_job = NULL;
4461 wd->pan_changed = EINA_FALSE;
4464 if (showme) it->item->block->showme = EINA_TRUE;
4465 /* same as eina_inlist_count > 1 */
4466 if (wd->blocks && wd->blocks->next)
4468 if ((t - t0) > (ecore_animator_frametime_get())) break;
4471 //evas_event_thaw(evas_object_evas_get(wd->obj));
4472 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4477 _idle_process(void *data, Eina_Bool *wakeup)
4479 Widget_Data *wd = data;
4482 //static double q_start = 0.0;
4483 //if (q_start == 0.0) q_start = ecore_time_get();
4485 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4489 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4491 return ECORE_CALLBACK_CANCEL;
4493 return ECORE_CALLBACK_RENEW;
4497 _item_idle_enterer(void *data)
4499 Widget_Data *wd = data;
4500 Eina_Bool wakeup = EINA_FALSE;
4501 Eina_Bool ok = _idle_process(data, &wakeup);
4506 if (wd->calc_job) ecore_job_del(wd->calc_job);
4507 wd->calc_job = ecore_job_add(_calc_job, wd);
4509 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4514 _item_queue(Widget_Data *wd,
4518 if (it->item->queued) return;
4519 it->item->queued = EINA_TRUE;
4520 if (cb && !wd->requeued)
4521 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4523 wd->queue = eina_list_append(wd->queue, it);
4524 // FIXME: why does a freeze then thaw here cause some genlist
4525 // elm_genlist_item_append() to be much much slower?
4526 // evas_event_freeze(evas_object_evas_get(wd->obj));
4527 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4529 if (wd->queue_idle_enterer)
4531 ecore_idle_enterer_del(wd->queue_idle_enterer);
4532 wd->queue_idle_enterer = NULL;
4536 // evas_event_thaw(evas_object_evas_get(wd->obj));
4537 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4538 if (!wd->queue_idle_enterer)
4539 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4543 _elm_genlist_item_compare(const void *data, const void *data1)
4545 const Elm_Gen_Item *it, *item1;
4546 it = ELM_GEN_ITEM_FROM_INLIST(data);
4547 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4548 return it->wd->item_compare_cb(it, item1);
4552 _elm_genlist_item_list_compare(const void *data, const void *data1)
4554 const Elm_Gen_Item *it = data;
4555 const Elm_Gen_Item *item1 = data1;
4556 return it->wd->item_compare_cb(it, item1);
4559 /*If application want to know the relative item, use elm_genlist_item_prev_get(it)*/
4561 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4566 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4567 _item_block_del(it);
4569 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4570 it->item->rel = after;
4571 it->item->rel->relcount++;
4572 it->item->before = EINA_FALSE;
4573 if (after->item->group_item) it->item->group_item = after->item->group_item;
4574 _item_queue(it->wd, it, NULL);
4576 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, it);
4579 /*If application want to know the relative item, use elm_genlist_item_next_get(it)*/
4581 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4584 if (!before) return;
4586 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4587 _item_block_del(it);
4588 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4589 it->item->rel = before;
4590 it->item->rel->relcount++;
4591 it->item->before = EINA_TRUE;
4592 if (before->item->group_item) it->item->group_item = before->item->group_item;
4593 _item_queue(it->wd, it, NULL);
4595 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, it);
4599 elm_genlist_items_count(const Evas_Object *obj)
4601 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4602 Widget_Data *wd = elm_widget_data_get(obj);
4604 return wd->item_count;
4607 EAPI Elm_Object_Item *
4608 elm_genlist_item_append(Evas_Object *obj,
4609 const Elm_Genlist_Item_Class *itc,
4611 Elm_Object_Item *parent,
4612 Elm_Genlist_Item_Type type,
4614 const void *func_data)
4616 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4617 Widget_Data *wd = elm_widget_data_get(obj);
4618 if (!wd) return NULL;
4619 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4621 if (!it) return NULL;
4625 wd->group_items = eina_list_append(wd->group_items, it);
4626 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4627 it->item->rel = NULL;
4631 Elm_Gen_Item *it2 = NULL;
4632 Eina_List *ll = eina_list_last(it->parent->item->items);
4633 if (ll) it2 = ll->data;
4634 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4635 if (!it2) it2 = it->parent;
4637 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4638 EINA_INLIST_GET(it2));
4639 it->item->rel = it2;
4640 it->item->rel->relcount++;
4642 it->item->before = EINA_FALSE;
4643 _item_queue(wd, it, NULL);
4644 return (Elm_Object_Item *)it;
4647 EAPI Elm_Object_Item *
4648 elm_genlist_item_prepend(Evas_Object *obj,
4649 const Elm_Genlist_Item_Class *itc,
4651 Elm_Object_Item *parent,
4652 Elm_Genlist_Item_Type type,
4654 const void *func_data)
4656 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4657 Widget_Data *wd = elm_widget_data_get(obj);
4658 if (!wd) return NULL;
4659 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4661 if (!it) return NULL;
4665 wd->group_items = eina_list_prepend(wd->group_items, it);
4666 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4667 it->item->rel = NULL;
4671 Elm_Gen_Item *it2 = NULL;
4672 Eina_List *ll = it->parent->item->items;
4673 if (ll) it2 = ll->data;
4674 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4675 if (!it2) it2 = it->parent;
4677 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4678 EINA_INLIST_GET(it2));
4679 it->item->rel = it2;
4680 it->item->rel->relcount++;
4682 it->item->before = EINA_TRUE;
4683 _item_queue(wd, it, NULL);
4684 return (Elm_Object_Item *)it;
4687 EAPI Elm_Object_Item *
4688 elm_genlist_item_insert_after(Evas_Object *obj,
4689 const Elm_Genlist_Item_Class *itc,
4691 Elm_Object_Item *parent,
4692 Elm_Object_Item *after,
4693 Elm_Genlist_Item_Type type,
4695 const void *func_data)
4697 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4698 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4699 Widget_Data *wd = elm_widget_data_get(obj);
4700 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4701 if (!wd) return NULL;
4702 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4703 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4705 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4707 if (!it) return NULL;
4710 if ((it->group) && (_after->group))
4711 wd->group_items = eina_list_append_relative(wd->group_items, it,
4716 it->parent->item->items =
4717 eina_list_append_relative(it->parent->item->items, it, _after);
4719 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4720 EINA_INLIST_GET(_after));
4721 it->item->rel = _after;
4722 it->item->rel->relcount++;
4723 it->item->before = EINA_FALSE;
4724 _item_queue(wd, it, NULL);
4725 return (Elm_Object_Item *)it;
4728 EAPI Elm_Object_Item *
4729 elm_genlist_item_insert_before(Evas_Object *obj,
4730 const Elm_Genlist_Item_Class *itc,
4732 Elm_Object_Item *parent,
4733 Elm_Object_Item *before,
4734 Elm_Genlist_Item_Type type,
4736 const void *func_data)
4738 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4739 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4740 Widget_Data *wd = elm_widget_data_get(obj);
4741 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4742 if (!wd) return NULL;
4743 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4744 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4746 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4748 if (!it) return NULL;
4751 if (it->group && _before->group)
4752 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4757 it->parent->item->items =
4758 eina_list_prepend_relative(it->parent->item->items, it, _before);
4760 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4761 EINA_INLIST_GET(_before));
4762 it->item->rel = _before;
4763 it->item->rel->relcount++;
4764 it->item->before = EINA_TRUE;
4765 _item_queue(wd, it, NULL);
4766 return (Elm_Object_Item *)it;
4769 EAPI Elm_Object_Item *
4770 elm_genlist_item_sorted_insert(Evas_Object *obj,
4771 const Elm_Genlist_Item_Class *itc,
4773 Elm_Object_Item *parent,
4774 Elm_Genlist_Item_Type type,
4775 Eina_Compare_Cb comp,
4777 const void *func_data)
4779 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4780 Widget_Data *wd = elm_widget_data_get(obj);
4781 if (!wd) return NULL;
4782 Elm_Gen_Item *rel = NULL;
4783 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4785 if (!it) return NULL;
4787 wd->item_compare_cb = comp;
4794 l = eina_list_search_sorted_near_list(it->parent->item->items,
4795 _elm_genlist_item_list_compare,
4799 rel = eina_list_data_get(l);
4803 if (cmp_result >= 0)
4805 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4806 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4807 it->item->before = EINA_FALSE;
4809 else if (cmp_result < 0)
4811 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4812 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4813 it->item->before = EINA_TRUE;
4820 wd->state = eina_inlist_sorted_state_new();
4821 eina_inlist_sorted_state_init(wd->state, wd->items);
4822 wd->requeued = EINA_FALSE;
4826 wd->group_items = eina_list_append(wd->group_items, it);
4828 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4829 _elm_genlist_item_compare, wd->state);
4831 if (EINA_INLIST_GET(it)->next)
4833 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4834 it->item->before = EINA_TRUE;
4836 else if (EINA_INLIST_GET(it)->prev)
4838 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4839 it->item->before = EINA_FALSE;
4845 it->item->rel = rel;
4846 it->item->rel->relcount++;
4849 _item_queue(wd, it, _elm_genlist_item_list_compare);
4851 return (Elm_Object_Item *)it;
4855 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4857 Eina_Inlist *next, *l;
4858 Widget_Data *wd = elm_widget_data_get(obj);
4861 if (!standby) wd->generation++;
4865 eina_inlist_sorted_state_free(wd->state);
4869 if (wd->walking > 0)
4871 wd->clear_me = EINA_TRUE;
4874 evas_event_freeze(evas_object_evas_get(wd->obj));
4875 for (l = wd->items, next = l ? l->next : NULL;
4877 l = next, next = next ? next->next : NULL)
4879 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4881 if (it->generation < wd->generation)
4883 Elm_Gen_Item *itn = NULL;
4885 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4886 if (itn) itn->walking++; /* prevent early death of subitem */
4888 elm_widget_item_free(it);
4889 if (itn) itn->walking--;
4892 wd->clear_me = EINA_FALSE;
4893 wd->pan_changed = EINA_TRUE;
4896 ecore_job_del(wd->calc_job);
4897 wd->calc_job = NULL;
4899 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4900 if (wd->clear_cb) wd->clear_cb(wd);
4906 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4907 wd->alpha_bg = NULL;
4911 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4912 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4914 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4915 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4916 evas_event_thaw(evas_object_evas_get(wd->obj));
4917 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4921 elm_genlist_clear(Evas_Object *obj)
4923 ELM_CHECK_WIDTYPE(obj, widtype);
4924 _elm_genlist_clear(obj, EINA_FALSE);
4928 elm_genlist_multi_select_set(Evas_Object *obj,
4931 ELM_CHECK_WIDTYPE(obj, widtype);
4932 Widget_Data *wd = elm_widget_data_get(obj);
4934 wd->multi = !!multi;
4938 elm_genlist_multi_select_get(const Evas_Object *obj)
4940 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4941 Widget_Data *wd = elm_widget_data_get(obj);
4942 if (!wd) return EINA_FALSE;
4946 EAPI Elm_Object_Item *
4947 elm_genlist_selected_item_get(const Evas_Object *obj)
4949 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4950 Widget_Data *wd = elm_widget_data_get(obj);
4951 if (!wd) return NULL;
4952 if (wd->selected) return wd->selected->data;
4956 EAPI const Eina_List *
4957 elm_genlist_selected_items_get(const Evas_Object *obj)
4959 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4960 Widget_Data *wd = elm_widget_data_get(obj);
4961 if (!wd) return NULL;
4962 return wd->selected;
4966 elm_genlist_realized_items_get(const Evas_Object *obj)
4968 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4969 Widget_Data *wd = elm_widget_data_get(obj);
4970 Eina_List *list = NULL;
4972 Eina_Bool done = EINA_FALSE;
4973 if (!wd) return NULL;
4974 EINA_INLIST_FOREACH(wd->blocks, itb)
4982 EINA_LIST_FOREACH(itb->items, l, it)
4984 if (it->realized) list = eina_list_append(list, it);
4995 EAPI Elm_Object_Item *
4996 elm_genlist_at_xy_item_get(const Evas_Object *obj,
5001 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5002 Widget_Data *wd = elm_widget_data_get(obj);
5003 Evas_Coord ox, oy, ow, oh;
5006 if (!wd) return NULL;
5007 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5009 EINA_INLIST_FOREACH(wd->blocks, itb)
5014 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
5015 oy + itb->y - itb->wd->pan_y,
5016 itb->w, itb->h, x, y, 1, 1))
5018 EINA_LIST_FOREACH(itb->items, l, it)
5020 Evas_Coord itx, ity;
5022 itx = ox + itb->x + it->x - itb->wd->pan_x;
5023 ity = oy + itb->y + it->y - itb->wd->pan_y;
5024 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
5028 if (y <= (ity + (it->item->h / 4))) *posret = -1;
5029 else if (y >= (ity + it->item->h - (it->item->h / 4)))
5033 return (Elm_Object_Item *)it;
5035 lasty = ity + it->item->h;
5040 if (y > lasty) *posret = 1;
5046 EAPI Elm_Object_Item *
5047 elm_genlist_first_item_get(const Evas_Object *obj)
5049 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5050 Widget_Data *wd = elm_widget_data_get(obj);
5051 if (!wd) return NULL;
5052 if (!wd->items) return NULL;
5053 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
5054 while ((it) && (it->generation < wd->generation))
5055 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
5056 return (Elm_Object_Item *)it;
5059 EAPI Elm_Object_Item *
5060 elm_genlist_last_item_get(const Evas_Object *obj)
5062 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5063 Widget_Data *wd = elm_widget_data_get(obj);
5064 if (!wd) return NULL;
5065 if (!wd->items) return NULL;
5066 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
5067 while ((it) && (it->generation < wd->generation))
5068 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
5069 return (Elm_Object_Item *)it;
5072 EAPI Elm_Object_Item *
5073 elm_genlist_item_next_get(const Elm_Object_Item *it)
5075 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5076 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5079 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
5080 if ((_it) && (_it->generation == _it->wd->generation)) break;
5082 return (Elm_Object_Item *) _it;
5085 EAPI Elm_Object_Item *
5086 elm_genlist_item_prev_get(const Elm_Object_Item *it)
5088 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5089 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5092 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
5093 if ((_it) && (_it->generation == _it->wd->generation)) break;
5095 return (Elm_Object_Item *) _it;
5098 EAPI Elm_Object_Item *
5099 elm_genlist_item_parent_get(const Elm_Object_Item *it)
5101 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5102 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
5106 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
5108 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5109 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
5111 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5113 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
5114 _item_subitems_clear(_it);
5117 if (!wd->tree_effect_animator)
5119 wd->expanded_item = _it;
5120 _item_tree_effect_before(_it);
5121 evas_object_raise(wd->alpha_bg);
5122 evas_object_show(wd->alpha_bg);
5123 wd->start_time = ecore_time_get();
5124 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
5127 _item_subitems_clear(_it);
5132 elm_genlist_item_selected_set(Elm_Object_Item *it,
5135 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5136 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5137 Widget_Data *wd = _it->wd;
5139 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
5141 selected = !!selected;
5142 if (_it->selected == selected) return;
5148 while (wd->selected)
5150 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
5151 _it->unsel_cb(wd->selected->data);
5154 _it->highlight_cb(_it);
5158 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
5163 elm_genlist_item_selected_get(const Elm_Object_Item *it)
5165 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5166 return ((Elm_Gen_Item *)it)->selected;
5170 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
5173 if (it->item->expanded)
5175 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5179 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
5182 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
5183 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5190 _elm_genlist_move_items_set(Elm_Gen_Item *it)
5193 Elm_Gen_Item *it2 = NULL;
5194 Evas_Coord ox, oy, ow, oh, dh = 0;
5196 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
5198 if (it->item->expanded)
5200 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
5201 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
5203 if (it2 == it->wd->expanded_next_item) break;
5204 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
5209 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
5210 it2 = it->wd->expanded_next_item;
5211 while (it2 && (dh < oy + oh))
5214 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
5215 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
5221 elm_genlist_item_expanded_set(Elm_Object_Item *it,
5224 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5225 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5226 expanded = !!expanded;
5227 if (_it->item->expanded == expanded) return;
5228 _it->item->expanded = expanded;
5229 _it->wd->expanded_item = _it;
5230 _elm_genlist_move_items_set(_it);
5232 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
5233 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
5235 if (_it->item->expanded)
5237 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
5239 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
5240 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
5241 _it->wd->auto_scroll_enabled = EINA_TRUE;
5245 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
5247 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
5248 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
5249 _it->wd->auto_scroll_enabled = EINA_FALSE;
5254 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
5256 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5257 return ((Elm_Gen_Item *)it)->item->expanded;
5261 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
5263 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
5264 return ((Elm_Gen_Item *)it)->item->expanded_depth;
5267 EINA_DEPRECATED EAPI void
5268 elm_genlist_item_display_only_set(Elm_Object_Item *it,
5269 Eina_Bool display_only)
5271 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5272 display_only = !!display_only;
5275 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
5278 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5279 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5280 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
5284 EINA_DEPRECATED EAPI Eina_Bool
5285 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
5287 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5288 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5289 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5290 Elm_Object_Select_Mode oldmode = elm_genlist_item_select_mode_get(it);
5291 if (oldmode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5297 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
5298 Elm_Genlist_Item_Scrollto_Type type,
5304 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5305 Evas_Coord gith = 0;
5306 if (_it->generation < _it->wd->generation) return EINA_FALSE;
5307 if ((_it->item->queued) || (!_it->item->mincalcd))
5309 _it->wd->show_item = _it;
5310 _it->wd->bring_in = EINA_FALSE;
5311 _it->wd->scrollto_type = type;
5312 _it->item->showme = EINA_TRUE;
5315 if (_it->wd->show_item)
5317 _it->wd->show_item->item->showme = EINA_FALSE;
5318 _it->wd->show_item = NULL;
5321 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
5322 if (type==ELM_GENLIST_ITEM_SCROLLTO_IN)
5324 if ((_it->item->group_item) &&
5325 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
5326 gith = _it->item->group_item->item->h;
5329 *y = _it->y + _it->item->block->y - gith;
5331 else if (type==ELM_GENLIST_ITEM_SCROLLTO_TOP)
5333 if (_it->item->group_item) gith = _it->item->group_item->item->h;
5334 *y = _it->y + _it->item->block->y - gith;
5336 else if (type==ELM_GENLIST_ITEM_SCROLLTO_MIDDLE)
5338 *y = _it->y + _it->item->block->y - *h / 2 + _it->item->h / 2;
5343 *x = _it->x + _it->item->block->x;
5344 *w = _it->item->block->w;
5349 elm_genlist_item_promote(Elm_Object_Item *it)
5351 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5352 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5353 if (_it->generation < _it->wd->generation) return;
5354 _item_move_before(_it,
5355 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
5359 elm_genlist_item_demote(Elm_Object_Item *it)
5361 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5362 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5363 if (_it->generation < _it->wd->generation) return;
5364 _item_move_after(_it,
5365 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
5369 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5371 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5372 Evas_Coord x, y, w, h;
5373 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5375 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
5376 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
5380 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
5383 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5384 Evas_Coord x, y, w, h;
5385 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5387 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
5388 elm_smart_scroller_region_bring_in(_it->wd->scr,x, y, w, h);
5392 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
5394 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5396 Evas_Object *content;
5397 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
5399 elm_widget_sub_object_del(WIDGET(it), content);
5400 evas_object_smart_member_del(content);
5401 evas_object_hide(content);
5403 *l = eina_list_append(*l, content);
5408 elm_genlist_item_update(Elm_Object_Item *it)
5410 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5411 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5413 if (!_it->item->block) return;
5414 if (_it->generation < _it->wd->generation) return;
5415 _it->item->mincalcd = EINA_FALSE;
5416 _it->item->updateme = EINA_TRUE;
5417 _it->item->block->updateme = EINA_TRUE;
5418 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5419 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5423 elm_genlist_item_fields_update(Elm_Object_Item *it,
5425 Elm_Genlist_Item_Field_Type itf)
5427 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5428 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5430 if (!_it->item->block) return;
5431 if (_it->generation < _it->wd->generation) return;
5433 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5434 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5435 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5437 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5438 &_it->contents, parts);
5439 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5440 &_it->contents, parts);
5444 _it->content_objs = _item_mode_content_unrealize(_it, VIEW(_it),
5445 &_it->contents, parts, &_it->content_objs, "flips");
5446 _it->content_objs = _item_mode_content_realize(_it, VIEW(_it),
5447 &_it->contents, parts, &_it->content_objs, "flips");
5450 if (_it->item->mode_view)
5452 _it->item->mode_content_objs = _item_mode_content_unrealize(_it, _it->item->mode_view,
5453 &_it->item->mode_contents, parts, &_it->item->mode_content_objs, "contents");
5454 _it->item->mode_content_objs = _item_mode_content_realize(_it, _it->item->mode_view,
5455 &_it->item->mode_contents, parts, &_it->item->mode_content_objs, "contents");
5458 if (_it->wd->decorate_mode)
5460 _it->item->edit_content_objs = _item_mode_content_unrealize(_it, _it->edit_obj,
5461 &_it->contents, parts, &_it->item->edit_content_objs, "decorate_contents");
5462 _it->item->edit_content_objs = _item_mode_content_realize(_it, _it->edit_obj,
5463 &_it->contents, parts, &_it->item->edit_content_objs, "decorate_contents"); // FIXME: is it "decorate_contents"??
5466 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5467 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5471 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5472 const Elm_Genlist_Item_Class *itc)
5474 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5475 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5477 if (!_it->item->block) return;
5478 EINA_SAFETY_ON_NULL_RETURN(itc);
5479 if (_it->generation < _it->wd->generation) return;
5481 _it->item->nocache_once = EINA_TRUE;
5482 elm_genlist_item_update(it);
5485 EAPI const Elm_Genlist_Item_Class *
5486 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5488 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5489 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5490 if (_it->generation < _it->wd->generation) return NULL;
5494 static Evas_Object *
5495 _elm_genlist_item_label_create(void *data,
5496 Evas_Object *obj __UNUSED__,
5497 Evas_Object *tooltip,
5498 void *it __UNUSED__)
5500 Evas_Object *label = elm_label_add(tooltip);
5503 elm_object_style_set(label, "tooltip");
5504 elm_object_text_set(label, data);
5509 _elm_genlist_item_label_del_cb(void *data,
5510 Evas_Object *obj __UNUSED__,
5511 void *event_info __UNUSED__)
5513 eina_stringshare_del(data);
5517 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5520 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5521 text = eina_stringshare_add(text);
5522 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5524 _elm_genlist_item_label_del_cb);
5528 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5529 Elm_Tooltip_Item_Content_Cb func,
5531 Evas_Smart_Cb del_cb)
5533 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5534 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5536 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5539 if (_it->tooltip.del_cb)
5540 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5542 _it->tooltip.content_cb = func;
5543 _it->tooltip.data = data;
5544 _it->tooltip.del_cb = del_cb;
5548 elm_widget_item_tooltip_content_cb_set(_it,
5549 _it->tooltip.content_cb,
5550 _it->tooltip.data, NULL);
5551 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5552 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5558 if (del_cb) del_cb((void *)data, NULL, NULL);
5562 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5564 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5565 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5567 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5568 elm_widget_item_tooltip_unset(_it);
5570 if (_it->tooltip.del_cb)
5571 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5572 _it->tooltip.del_cb = NULL;
5573 _it->tooltip.content_cb = NULL;
5574 _it->tooltip.data = NULL;
5575 _it->tooltip.free_size = EINA_FALSE;
5576 if (_it->tooltip.style)
5577 elm_genlist_item_tooltip_style_set(it, NULL);
5581 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5584 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5585 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5587 eina_stringshare_replace(&_it->tooltip.style, style);
5588 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5592 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5594 return elm_object_item_tooltip_style_get(it);
5598 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5601 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5602 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5604 _it->tooltip.free_size = disable;
5605 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5610 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5612 return elm_object_tooltip_window_mode_get(VIEW(it));
5616 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5619 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5620 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5621 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5622 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5626 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5628 return elm_widget_item_cursor_get(it);
5632 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5634 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5635 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5637 if (!_it->mouse_cursor) return;
5639 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5641 eina_stringshare_del(_it->mouse_cursor);
5642 _it->mouse_cursor = NULL;
5646 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5649 elm_widget_item_cursor_style_set(it, style);
5653 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5655 return elm_widget_item_cursor_style_get(it);
5659 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5660 Eina_Bool engine_only)
5662 elm_widget_item_cursor_engine_only_set(it, engine_only);
5666 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5668 return elm_widget_item_cursor_engine_only_get(it);
5672 elm_genlist_item_index_get(const Elm_Object_Item *it)
5674 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5675 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5677 if (_it->item->block)
5678 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5683 elm_genlist_mode_set(Evas_Object *obj,
5686 ELM_CHECK_WIDTYPE(obj, widtype);
5687 Widget_Data *wd = elm_widget_data_get(obj);
5689 if (wd->mode == mode) return;
5691 if (wd->mode == ELM_LIST_COMPRESS)
5692 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5698 elm_genlist_mode_get(const Evas_Object *obj)
5700 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5701 Widget_Data *wd = elm_widget_data_get(obj);
5702 if (!wd) return ELM_LIST_LAST;
5707 elm_genlist_bounce_set(Evas_Object *obj,
5711 ELM_CHECK_WIDTYPE(obj, widtype);
5712 Widget_Data *wd = elm_widget_data_get(obj);
5714 wd->h_bounce = !!h_bounce;
5715 wd->v_bounce = !!v_bounce;
5716 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5720 elm_genlist_bounce_get(const Evas_Object *obj,
5721 Eina_Bool *h_bounce,
5722 Eina_Bool *v_bounce)
5724 ELM_CHECK_WIDTYPE(obj, widtype);
5725 Widget_Data *wd = elm_widget_data_get(obj);
5727 if (h_bounce) *h_bounce = wd->h_bounce;
5728 if (v_bounce) *v_bounce = wd->v_bounce;
5732 elm_genlist_homogeneous_set(Evas_Object *obj,
5733 Eina_Bool homogeneous)
5735 ELM_CHECK_WIDTYPE(obj, widtype);
5736 Widget_Data *wd = elm_widget_data_get(obj);
5738 wd->homogeneous = !!homogeneous;
5742 elm_genlist_homogeneous_get(const Evas_Object *obj)
5744 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5745 Widget_Data *wd = elm_widget_data_get(obj);
5746 if (!wd) return EINA_FALSE;
5747 return wd->homogeneous;
5751 elm_genlist_block_count_set(Evas_Object *obj,
5754 ELM_CHECK_WIDTYPE(obj, widtype);
5755 Widget_Data *wd = elm_widget_data_get(obj);
5757 wd->max_items_per_block = count;
5758 wd->item_cache_max = wd->max_items_per_block * 2;
5759 _item_cache_clean(wd);
5763 elm_genlist_block_count_get(const Evas_Object *obj)
5765 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5766 Widget_Data *wd = elm_widget_data_get(obj);
5768 return wd->max_items_per_block;
5772 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5775 ELM_CHECK_WIDTYPE(obj, widtype);
5776 Widget_Data *wd = elm_widget_data_get(obj);
5778 wd->longpress_timeout = timeout;
5782 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5784 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5785 Widget_Data *wd = elm_widget_data_get(obj);
5787 return wd->longpress_timeout;
5791 elm_genlist_scroller_policy_set(Evas_Object *obj,
5792 Elm_Scroller_Policy policy_h,
5793 Elm_Scroller_Policy policy_v)
5795 ELM_CHECK_WIDTYPE(obj, widtype);
5796 Widget_Data *wd = elm_widget_data_get(obj);
5797 if ((!wd) || (!wd->scr)) return;
5798 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5799 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5801 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5805 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5806 Elm_Scroller_Policy *policy_h,
5807 Elm_Scroller_Policy *policy_v)
5809 ELM_CHECK_WIDTYPE(obj, widtype);
5810 Widget_Data *wd = elm_widget_data_get(obj);
5811 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5812 if ((!wd) || (!wd->scr)) return;
5813 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5814 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5815 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5819 elm_genlist_realized_items_update(Evas_Object *obj)
5821 ELM_CHECK_WIDTYPE(obj, widtype);
5823 Eina_List *list, *l;
5824 Elm_Object_Item *it;
5826 list = elm_genlist_realized_items_get(obj);
5827 EINA_LIST_FOREACH(list, l, it)
5828 elm_genlist_item_update(it);
5832 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5833 const char *decorate_type,
5836 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5837 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5839 Widget_Data *wd = _it->wd;
5841 Elm_Object_Item *it2;
5844 if (!decorate_type) return;
5845 if ((_it->generation < _it->wd->generation) ||
5846 elm_widget_item_disabled_get(_it)) return;
5847 if (wd->decorate_mode) return;
5849 if ((wd->mode_item == _it) &&
5850 (!strcmp(decorate_type, wd->decorate_type)) &&
5853 if (!_it->itc->decorate_item_style) return;
5854 _it->mode_set = mode_set;
5858 EINA_LIST_FOREACH(wd->selected, l, it2)
5859 if (((Elm_Gen_Item *)it2)->realized)
5860 elm_genlist_item_selected_set(it2, EINA_FALSE);
5864 it2 = elm_genlist_selected_item_get(wd->obj);
5865 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5866 elm_genlist_item_selected_set(it2, EINA_FALSE);
5869 if (((wd->decorate_type) && (strcmp(decorate_type, wd->decorate_type))) ||
5871 ((_it == wd->mode_item) && (!mode_set)))
5872 _item_mode_unset(wd);
5874 eina_stringshare_replace(&wd->decorate_type, decorate_type);
5875 if (mode_set) _item_mode_set(_it);
5879 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5881 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5882 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5883 return _it->wd->decorate_type;
5886 EAPI const Elm_Object_Item *
5887 elm_genlist_decorated_item_get(const Evas_Object *obj)
5889 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5890 Widget_Data *wd = elm_widget_data_get(obj);
5891 if (!wd) return NULL;
5892 return (Elm_Object_Item *) wd->mode_item;
5896 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5898 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5899 Widget_Data *wd = elm_widget_data_get(obj);
5900 if (!wd) return EINA_FALSE;
5902 return wd->decorate_mode;
5906 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5908 ELM_CHECK_WIDTYPE(obj, widtype);
5909 Eina_List *list, *l;
5912 Widget_Data *wd = elm_widget_data_get(obj);
5914 decorated = !!decorated;
5915 if (wd->decorate_mode == decorated) return;
5916 wd->decorate_mode = decorated;
5918 list = elm_genlist_realized_items_get(obj);
5919 if (!wd->decorate_mode)
5921 EINA_LIST_FOREACH(list, l, it)
5923 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5924 _decorate_mode_item_unrealize(it);
5926 _item_cache_zero(wd);
5930 EINA_LIST_FOREACH(list, l, it)
5932 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5934 if (it->selected) _item_unselect(it);
5935 if (it->itc->decorate_all_item_style)
5936 _decorate_mode_item_realize(it, EINA_TRUE);
5940 if (wd->calc_job) ecore_job_del(wd->calc_job);
5941 wd->calc_job = ecore_job_add(_calc_job, wd);
5945 elm_genlist_reorder_mode_set(Evas_Object *obj,
5946 Eina_Bool reorder_mode)
5948 ELM_CHECK_WIDTYPE(obj, widtype);
5949 Widget_Data *wd = elm_widget_data_get(obj);
5951 wd->reorder_mode = !!reorder_mode;
5955 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5957 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5958 Widget_Data *wd = elm_widget_data_get(obj);
5959 if (!wd) return EINA_FALSE;
5960 return wd->reorder_mode;
5963 EAPI Elm_Genlist_Item_Type
5964 elm_genlist_item_type_get(const Elm_Object_Item *it)
5966 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5967 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5968 return _it->item->type;
5971 EAPI Elm_Genlist_Item_Class *
5972 elm_genlist_item_class_new(void)
5974 Elm_Genlist_Item_Class *itc;
5976 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5979 itc->version = CLASS_ALLOCATED;
5981 itc->delete_me = EINA_FALSE;
5987 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5989 if (itc && (itc->version == CLASS_ALLOCATED))
5991 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5992 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
6002 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
6004 if (itc && (itc->version == CLASS_ALLOCATED))
6007 if (itc->refcount == 0) itc->refcount--;
6012 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
6014 if (itc && (itc->version == CLASS_ALLOCATED))
6016 if (itc->refcount > 0) itc->refcount--;
6017 if (itc->delete_me && (!itc->refcount))
6018 elm_genlist_item_class_free(itc);
6022 void _flip_job(void *data)
6024 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
6025 _elm_genlist_item_unrealize(it, EINA_FALSE);
6026 if (it->selected) _item_unselect(it);
6027 it->flipped = EINA_TRUE;
6028 it->item->nocache = EINA_TRUE;
6032 elm_genlist_item_flip_set(Elm_Object_Item *it,
6035 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6036 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6039 if (_it->flipped == flip) return;
6043 ecore_job_add(_flip_job, _it);
6044 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
6045 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
6049 _it->flipped = flip;
6050 _item_cache_zero(_it->wd);
6051 elm_genlist_item_update(it);
6052 _it->item->nocache = EINA_FALSE;
6057 elm_genlist_item_flip_get(const Elm_Object_Item *it)
6059 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6060 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6061 return _it->flipped;
6065 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
6067 ELM_CHECK_WIDTYPE(obj, widtype);
6068 Widget_Data *wd = elm_widget_data_get(obj);
6070 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6072 if (wd->select_mode != mode)
6073 wd->select_mode = mode;
6076 EAPI Elm_Object_Select_Mode
6077 elm_genlist_select_mode_get(const Evas_Object *obj)
6079 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
6080 Widget_Data *wd = elm_widget_data_get(obj);
6081 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
6082 return wd->select_mode;
6086 elm_genlist_highlight_mode_set(Evas_Object *obj,
6087 Eina_Bool highlight)
6089 ELM_CHECK_WIDTYPE(obj, widtype);
6090 Widget_Data *wd = elm_widget_data_get(obj);
6092 wd->highlight = !!highlight;
6096 elm_genlist_highlight_mode_get(const Evas_Object *obj)
6098 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6099 Widget_Data *wd = elm_widget_data_get(obj);
6100 if (!wd) return EINA_FALSE;
6101 return wd->highlight;
6105 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
6106 Elm_Object_Select_Mode mode)
6108 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
6109 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6111 if (_it->generation < _it->wd->generation) return;
6112 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
6114 if (_it->select_mode != mode)
6115 _it->select_mode = mode;
6117 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
6119 _it->item->mincalcd = EINA_FALSE;
6120 _it->item->updateme = EINA_TRUE;
6121 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
6122 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
6123 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
6127 EAPI Elm_Object_Select_Mode
6128 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
6130 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
6131 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
6132 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
6133 return _it->select_mode;
6136 /* for gengrid as of now */
6138 _elm_genlist_page_relative_set(Evas_Object *obj,
6142 Evas_Coord pagesize_h;
6143 Evas_Coord pagesize_v;
6145 ELM_CHECK_WIDTYPE(obj, widtype);
6146 Widget_Data *wd = elm_widget_data_get(obj);
6149 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
6150 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
6154 /* for gengrid as of now */
6156 _elm_genlist_page_relative_get(const Evas_Object *obj,
6160 ELM_CHECK_WIDTYPE(obj, widtype);
6161 Widget_Data *wd = elm_widget_data_get(obj);
6164 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
6167 /* for gengrid as of now */
6169 _elm_genlist_page_size_set(Evas_Object *obj,
6170 Evas_Coord h_pagesize,
6171 Evas_Coord v_pagesize)
6176 ELM_CHECK_WIDTYPE(obj, widtype);
6177 Widget_Data *wd = elm_widget_data_get(obj);
6179 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
6180 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
6184 /* for gengrid as of now */
6186 _elm_genlist_current_page_get(const Evas_Object *obj,
6190 ELM_CHECK_WIDTYPE(obj, widtype);
6191 Widget_Data *wd = elm_widget_data_get(obj);
6193 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
6196 /* for gengrid as of now */
6198 _elm_genlist_last_page_get(const Evas_Object *obj,
6202 ELM_CHECK_WIDTYPE(obj, widtype);
6203 Widget_Data *wd = elm_widget_data_get(obj);
6205 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
6208 /* for gengrid as of now */
6210 _elm_genlist_page_show(const Evas_Object *obj,
6214 ELM_CHECK_WIDTYPE(obj, widtype);
6215 Widget_Data *wd = elm_widget_data_get(obj);
6217 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
6220 /* for gengrid as of now */
6222 _elm_genlist_page_bring_in(const Evas_Object *obj,
6226 ELM_CHECK_WIDTYPE(obj, widtype);
6227 Widget_Data *wd = elm_widget_data_get(obj);
6229 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
6233 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
6236 Evas_Object *content;
6238 if (!it->realized) return;
6239 if (it->wd->reorder_it == it) return;
6240 if (it->defer_unrealize && !it->item->updateme) return;
6242 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
6244 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
6247 ecore_timer_del(it->long_timer);
6248 it->long_timer = NULL;
6251 elm_widget_stringlist_free(it->texts);
6253 elm_widget_stringlist_free(it->contents);
6254 it->contents = NULL;
6255 elm_widget_stringlist_free(it->states);
6258 EINA_LIST_FREE(it->content_objs, content)
6259 evas_object_del(content);
6261 it->unrealize_cb(it);
6263 it->realized = EINA_FALSE;
6264 it->want_unrealize = EINA_FALSE;
6265 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
6266 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
6270 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
6272 elm_widget_item_pre_notify_del(it);
6273 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
6275 if ((it->relcount > 0) || (it->walking > 0)) return;
6277 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6279 if (it->itc->func.del)
6280 it->itc->func.del((void *)it->base.data, WIDGET(it));
6284 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
6286 _elm_genlist_item_del_notserious(it);
6287 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6288 if (it->tooltip.del_cb)
6289 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6290 it->wd->walking -= it->walking;
6291 if (it->long_timer) ecore_timer_del(it->long_timer);
6293 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
6297 eina_inlist_sorted_state_free(it->wd->state);
6298 it->wd->state = NULL;
6300 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6301 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
6305 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
6306 it->wd->last_selected_item = NULL;
6307 it->wd->item_count--;
6311 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
6313 ELM_CHECK_WIDTYPE(obj, widtype);
6314 Widget_Data *wd = elm_widget_data_get(obj);
6316 wd->tree_effect_enabled = !!enabled;
6320 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
6322 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6323 Widget_Data *wd = elm_widget_data_get(obj);
6324 if (!wd) return EINA_FALSE;
6325 return wd->tree_effect_enabled;
6329 _create_tray_alpha_bg(const Evas_Object *obj)
6331 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6332 Widget_Data *wd = elm_widget_data_get(obj);
6333 if (!wd) return NULL;
6335 Evas_Object *bg = NULL;
6336 Evas_Coord ox, oy, ow, oh;
6338 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6339 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
6340 evas_object_color_set(bg,0,0,0,0);
6341 evas_object_resize(bg , ow, oh);
6342 evas_object_move(bg , ox, oy);
6347 _item_contract_emit(Elm_Gen_Item *it)
6352 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
6353 it->item->tree_effect_finished = EINA_FALSE;
6355 EINA_LIST_FOREACH(it->item->items, l, it2)
6356 if (it2) _item_contract_emit(it2);
6360 _item_tree_effect_before(Elm_Gen_Item *it)
6365 EINA_LIST_FOREACH(it->item->items, l, it2)
6367 if (it2->parent && (it == it2->parent))
6370 it2->item->tree_effect_hideme = EINA_TRUE;
6371 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6372 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
6373 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6374 _item_contract_emit(it2);
6377 return ECORE_CALLBACK_CANCEL;
6381 _item_tree_effect(Widget_Data *wd, int y)
6383 Elm_Gen_Item *it = NULL, *expanded_next_it;
6385 expanded_next_it = wd->expanded_next_item;
6387 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6389 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6392 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
6393 if (it->item->scrl_y && (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y) &&
6394 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6396 if (!it->item->tree_effect_finished)
6398 edje_object_signal_emit(VIEW(it), "flip_item", "");
6399 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6400 it->item->tree_effect_finished = EINA_TRUE;
6403 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6406 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6408 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
6411 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
6412 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
6414 if (!it->item->tree_effect_finished)
6416 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
6417 it->item->tree_effect_finished = EINA_TRUE;
6422 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
6428 _item_tree_effect_finish(Widget_Data *wd)
6430 Elm_Gen_Item *it = NULL;
6433 if (wd->tree_effect_animator)
6435 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6436 _item_subitems_clear(wd->expanded_item);
6437 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
6439 it->item->tree_effect_finished = EINA_TRUE;
6440 it->item->old_scrl_y = it->item->scrl_y;
6441 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6442 edje_object_signal_emit(VIEW(it), "elm,state,show", "");
6445 _item_auto_scroll(wd);
6446 evas_object_lower(wd->alpha_bg);
6447 evas_object_hide(wd->alpha_bg);
6448 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
6449 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
6451 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
6452 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
6453 evas_object_smart_changed(wd->pan_smart);
6455 wd->tree_effect_animator = NULL;
6459 _tree_effect_animator_cb(void *data)
6461 Widget_Data *wd = data;
6462 if (!wd) return EINA_FALSE;
6463 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
6464 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
6466 double effect_duration = 0.3, t;
6467 int y = 0, dy = 0, dh = 0;
6468 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
6471 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
6472 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
6473 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
6474 if (t > effect_duration) end = EINA_TRUE;
6476 // Below while statement is needed, when the genlist is resized.
6477 it2 = wd->expanded_item;
6480 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
6481 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
6482 cvx, cvy, cvw, cvh));
6483 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
6486 if (wd->expanded_next_item)
6488 expanded_next_it = wd->expanded_next_item;
6491 EINA_LIST_FOREACH(wd->move_items, l, it)
6493 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6495 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6496 if (expanded_next_it->item->scrl_y <= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6497 expanded_next_it->item->scrl_y = cvy + cvh;
6499 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6500 cvy + cvh : expanded_next_it->item->scrl_y) -
6501 expanded_next_it->item->old_scrl_y;
6503 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6505 if (expanded_next_it->item->scrl_y >= expanded_next_it->item->old_scrl_y) //did not calculate next item position
6506 expanded_next_it->item->old_scrl_y = cvy + cvh;
6508 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6510 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6512 expanded_next_it->item->old_scrl_y = cvy + cvh;
6516 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6517 expanded_next_it->item->old_scrl_y;
6521 if (t <= effect_duration)
6523 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6533 _item_realize(it, in, 0);
6537 if (it != expanded_next_it)
6539 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6543 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6544 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6547 _item_tree_effect(wd, y);
6551 int expanded_item_num = 0;
6554 if (wd->expanded_item)
6555 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6560 expanded_item_num++;
6561 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6567 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6568 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6570 if (!it->item->tree_effect_finished)
6572 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6574 edje_object_signal_emit(VIEW(it), "flip_item", "");
6575 _item_position(it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
6576 it->item->tree_effect_finished = EINA_TRUE;
6580 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6586 _item_tree_effect_finish(wd);
6587 return ECORE_CALLBACK_CANCEL;
6589 return ECORE_CALLBACK_RENEW;