3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.h"
9 // internally allocated
10 #define CLASS_ALLOCATED 0x3a70f11f
12 #define MAX_ITEMS_PER_BLOCK 32
13 #define REORDER_EFFECT_TIME 0.5
15 #define ELM_GEN_SETUP(wd) \
16 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
17 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
18 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
32 ERR("Genlist_Item_Class(itc) is NULL"); \
35 if ((itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) && \
36 (itc->version != CLASS_ALLOCATED)) \
38 ERR("Genlist_Item_Class version mismatched! current = (%d), required = (%d) or (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION, CLASS_ALLOCATED); \
44 typedef struct _Item_Block Item_Block;
45 typedef struct _Item_Cache Item_Cache;
47 struct Elm_Gen_Item_Type
52 Evas_Coord w, h, minw, minh;
53 Elm_Gen_Item *group_item;
54 Elm_Genlist_Item_Type type;
55 Eina_List *mode_texts, *mode_contents, *mode_states, *mode_content_objs;
56 Eina_List *edit_texts, *edit_contents, *edit_states, *edit_content_objs;
57 Ecore_Timer *swipe_timer;
58 Evas_Coord scrl_x, scrl_y, old_scrl_y;
61 Evas_Object *mode_view;
67 Eina_Bool want_realize : 1;
68 Eina_Bool expanded : 1;
69 Eina_Bool mincalcd : 1;
72 Eina_Bool updateme : 1;
73 Eina_Bool nocache : 1; /* do not use cache for this item */
74 Eina_Bool nocache_once : 1; /* do not use cache for this item only once */
75 Eina_Bool stacking_even : 1;
76 Eina_Bool nostacking : 1;
77 Eina_Bool move_effect_enabled : 1;
78 Eina_Bool decorate_mode_item_realized : 1;
79 Eina_Bool tree_effect_finished : 1; /* tree effect */
90 Evas_Coord x, y, w, h, minw, minh;
92 int item_position_stamp;
94 Eina_Bool position_update : 1;
95 Eina_Bool want_unrealize : 1;
96 Eina_Bool realized : 1;
97 Eina_Bool changed : 1;
98 Eina_Bool updateme : 1;
100 Eina_Bool must_recalc : 1;
107 Evas_Object *base_view, *spacer;
109 const char *item_style; // it->itc->item_style
110 Eina_Bool tree : 1; // it->group
112 Eina_Bool selected : 1; // it->selected
113 Eina_Bool disabled : 1; // it->disabled
114 Eina_Bool expanded : 1; // it->item->expanded
117 static const char *widtype = NULL;
118 static void _item_cache_zero(Widget_Data *wd);
119 static void _del_hook(Evas_Object *obj);
120 static void _mirrored_set(Evas_Object *obj,
122 static void _theme_hook(Evas_Object *obj);
123 static void _show_region_hook(void *data,
125 static void _sizing_eval(Evas_Object *obj);
126 static void _item_realize(Elm_Gen_Item *it,
129 static void _item_unrealize_cb(Elm_Gen_Item *it);
130 static void _item_block_unrealize(Item_Block *itb);
131 static void _calc_job(void *data);
132 static void _on_focus_hook(void *data,
134 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
135 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
136 static Eina_Bool _item_single_select_up(Widget_Data *wd);
137 static Eina_Bool _item_single_select_down(Widget_Data *wd);
138 static Eina_Bool _event_hook(Evas_Object *obj,
140 Evas_Callback_Type type,
142 static void _signal_emit_hook(Evas_Object *obj,
143 const char *emission,
145 static Eina_Bool _deselect_all_items(Widget_Data *wd);
146 static void _pan_calculate(Evas_Object *obj);
147 static void _pan_max_get(Evas_Object *obj,
150 static void _item_position(Elm_Gen_Item *it,
154 static void _mode_item_realize(Elm_Gen_Item *it);
155 static void _mode_item_unrealize(Elm_Gen_Item *it);
156 static void _item_mode_set(Elm_Gen_Item *it);
157 static void _item_mode_unset(Widget_Data *wd);
158 static void _decorate_mode_item_position(Elm_Gen_Item *it, int itx, int ity);
159 static void _decorate_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
160 static void _decorate_mode_item_unrealize(Elm_Gen_Item *it);
161 static void _group_items_recalc(void *data);
162 static void _item_move_after(Elm_Gen_Item *it,
163 Elm_Gen_Item *after);
164 static void _item_move_before(Elm_Gen_Item *it,
165 Elm_Gen_Item *before);
166 static void _item_auto_scroll(Widget_Data *wd);
167 static void _elm_genlist_clear(Evas_Object *obj,
169 static void _pan_child_size_get(Evas_Object *obj,
172 static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
173 static void _item_contract_emit(Elm_Gen_Item *it);
174 static int _item_tree_effect_before(Elm_Gen_Item *it);
175 static void _item_tree_effect(Widget_Data *wd, int y);
176 static void _item_tree_effect_finish(Widget_Data *wd);
177 static Eina_Bool _tree_effect_animator_cb(void *data);
179 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
181 static const char SIG_ACTIVATED[] = "activated";
182 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
183 static const char SIG_SELECTED[] = "selected";
184 static const char SIG_UNSELECTED[] = "unselected";
185 static const char SIG_EXPANDED[] = "expanded";
186 static const char SIG_CONTRACTED[] = "contracted";
187 static const char SIG_EXPAND_REQUEST[] = "expand,request";
188 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
189 static const char SIG_REALIZED[] = "realized";
190 static const char SIG_UNREALIZED[] = "unrealized";
191 static const char SIG_DRAG_START_UP[] = "drag,start,up";
192 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
193 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
194 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
195 static const char SIG_DRAG_STOP[] = "drag,stop";
196 static const char SIG_DRAG[] = "drag";
197 static const char SIG_LONGPRESSED[] = "longpressed";
198 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
199 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
200 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
201 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
202 static const char SIG_EDGE_TOP[] = "edge,top";
203 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
204 static const char SIG_EDGE_LEFT[] = "edge,left";
205 static const char SIG_EDGE_RIGHT[] = "edge,right";
206 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
207 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
208 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
209 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
210 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
211 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
212 static const char SIG_SWIPE[] = "swipe";
213 static const char SIG_MOVED[] = "moved";
214 static const char SIG_INDEX_UPDATE[] = "index,update";
215 static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
217 static const Evas_Smart_Cb_Description _signals[] = {
218 {SIG_CLICKED_DOUBLE, ""},
221 {SIG_UNSELECTED, ""},
223 {SIG_CONTRACTED, ""},
224 {SIG_EXPAND_REQUEST, ""},
225 {SIG_CONTRACT_REQUEST, ""},
227 {SIG_UNREALIZED, ""},
228 {SIG_DRAG_START_UP, ""},
229 {SIG_DRAG_START_DOWN, ""},
230 {SIG_DRAG_START_LEFT, ""},
231 {SIG_DRAG_START_RIGHT, ""},
234 {SIG_LONGPRESSED, ""},
235 {SIG_SCROLL_ANIM_START, ""},
236 {SIG_SCROLL_ANIM_STOP, ""},
237 {SIG_SCROLL_DRAG_START, ""},
238 {SIG_SCROLL_DRAG_STOP, ""},
240 {SIG_EDGE_BOTTOM, ""},
242 {SIG_EDGE_RIGHT, ""},
243 {SIG_MULTI_SWIPE_LEFT, ""},
244 {SIG_MULTI_SWIPE_RIGHT, ""},
245 {SIG_MULTI_SWIPE_UP, ""},
246 {SIG_MULTI_SWIPE_DOWN, ""},
247 {SIG_MULTI_PINCH_OUT, ""},
248 {SIG_MULTI_PINCH_IN, ""},
251 {SIG_TREE_EFFECT_FINISHED, ""},
256 #undef ELM_CHECK_WIDTYPE
257 #define ELM_CHECK_WIDTYPE(obj, widtype) \
258 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
259 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
260 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
261 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
262 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
264 static const char *_gengrid = NULL;
265 static const char *_genlist = NULL;
267 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
269 elm_genlist_type_check(const Evas_Object *obj,
272 const char *provided, *expected = "(unknown)";
273 static int abort_on_warn = -1;
274 provided = elm_widget_type_get(obj);
275 if (!_genlist) _genlist = eina_stringshare_add("genlist");
276 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
277 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
279 if ((!provided) || (!provided[0]))
281 provided = evas_object_type_get(obj);
282 if ((!provided) || (!provided[0]))
283 provided = "(unknown)";
285 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
286 if (abort_on_warn == -1)
288 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
289 else abort_on_warn = 0;
291 if (abort_on_warn == 1) abort();
296 _event_hook(Evas_Object *obj,
297 Evas_Object *src __UNUSED__,
298 Evas_Callback_Type type,
301 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
302 Evas_Event_Key_Down *ev = event_info;
303 Widget_Data *wd = elm_widget_data_get(obj);
304 Evas_Coord pan_max_x = 0, pan_max_y = 0;
305 if (!wd) return EINA_FALSE;
306 if (!wd->items) return EINA_FALSE;
307 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
308 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
310 Elm_Object_Item *it = NULL;
313 Evas_Coord step_x = 0;
314 Evas_Coord step_y = 0;
317 Evas_Coord page_x = 0;
318 Evas_Coord page_y = 0;
320 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
321 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
322 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
323 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
325 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
329 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
333 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
335 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
336 (_item_multi_select_up(wd)))
337 || (_item_single_select_up(wd)))
339 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
345 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
347 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
348 (_item_multi_select_down(wd)))
349 || (_item_single_select_down(wd)))
351 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
357 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
359 it = elm_genlist_first_item_get(obj);
360 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
361 elm_genlist_item_selected_set(it, EINA_TRUE);
362 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
365 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
367 it = elm_genlist_last_item_get(obj);
368 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
369 elm_genlist_item_selected_set(it, EINA_TRUE);
370 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
373 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
376 y -= -(page_y * v_h) / 100;
380 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
383 y += -(page_y * v_h) / 100;
387 else if (!strcmp(ev->keyname, "Escape"))
389 if (!_deselect_all_items(wd)) return EINA_FALSE;
390 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
393 else if (((!strcmp(ev->keyname, "Return")) ||
394 (!strcmp(ev->keyname, "KP_Enter")) ||
395 (!strcmp(ev->keyname, "space")))
396 && (!wd->multi) && (wd->selected))
398 it = elm_genlist_selected_item_get(obj);
399 elm_genlist_item_expanded_set(it,
400 !elm_genlist_item_expanded_get(it));
401 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
403 else return EINA_FALSE;
405 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
406 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
408 if (x > pan_max_x) x = pan_max_x;
410 if (y > pan_max_y) y = pan_max_y;
411 elm_smart_scroller_child_pos_set(wd->scr, x, y);
416 _deselect_all_items(Widget_Data *wd)
418 if (!wd->selected) return EINA_FALSE;
420 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
426 _item_multi_select_up(Widget_Data *wd)
428 if (!wd->selected) return EINA_FALSE;
429 if (!wd->multi) return EINA_FALSE;
431 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
432 if (!prev) return EINA_TRUE;
434 if (elm_genlist_item_selected_get(prev))
436 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
437 wd->last_selected_item = prev;
438 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
442 elm_genlist_item_selected_set(prev, EINA_TRUE);
443 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
449 _item_multi_select_down(Widget_Data *wd)
451 if (!wd->selected) return EINA_FALSE;
452 if (!wd->multi) return EINA_FALSE;
454 Elm_Object_Item *next;
455 next = elm_genlist_item_next_get(wd->last_selected_item);
456 if (!next) return EINA_TRUE;
458 if (elm_genlist_item_selected_get(next))
460 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
461 wd->last_selected_item = next;
462 elm_genlist_item_show(wd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
466 elm_genlist_item_selected_set(next, EINA_TRUE);
467 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
473 _item_single_select_up(Widget_Data *wd)
478 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
479 while ((prev) && (prev->generation < wd->generation))
480 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
482 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
484 if (!prev) return EINA_FALSE;
486 _deselect_all_items(wd);
488 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
489 elm_genlist_item_show((Elm_Object_Item *) prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
494 _item_single_select_down(Widget_Data *wd)
499 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
500 while ((next) && (next->generation < wd->generation))
501 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
503 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
505 if (!next) return EINA_FALSE;
507 _deselect_all_items(wd);
509 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
510 elm_genlist_item_show((Elm_Object_Item *) next, ELM_GENLIST_ITEM_SCROLLTO_IN);
515 _on_focus_hook(void *data __UNUSED__,
518 Widget_Data *wd = elm_widget_data_get(obj);
520 if (elm_widget_focus_get(obj))
522 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
523 evas_object_focus_set(wd->obj, EINA_TRUE);
524 if ((wd->selected) && (!wd->last_selected_item))
525 wd->last_selected_item = eina_list_data_get(wd->selected);
529 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
530 evas_object_focus_set(wd->obj, EINA_FALSE);
535 _del_hook(Evas_Object *obj)
537 Widget_Data *wd = elm_widget_data_get(obj);
539 _item_cache_zero(wd);
540 if (wd->calc_job) ecore_job_del(wd->calc_job);
541 if (wd->update_job) ecore_job_del(wd->update_job);
542 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
543 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
544 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
545 if (wd->decorate_type) eina_stringshare_del(wd->decorate_type);
546 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
551 _del_pre_hook(Evas_Object *obj)
553 Widget_Data *wd = elm_widget_data_get(obj);
555 if (wd->decorate_mode) elm_genlist_decorate_mode_set(wd->obj, EINA_FALSE);
556 elm_genlist_clear(obj);
557 evas_object_del(wd->pan_smart);
558 wd->pan_smart = NULL;
562 _mirrored_set(Evas_Object *obj,
565 Widget_Data *wd = elm_widget_data_get(obj);
567 _item_cache_zero(wd);
568 elm_smart_scroller_mirrored_set(wd->scr, rtl);
572 _theme_hook(Evas_Object *obj)
574 Widget_Data *wd = elm_widget_data_get(obj);
577 evas_event_freeze(evas_object_evas_get(wd->obj));
578 _item_cache_zero(wd);
579 _elm_widget_mirrored_reload(obj);
580 _mirrored_set(obj, elm_widget_mirrored_get(obj));
581 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
582 elm_widget_style_get(obj));
583 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
584 wd->item_width = wd->item_height = 0;
585 wd->group_item_width = wd->group_item_height = 0;
586 wd->minw = wd->minh = wd->realminw = 0;
587 EINA_INLIST_FOREACH(wd->blocks, itb)
592 if (itb->realized) _item_block_unrealize(itb);
593 EINA_LIST_FOREACH(itb->items, l, it)
594 it->item->mincalcd = EINA_FALSE;
596 itb->changed = EINA_TRUE;
598 if (wd->calc_job) ecore_job_del(wd->calc_job);
599 wd->calc_job = ecore_job_add(_calc_job, wd);
601 evas_event_thaw(evas_object_evas_get(wd->obj));
602 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
606 _show_region_hook(void *data,
609 Widget_Data *wd = elm_widget_data_get(data);
610 Evas_Coord x, y, w, h;
612 elm_widget_show_region_get(obj, &x, &y, &w, &h);
613 //x & y are screen coordinates, Add with pan coordinates
616 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
620 _translate_hook(Evas_Object *obj)
622 evas_object_smart_callback_call(obj, "language,changed", NULL);
626 _sizing_eval(Evas_Object *obj)
628 Widget_Data *wd = elm_widget_data_get(obj);
629 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
630 Evas_Coord vmw = 0, vmh = 0;
633 evas_object_size_hint_min_get(wd->scr, &minw, NULL);
634 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
636 edje_object_size_min_calc
637 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
639 if (wd->mode == ELM_LIST_COMPRESS)
643 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
644 if ((vw != 0) && (vw != wd->prev_viewport_w))
648 wd->prev_viewport_w = vw;
649 EINA_INLIST_FOREACH(wd->blocks, itb)
651 itb->must_recalc = EINA_TRUE;
653 if (wd->calc_job) ecore_job_del(wd->calc_job);
654 wd->calc_job = ecore_job_add(_calc_job, wd);
659 else if (wd->mode == ELM_LIST_LIMIT)
670 evas_object_size_hint_min_set(obj, minw, minh);
671 evas_object_size_hint_max_set(obj, maxw, maxh);
675 _signal_emit_hook(Evas_Object *obj,
676 const char *emission,
679 Widget_Data *wd = elm_widget_data_get(obj);
680 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
685 _item_highlight(Elm_Gen_Item *it)
687 const char *selectraise;
688 if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
689 (!it->wd->highlight) ||
690 (it->generation < it->wd->generation) ||
691 (it->highlighted) || elm_widget_item_disabled_get(it) ||
692 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || (it->item->mode_view) ||
693 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
695 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
696 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,selected", "elm");
697 selectraise = edje_object_data_get(VIEW(it), "selectraise");
698 if ((selectraise) && (!strcmp(selectraise, "on")))
700 if (it->edit_obj) evas_object_raise(it->edit_obj);
701 else evas_object_raise(VIEW(it));
702 if ((it->item->group_item) && (it->item->group_item->realized))
703 evas_object_raise(it->item->VIEW(group_item));
705 it->highlighted = EINA_TRUE;
709 _item_unhighlight(Elm_Gen_Item *it)
711 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
712 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
713 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,unselected", "elm");
714 if (!it->item->nostacking)
716 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
718 if (it->edit_obj) evas_object_lower(it->edit_obj);
719 else evas_object_lower(VIEW(it));
723 if (it->edit_obj) evas_object_raise(it->edit_obj);
724 else evas_object_raise(VIEW(it));
727 it->highlighted = EINA_FALSE;
731 _item_block_position_update(Eina_Inlist *list, int idx)
735 EINA_INLIST_FOREACH(list, tmp)
737 tmp->position = idx++;
738 tmp->position_update = EINA_TRUE;
743 _item_position_update(Eina_List *list, int idx)
748 EINA_LIST_FOREACH(list, l, it)
750 it->position = idx++;
751 it->position_update = EINA_TRUE;
756 _item_block_del(Elm_Gen_Item *it)
759 Item_Block *itb = it->item->block;
761 itb->items = eina_list_remove(itb->items, it);
763 itb->changed = EINA_TRUE;
764 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
765 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
768 il = EINA_INLIST_GET(itb);
769 Item_Block *itbn = (Item_Block *)(il->next);
771 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
774 _item_block_position_update(il->next, itb->position);
775 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
778 if (itbn) itbn->changed = EINA_TRUE;
782 if (itb->count < itb->wd->max_items_per_block/2)
784 il = EINA_INLIST_GET(itb);
785 Item_Block *itbp = (Item_Block *)(il->prev);
786 Item_Block *itbn = (Item_Block *)(il->next);
787 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
791 EINA_LIST_FREE(itb->items, it2)
793 it2->item->block = itbp;
794 itbp->items = eina_list_append(itbp->items, it2);
796 itbp->changed = EINA_TRUE;
798 _item_block_position_update(EINA_INLIST_GET(itb)->next,
800 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
801 EINA_INLIST_GET(itb));
804 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
808 Eina_List *last = eina_list_last(itb->items);
809 Elm_Gen_Item *it2 = last->data;
811 it2->item->block = itbn;
812 itb->items = eina_list_remove_list(itb->items, last);
813 itbn->items = eina_list_prepend(itbn->items, it2);
815 itbn->changed = EINA_TRUE;
817 _item_block_position_update(EINA_INLIST_GET(itb)->next,
820 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
828 _item_subitems_clear(Elm_Gen_Item *it)
830 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
831 Eina_List *tl = NULL, *l;
832 Elm_Object_Item *it2;
834 EINA_LIST_FOREACH(it->item->items, l, it2)
835 tl = eina_list_append(tl, it2);
836 EINA_LIST_FREE(tl, it2)
837 elm_object_item_del(it2);
841 _item_del(Elm_Gen_Item *it)
843 Evas_Object *obj = WIDGET(it);
845 evas_event_freeze(evas_object_evas_get(obj));
846 elm_genlist_item_subitems_clear((Elm_Object_Item *)it);
847 if (it->wd->show_item == it) it->wd->show_item = NULL;
848 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
849 if (it->item->decorate_mode_item_realized) _decorate_mode_item_unrealize(it);
850 if (it->item->block) _item_block_del(it);
851 if (it->item->queued)
852 it->wd->queue = eina_list_remove(it->wd->queue, it);
853 if (it->wd->anchor_item == it)
855 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
856 if (!it->wd->anchor_item)
857 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
859 if (it->wd->expanded_item == it) it->wd->expanded_item = NULL;
861 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
862 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
863 _elm_genlist_item_del_serious(it);
864 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
865 evas_event_thaw(evas_object_evas_get(obj));
866 evas_event_thaw_eval(evas_object_evas_get(obj));
870 _clear_cb(Widget_Data *wd)
872 wd->anchor_item = NULL;
875 Item_Block *itb = (Item_Block *)(wd->blocks);
877 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
878 if (itb->items) eina_list_free(itb->items);
881 if (wd->queue_idle_enterer)
883 ecore_idle_enterer_del(wd->queue_idle_enterer);
884 wd->queue_idle_enterer = NULL;
886 if (wd->must_recalc_idler)
888 ecore_idler_del(wd->must_recalc_idler);
889 wd->must_recalc_idler = NULL;
891 if (wd->queue) wd->queue = eina_list_free(wd->queue);
892 if (wd->reorder_move_animator)
894 ecore_animator_del(wd->reorder_move_animator);
895 wd->reorder_move_animator = NULL;
897 wd->show_item = NULL;
898 wd->reorder_old_pan_y = 0;
902 _item_unselect(Elm_Gen_Item *it)
904 if ((it->generation < it->wd->generation) || (!it->selected)) return;
905 it->selected = EINA_FALSE;
906 it->wd->selected = eina_list_remove(it->wd->selected, it);
907 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
911 _mouse_move(void *data,
912 Evas *evas __UNUSED__,
916 Elm_Gen_Item *it = data;
917 Evas_Event_Mouse_Move *ev = event_info;
918 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
919 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
921 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
923 if (!it->wd->on_hold)
925 it->wd->on_hold = EINA_TRUE;
926 if ((!it->wd->wasselected) && (!it->flipped))
928 _item_unhighlight(it);
933 if (it->wd->multitouched)
935 it->wd->cur_x = ev->cur.canvas.x;
936 it->wd->cur_y = ev->cur.canvas.y;
939 if ((it->dragging) && (it->down))
941 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
944 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
945 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
946 if (abs((it->wd->history[it->wd->movements].x -
947 it->wd->history[0].x)) > 40)
948 it->wd->swipe = EINA_TRUE;
954 ecore_timer_del(it->long_timer);
955 it->long_timer = NULL;
957 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
960 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
964 ecore_timer_del(it->long_timer);
965 it->long_timer = NULL;
967 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
969 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
970 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
972 if (!it->wd->reorder_start_y)
973 it->wd->reorder_start_y = it->item->block->y + it->y;
977 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
978 y_pos = oy + oh - it->wd->reorder_it->item->h;
983 _item_position(it, it->edit_obj, it->item->scrl_x, y_pos);
985 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
987 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
988 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
992 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
993 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
994 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
995 x = ev->cur.canvas.x - x;
996 y = ev->cur.canvas.y - y;
999 if (adx < 0) adx = -dx;
1002 if (ady < 0) ady = -dy;
1005 if ((adx > minw) || (ady > minh))
1007 it->dragging = EINA_TRUE;
1010 ecore_timer_del(it->long_timer);
1011 it->long_timer = NULL;
1013 if (!it->wd->wasselected)
1015 _item_unhighlight(it);
1021 evas_object_smart_callback_call(WIDGET(it),
1022 SIG_DRAG_START_UP, it);
1026 evas_object_smart_callback_call(WIDGET(it),
1027 SIG_DRAG_START_LEFT, it);
1029 evas_object_smart_callback_call(WIDGET(it),
1030 SIG_DRAG_START_RIGHT, it);
1036 evas_object_smart_callback_call(WIDGET(it),
1037 SIG_DRAG_START_DOWN, it);
1041 evas_object_smart_callback_call(WIDGET(it),
1042 SIG_DRAG_START_LEFT, it);
1044 evas_object_smart_callback_call(WIDGET(it),
1045 SIG_DRAG_START_RIGHT, it);
1052 _long_press(void *data)
1054 Elm_Gen_Item *it = data, *it_tmp;
1055 Eina_List *list, *l;
1057 it->long_timer = NULL;
1058 if (elm_widget_item_disabled_get(it) || (it->dragging) ||
1059 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1060 return ECORE_CALLBACK_CANCEL;
1061 it->wd->longpressed = EINA_TRUE;
1062 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1063 if ((it->wd->reorder_mode) && (!it->group))
1065 it->wd->reorder_it = it;
1066 it->wd->reorder_start_y = 0;
1068 evas_object_raise(it->edit_obj);
1070 evas_object_raise(VIEW(it));
1072 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1073 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1075 list = elm_genlist_realized_items_get(it->wd->obj);
1076 EINA_LIST_FOREACH(list, l, it_tmp)
1078 if (it != it_tmp) _item_unselect(it_tmp);
1080 if (elm_genlist_item_expanded_get((Elm_Object_Item *)it))
1082 elm_genlist_item_expanded_set((Elm_Object_Item *)it, EINA_FALSE);
1083 return ECORE_CALLBACK_RENEW;
1086 if (!it->wd->decorate_mode)
1087 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1089 return ECORE_CALLBACK_CANCEL;
1093 _swipe(Elm_Gen_Item *it)
1098 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1099 elm_widget_item_disabled_get(it)) return;
1100 it->wd->swipe = EINA_FALSE;
1101 for (i = 0; i < it->wd->movements; i++)
1103 sum += it->wd->history[i].x;
1104 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1107 sum /= it->wd->movements;
1108 if (abs(sum - it->wd->history[0].x) <= 10) return;
1109 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1113 _swipe_cancel(void *data)
1115 Elm_Gen_Item *it = data;
1117 if (!it) return ECORE_CALLBACK_CANCEL;
1118 it->wd->swipe = EINA_FALSE;
1119 it->wd->movements = 0;
1120 return ECORE_CALLBACK_RENEW;
1124 _multi_cancel(void *data)
1126 Widget_Data *wd = data;
1128 if (!wd) return ECORE_CALLBACK_CANCEL;
1129 wd->multi_timeout = EINA_TRUE;
1130 return ECORE_CALLBACK_RENEW;
1134 _multi_touch_gesture_eval(void *data)
1136 Elm_Gen_Item *it = data;
1138 it->wd->multitouched = EINA_FALSE;
1139 if (it->wd->multi_timer)
1141 ecore_timer_del(it->wd->multi_timer);
1142 it->wd->multi_timer = NULL;
1144 if (it->wd->multi_timeout)
1146 it->wd->multi_timeout = EINA_FALSE;
1150 Evas_Coord minw = 0, minh = 0;
1151 Evas_Coord off_x, off_y, off_mx, off_my;
1153 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1154 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1155 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1156 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1157 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1159 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1161 if ((off_x + off_mx) > (off_y + off_my))
1163 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1164 evas_object_smart_callback_call(WIDGET(it),
1165 SIG_MULTI_SWIPE_RIGHT, it);
1166 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1167 evas_object_smart_callback_call(WIDGET(it),
1168 SIG_MULTI_SWIPE_LEFT, it);
1169 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1170 evas_object_smart_callback_call(WIDGET(it),
1171 SIG_MULTI_PINCH_OUT, it);
1173 evas_object_smart_callback_call(WIDGET(it),
1174 SIG_MULTI_PINCH_IN, it);
1178 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1179 evas_object_smart_callback_call(WIDGET(it),
1180 SIG_MULTI_SWIPE_DOWN, it);
1181 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1182 evas_object_smart_callback_call(WIDGET(it),
1183 SIG_MULTI_SWIPE_UP, it);
1184 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1185 evas_object_smart_callback_call(WIDGET(it),
1186 SIG_MULTI_PINCH_OUT, it);
1188 evas_object_smart_callback_call(WIDGET(it),
1189 SIG_MULTI_PINCH_IN, it);
1192 it->wd->multi_timeout = EINA_FALSE;
1196 _multi_down(void *data,
1197 Evas *evas __UNUSED__,
1198 Evas_Object *obj __UNUSED__,
1201 Elm_Gen_Item *it = data;
1202 Evas_Event_Multi_Down *ev = event_info;
1204 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1205 it->wd->multi_device = ev->device;
1206 it->wd->multi_down = EINA_TRUE;
1207 it->wd->multitouched = EINA_TRUE;
1208 it->wd->prev_mx = ev->canvas.x;
1209 it->wd->prev_my = ev->canvas.y;
1210 if (!it->wd->wasselected)
1212 _item_unhighlight(it);
1215 it->wd->wasselected = EINA_FALSE;
1216 it->wd->longpressed = EINA_FALSE;
1219 ecore_timer_del(it->long_timer);
1220 it->long_timer = NULL;
1224 it->dragging = EINA_FALSE;
1225 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1227 if (it->item->swipe_timer)
1229 ecore_timer_del(it->item->swipe_timer);
1230 it->item->swipe_timer = NULL;
1232 if (it->wd->on_hold)
1234 it->wd->swipe = EINA_FALSE;
1235 it->wd->movements = 0;
1236 it->wd->on_hold = EINA_FALSE;
1241 _multi_up(void *data,
1242 Evas *evas __UNUSED__,
1243 Evas_Object *obj __UNUSED__,
1246 Elm_Gen_Item *it = data;
1247 Evas_Event_Multi_Up *ev = event_info;
1249 if (it->wd->multi_device != ev->device) return;
1250 it->wd->multi_device = 0;
1251 it->wd->multi_down = EINA_FALSE;
1252 if (it->wd->mouse_down) return;
1253 _multi_touch_gesture_eval(data);
1257 _multi_move(void *data,
1258 Evas *evas __UNUSED__,
1259 Evas_Object *obj __UNUSED__,
1262 Elm_Gen_Item *it = data;
1263 Evas_Event_Multi_Move *ev = event_info;
1265 if (it->wd->multi_device != ev->device) return;
1266 it->wd->cur_mx = ev->cur.canvas.x;
1267 it->wd->cur_my = ev->cur.canvas.y;
1271 _mouse_down(void *data,
1272 Evas *evas __UNUSED__,
1276 Elm_Gen_Item *it = data;
1277 Evas_Event_Mouse_Down *ev = event_info;
1280 if (ev->button != 1) return;
1281 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1283 it->wd->on_hold = EINA_TRUE;
1286 it->down = EINA_TRUE;
1287 it->dragging = EINA_FALSE;
1288 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1289 it->dx = ev->canvas.x - x;
1290 it->dy = ev->canvas.y - y;
1291 it->wd->mouse_down = EINA_TRUE;
1292 if (!it->wd->multitouched)
1294 it->wd->prev_x = ev->canvas.x;
1295 it->wd->prev_y = ev->canvas.y;
1296 it->wd->multi_timeout = EINA_FALSE;
1297 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1298 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1300 it->wd->longpressed = EINA_FALSE;
1301 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1302 else it->wd->on_hold = EINA_FALSE;
1303 if (it->wd->on_hold) return;
1304 it->wd->wasselected = it->selected;
1305 _item_highlight(it);
1306 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1307 if ((!elm_widget_item_disabled_get(it)) &&
1308 (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1310 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1311 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1313 if (it->long_timer) ecore_timer_del(it->long_timer);
1314 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1315 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1317 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1320 it->long_timer = NULL;
1321 it->wd->swipe = EINA_FALSE;
1322 it->wd->movements = 0;
1326 _mouse_up(void *data,
1327 Evas *evas __UNUSED__,
1328 Evas_Object *obj __UNUSED__,
1331 Elm_Gen_Item *it = data;
1332 Evas_Event_Mouse_Up *ev = event_info;
1333 Eina_Bool dragged = EINA_FALSE;
1335 if (ev->button != 1) return;
1336 it->down = EINA_FALSE;
1337 it->wd->mouse_down = EINA_FALSE;
1338 if (it->wd->multitouched)
1340 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1341 if (it->wd->multi_down) return;
1342 _multi_touch_gesture_eval(data);
1345 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1346 else it->wd->on_hold = EINA_FALSE;
1349 ecore_timer_del(it->long_timer);
1350 it->long_timer = NULL;
1354 it->dragging = EINA_FALSE;
1355 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1358 if (it->item->swipe_timer)
1360 ecore_timer_del(it->item->swipe_timer);
1361 it->item->swipe_timer = NULL;
1363 if (it->wd->multi_timer)
1365 ecore_timer_del(it->wd->multi_timer);
1366 it->wd->multi_timer = NULL;
1367 it->wd->multi_timeout = EINA_FALSE;
1369 if (it->wd->on_hold)
1371 if (it->wd->swipe) _swipe(data);
1372 it->wd->longpressed = EINA_FALSE;
1373 it->wd->on_hold = EINA_FALSE;
1376 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1378 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1380 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1382 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1383 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1385 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1389 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1390 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1392 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1393 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1394 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1395 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1397 if (it->wd->longpressed)
1399 it->wd->longpressed = EINA_FALSE;
1400 if ((!it->wd->wasselected) && (!it->flipped))
1402 _item_unhighlight(it);
1405 it->wd->wasselected = EINA_FALSE;
1410 if (it->want_unrealize)
1412 _elm_genlist_item_unrealize(it, EINA_FALSE);
1413 if (it->item->block->want_unrealize)
1414 _item_block_unrealize(it->item->block);
1417 if (elm_widget_item_disabled_get(it) || (dragged) ||
1418 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
1420 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1425 _item_highlight(it);
1430 _item_unhighlight(it);
1438 Widget_Data *wd = it->wd;
1441 while (wd->selected)
1443 _item_unhighlight(wd->selected->data);
1444 _item_unselect(wd->selected->data);
1450 const Eina_List *l, *l_next;
1453 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1456 _item_unhighlight(it2);
1457 _item_unselect(it2);
1459 //_item_highlight(it);
1462 _item_highlight(it);
1468 _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view)
1470 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_DOWN,
1472 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_UP,
1474 evas_object_event_callback_add(view, EVAS_CALLBACK_MOUSE_MOVE,
1476 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_DOWN,
1478 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_UP,
1480 evas_object_event_callback_add(view, EVAS_CALLBACK_MULTI_MOVE,
1485 _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view)
1487 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_DOWN,
1489 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_UP,
1491 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MOUSE_MOVE,
1493 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_DOWN,
1495 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_UP,
1497 evas_object_event_callback_del_full(view, EVAS_CALLBACK_MULTI_MOVE,
1502 _signal_expand_toggle(void *data,
1503 Evas_Object *obj __UNUSED__,
1504 const char *emission __UNUSED__,
1505 const char *source __UNUSED__)
1507 Elm_Gen_Item *it = data;
1509 if (it->item->expanded)
1510 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1512 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1516 _signal_expand(void *data,
1517 Evas_Object *obj __UNUSED__,
1518 const char *emission __UNUSED__,
1519 const char *source __UNUSED__)
1521 Elm_Gen_Item *it = data;
1523 if (!it->item->expanded)
1524 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1528 _signal_contract(void *data,
1529 Evas_Object *obj __UNUSED__,
1530 const char *emission __UNUSED__,
1531 const char *source __UNUSED__)
1533 Elm_Gen_Item *it = data;
1535 if (it->item->expanded)
1536 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1540 _scr_hold_timer_cb(void *data)
1542 if (!data) return ECORE_CALLBACK_CANCEL;
1543 Widget_Data *wd = data;
1544 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1545 wd->scr_hold_timer = NULL;
1546 return ECORE_CALLBACK_CANCEL;
1550 _mode_finished_signal_cb(void *data,
1552 const char *emission __UNUSED__,
1553 const char *source __UNUSED__)
1557 Elm_Gen_Item *it = data;
1558 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1560 Evas *te = evas_object_evas_get(obj);
1562 evas_event_freeze(te);
1563 it->item->nocache_once = EINA_FALSE;
1564 _mode_item_unrealize(it);
1565 if (it->item->group_item)
1566 evas_object_raise(it->item->VIEW(group_item));
1567 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->decorate_type);
1568 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1569 evas_event_thaw(te);
1570 evas_event_thaw_eval(te);
1574 _item_cache_clean(Widget_Data *wd)
1576 evas_event_freeze(evas_object_evas_get(wd->obj));
1577 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1581 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1582 wd->item_cache = eina_inlist_remove(wd->item_cache,
1583 wd->item_cache->last);
1584 wd->item_cache_count--;
1585 if (itc->spacer) evas_object_del(itc->spacer);
1586 if (itc->base_view) evas_object_del(itc->base_view);
1587 eina_stringshare_del(itc->item_style);
1590 evas_event_thaw(evas_object_evas_get(wd->obj));
1591 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1595 _item_cache_zero(Widget_Data *wd)
1597 int pmax = wd->item_cache_max;
1598 wd->item_cache_max = 0;
1599 _item_cache_clean(wd);
1600 wd->item_cache_max = pmax;
1604 _item_cache_add(Elm_Gen_Item *it)
1608 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1609 if (it->wd->item_cache_max <= 0)
1611 evas_object_del(VIEW(it));
1615 evas_object_del(it->spacer);
1618 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1619 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1623 it->wd->item_cache_count++;
1624 itc = calloc(1, sizeof(Item_Cache));
1627 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1628 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1631 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1632 EINA_INLIST_GET(itc));
1633 itc->spacer = it->spacer;
1635 itc->base_view = VIEW(it);
1637 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1638 evas_object_hide(itc->base_view);
1639 evas_object_move(itc->base_view, -9999, -9999);
1640 itc->item_style = eina_stringshare_add(it->itc->item_style);
1641 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1642 itc->selected = it->selected;
1643 itc->disabled = elm_widget_item_disabled_get(it);
1644 itc->expanded = it->item->expanded;
1647 ecore_timer_del(it->long_timer);
1648 it->long_timer = NULL;
1650 if (it->item->swipe_timer)
1652 ecore_timer_del(it->item->swipe_timer);
1653 it->item->swipe_timer = NULL;
1655 // FIXME: other callbacks?
1656 edje_object_signal_callback_del_full(itc->base_view,
1657 "elm,action,expand,toggle",
1658 "elm", _signal_expand_toggle, it);
1659 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1661 _signal_expand, it);
1662 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1663 "elm", _signal_contract, it);
1664 _item_mouse_callbacks_del(it, itc->base_view);
1665 _item_cache_clean(it->wd);
1666 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1667 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1671 _item_cache_find(Elm_Gen_Item *it)
1676 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1677 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1679 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1681 if ((itc->tree == tree) &&
1682 (((!it->itc->item_style) && (!itc->item_style)) ||
1683 (it->itc->item_style && itc->item_style &&
1684 (!strcmp(it->itc->item_style, itc->item_style)))))
1686 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1687 EINA_INLIST_GET(itc));
1688 it->wd->item_cache_count--;
1696 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1698 if (it->position_update || it->item->block->position_update)
1700 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1701 it->position_update = EINA_FALSE;
1706 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1708 if (!it->item->nostacking)
1710 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1712 if (it->edit_obj) evas_object_lower(it->edit_obj);
1713 else evas_object_lower(VIEW(it));
1717 if (it->edit_obj) evas_object_raise(it->edit_obj);
1718 else evas_object_raise(VIEW(it));
1722 if (it->item->order_num_in & 0x1)
1724 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1725 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,odd", "elm");
1729 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1730 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,even", "elm");
1735 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1739 if (it->selected != itc->selected)
1742 edje_object_signal_emit(VIEW(it),
1743 "elm,state,selected", "elm");
1746 edje_object_signal_emit(it->edit_obj,
1747 "elm,state,selected", "elm");
1749 if (elm_widget_item_disabled_get(it) != itc->disabled)
1751 if (elm_widget_item_disabled_get(it))
1752 edje_object_signal_emit(VIEW(it),
1753 "elm,state,disabled", "elm");
1755 edje_object_signal_emit(it->edit_obj,
1756 "elm,state,disabled", "elm");
1758 if (it->item->expanded != itc->expanded)
1760 if (it->item->expanded)
1761 edje_object_signal_emit(VIEW(it),
1762 "elm,state,expanded", "elm");
1764 edje_object_signal_emit(it->edit_obj,
1765 "elm,state,expanded", "elm");
1772 edje_object_signal_emit(VIEW(it),
1773 "elm,state,selected", "elm");
1775 edje_object_signal_emit(it->edit_obj,
1776 "elm,state,selected", "elm");
1779 if (elm_widget_item_disabled_get(it))
1781 edje_object_signal_emit(VIEW(it),
1782 "elm,state,disabled", "elm");
1784 edje_object_signal_emit(it->edit_obj,
1785 "elm,state,disabled", "elm");
1787 if (it->item->expanded)
1789 edje_object_signal_emit(VIEW(it),
1790 "elm,state,expanded", "elm");
1792 edje_object_signal_emit(it->edit_obj,
1793 "elm,state,expanded", "elm");
1799 _item_cache_free(Item_Cache *itc)
1801 if (itc->spacer) evas_object_del(itc->spacer);
1802 if (itc->base_view) evas_object_del(itc->base_view);
1803 eina_stringshare_del(itc->item_style);
1808 _item_text_realize(Elm_Gen_Item *it,
1809 Evas_Object *target,
1813 if (it->itc->func.text_get)
1818 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1819 EINA_LIST_FOREACH(*source, l, key)
1821 if (parts && fnmatch(parts, key, FNM_PERIOD))
1824 char *s = it->itc->func.text_get
1825 ((void *)it->base.data, WIDGET(it), key);
1829 edje_object_part_text_set(target, key, s);
1834 edje_object_part_text_set(target, key, "");
1841 _item_content_unrealize(Elm_Gen_Item *it,
1842 Evas_Object *target,
1846 Eina_List *res = it->content_objs;
1848 if (it->itc->func.content_get)
1852 Evas_Object *ic = NULL;
1854 EINA_LIST_FOREACH(*source, l, key)
1856 if (parts && fnmatch(parts, key, FNM_PERIOD))
1859 ic = edje_object_part_swallow_get(target, key);
1862 res = eina_list_remove(res, ic);
1863 edje_object_part_unswallow(target, ic);
1864 evas_object_del(ic);
1873 _item_content_realize(Elm_Gen_Item *it,
1874 Evas_Object *target,
1878 Eina_List *res = NULL;
1880 if (it->itc->func.content_get)
1884 Evas_Object *ic = NULL;
1886 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1888 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
1889 res = it->content_objs;
1891 EINA_LIST_FOREACH(*source, l, key)
1893 if (parts && fnmatch(parts, key, FNM_PERIOD))
1896 if (it->itc->func.content_get)
1897 ic = it->itc->func.content_get
1898 ((void *)it->base.data, WIDGET(it), key);
1901 res = eina_list_append(res, ic);
1902 edje_object_part_swallow(target, key, ic);
1903 evas_object_show(ic);
1904 elm_widget_sub_object_add(WIDGET(it), ic);
1905 if (elm_widget_item_disabled_get(it))
1906 elm_widget_disabled_set(ic, EINA_TRUE);
1915 _item_state_realize(Elm_Gen_Item *it,
1916 Evas_Object *target,
1920 if (it->itc->func.state_get)
1926 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
1927 EINA_LIST_FOREACH(*source, l, key)
1929 if (parts && fnmatch(parts, key, FNM_PERIOD))
1932 Eina_Bool on = it->itc->func.state_get
1933 ((void *)it->base.data, WIDGET(it), key);
1937 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1938 edje_object_signal_emit(target, buf, "elm");
1942 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1943 edje_object_signal_emit(target, buf, "elm");
1950 _item_flips_realize(Elm_Gen_Item *it,
1951 Evas_Object *target,
1954 Eina_List *res = NULL;
1956 if (it->itc->func.content_get)
1960 Evas_Object *ic = NULL;
1961 Eina_List *cons = NULL;
1962 cons = elm_widget_stringlist_get(edje_object_data_get(target, "flips"));
1964 EINA_LIST_FOREACH(cons, l, key)
1966 if (it->itc->func.content_get)
1967 ic = it->itc->func.content_get
1968 ((void *)it->base.data, WIDGET(it), key);
1971 res = eina_list_append(res, ic);
1972 edje_object_part_swallow(target, key, ic);
1973 evas_object_show(ic);
1974 elm_widget_sub_object_add(WIDGET(it), ic);
1975 if (elm_widget_item_disabled_get(it))
1976 elm_widget_disabled_set(ic, EINA_TRUE);
1979 *source = eina_list_merge(*source, cons);
1980 elm_widget_stringlist_free(cons);
1987 _item_realize(Elm_Gen_Item *it,
1991 const char *treesize;
1994 Item_Cache *itc = NULL;
1996 if (it->generation < it->wd->generation) return;
1997 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
2000 if (it->item->order_num_in != in)
2002 it->item->order_num_in = in;
2003 _elm_genlist_item_odd_even_update(it);
2004 _elm_genlist_item_state_update(it, NULL);
2005 _elm_genlist_item_index_update(it);
2007 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2008 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2011 it->item->order_num_in = in;
2013 if (it->item->nocache_once)
2014 it->item->nocache_once = EINA_FALSE;
2015 else if (!it->item->nocache)
2016 itc = _item_cache_find(it);
2017 if (itc && (!it->wd->tree_effect_enabled))
2019 VIEW(it) = itc->base_view;
2020 itc->base_view = NULL;
2021 it->spacer = itc->spacer;
2026 const char *stacking_even;
2027 const char *stacking;
2029 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
2030 edje_object_scale_set(VIEW(it),
2031 elm_widget_scale_get(WIDGET(it)) *
2032 _elm_config->scale);
2033 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
2034 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
2036 if (it->item->type & ELM_GENLIST_ITEM_TREE)
2037 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2039 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->mode == ELM_LIST_COMPRESS ? "_compress" : "", it->itc->item_style ?: "default");
2041 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
2042 elm_widget_style_get(WIDGET(it)));
2044 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
2045 if (!stacking_even) stacking_even = "above";
2046 it->item->stacking_even = !!strcmp("above", stacking_even);
2048 stacking = edje_object_data_get(VIEW(it), "stacking");
2049 if (!stacking) stacking = "yes";
2050 it->item->nostacking = !!strcmp("yes", stacking);
2052 edje_object_mirrored_set(VIEW(it),
2053 elm_widget_mirrored_get(WIDGET(it)));
2056 _elm_genlist_item_odd_even_update(it);
2058 treesize = edje_object_data_get(VIEW(it), "treesize");
2059 if (treesize) tsize = atoi(treesize);
2060 if (!it->spacer && treesize)
2063 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
2064 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2065 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2069 evas_object_size_hint_min_set(it->spacer,
2070 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2071 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2075 edje_object_signal_callback_add(VIEW(it),
2076 "elm,action,expand,toggle",
2077 "elm", _signal_expand_toggle, it);
2078 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2079 "elm", _signal_expand, it);
2080 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2081 "elm", _signal_contract, it);
2082 _item_mouse_callbacks_add(it, VIEW(it));
2084 if ((it->wd->decorate_mode) && (!it->edit_obj) &&
2085 (it->item->type != ELM_GENLIST_ITEM_GROUP) && (it->itc->decorate_all_item_style))
2086 _decorate_mode_item_realize(it, EINA_FALSE);
2088 _elm_genlist_item_state_update(it, itc);
2089 _elm_genlist_item_index_update(it);
2092 if ((calc) && (it->wd->homogeneous) &&
2093 ((it->wd->item_width) ||
2094 ((it->wd->item_width) && (it->wd->group_item_width))))
2096 /* homogenous genlist shortcut */
2097 if (!it->item->mincalcd)
2101 it->item->w = it->item->minw = it->wd->group_item_width;
2102 it->item->h = it->item->minh = it->wd->group_item_height;
2106 it->item->w = it->item->minw = it->wd->item_width;
2107 it->item->h = it->item->minh = it->wd->item_height;
2109 it->item->mincalcd = EINA_TRUE;
2114 /* FIXME: If you see that assert, please notify us and we
2115 will clean our mess */
2116 assert(eina_list_count(it->content_objs) == 0);
2118 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2119 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2120 _item_state_realize(it, VIEW(it), &it->states, NULL);
2123 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2124 it->content_objs = _item_flips_realize(it, VIEW(it), &it->contents);
2127 if (!it->item->mincalcd)
2129 Evas_Coord mw = -1, mh = -1;
2131 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2132 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2133 if (it->wd->mode == ELM_LIST_COMPRESS) mw = it->wd->prev_viewport_w;
2134 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2136 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2137 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2138 it->item->w = it->item->minw = mw;
2139 it->item->h = it->item->minh = mh;
2140 it->item->mincalcd = EINA_TRUE;
2142 if ((!it->wd->group_item_width) && (it->group))
2144 it->wd->group_item_width = mw;
2145 it->wd->group_item_height = mh;
2147 else if ((!it->wd->item_width) && (it->item->type == ELM_GENLIST_ITEM_NONE))
2149 it->wd->item_width = mw;
2150 it->wd->item_height = mh;
2153 if (!calc) evas_object_show(VIEW(it));
2156 if (it->tooltip.content_cb)
2158 elm_widget_item_tooltip_content_cb_set(it,
2159 it->tooltip.content_cb,
2160 it->tooltip.data, NULL);
2161 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2162 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2165 if (it->mouse_cursor)
2166 elm_widget_item_cursor_set(it, it->mouse_cursor);
2168 it->realized = EINA_TRUE;
2169 it->want_unrealize = EINA_FALSE;
2171 if (itc) _item_cache_free(itc);
2172 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2173 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2175 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2177 if ((!calc) && (it->wd->decorate_mode) && (it->item->type != ELM_GENLIST_ITEM_GROUP))
2179 if (it->itc->decorate_all_item_style)
2181 if (!it->edit_obj) _decorate_mode_item_realize(it, EINA_FALSE);
2182 edje_object_message_signal_process(it->edit_obj);
2185 edje_object_message_signal_process(VIEW(it));
2189 _item_unrealize_cb(Elm_Gen_Item *it)
2191 if (it->item->nocache_once || it->item->nocache)
2193 evas_object_del(VIEW(it));
2197 evas_object_del(it->spacer);
2203 edje_object_mirrored_set(VIEW(it),
2204 elm_widget_mirrored_get(WIDGET(it)));
2205 edje_object_scale_set(VIEW(it),
2206 elm_widget_scale_get(WIDGET(it))
2207 * _elm_config->scale);
2208 _item_cache_add(it);
2211 _mode_item_unrealize(it);
2213 it->realized = EINA_FALSE;
2214 it->want_unrealize = EINA_FALSE;
2215 if (it->wd->decorate_mode) _decorate_mode_item_unrealize(it);
2219 _item_block_recalc(Item_Block *itb,
2225 Evas_Coord minw = 0, minh = 0;
2226 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2229 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2231 EINA_LIST_FOREACH(itb->items, l, it)
2233 if (it->generation < it->wd->generation) continue;
2234 showme |= it->item->showme;
2239 if (!it->item->mincalcd) changed = EINA_TRUE;
2242 _item_realize(it, in, EINA_TRUE);
2243 _elm_genlist_item_unrealize(it, EINA_TRUE);
2248 _item_realize(it, in, EINA_TRUE);
2249 _elm_genlist_item_unrealize(it, EINA_TRUE);
2253 _item_realize(it, in, EINA_FALSE);
2254 minh += it->item->minh;
2255 if (minw < it->item->minw) minw = it->item->minw;
2263 itb->changed = EINA_FALSE;
2264 itb->position_update = EINA_FALSE;
2265 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2266 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2271 _item_block_realize(Item_Block *itb)
2273 if (itb->realized) return;
2274 itb->realized = EINA_TRUE;
2275 itb->want_unrealize = EINA_FALSE;
2279 _item_block_unrealize(Item_Block *itb)
2283 Eina_Bool dragging = EINA_FALSE;
2285 if (!itb->realized) return;
2286 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2287 EINA_LIST_FOREACH(itb->items, l, it)
2289 if (itb->must_recalc || !it->group)
2293 dragging = EINA_TRUE;
2294 it->want_unrealize = EINA_TRUE;
2297 _elm_genlist_item_unrealize(it, EINA_FALSE);
2302 itb->realized = EINA_FALSE;
2303 itb->want_unrealize = EINA_TRUE;
2306 itb->want_unrealize = EINA_FALSE;
2307 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2308 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2312 _get_space_for_reorder_item(Elm_Gen_Item *it)
2314 Evas_Coord rox, roy, row, roh, oy, oh;
2315 Eina_Bool top = EINA_FALSE;
2316 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2317 if (!reorder_it) return 0;
2319 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2320 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2322 if ((it->wd->reorder_start_y < it->item->block->y) &&
2323 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2325 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2326 if (it->item->block->count == 1)
2327 it->wd->reorder_rel = it;
2329 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2330 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2332 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2335 it->item->block->reorder_offset = 0;
2337 it->item->scrl_y += it->item->block->reorder_offset;
2339 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2340 rox, roy + (roh / 2), row, 1));
2343 it->wd->reorder_rel = it;
2344 it->item->scrl_y += it->wd->reorder_it->item->h;
2345 return it->wd->reorder_it->item->h;
2352 _reorder_move_animator_cb(void *data)
2354 Elm_Gen_Item *it = data;
2355 Eina_Bool down = EINA_FALSE;
2357 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2359 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2361 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2364 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2365 if (diff > it->item->h) y = diff / 2;
2367 if (it->item->old_scrl_y < it->item->scrl_y)
2369 it->item->old_scrl_y += y;
2372 else if (it->item->old_scrl_y > it->item->scrl_y)
2374 it->item->old_scrl_y -= y;
2379 _item_position(it, it->edit_obj, it->item->scrl_x, it->item->old_scrl_y);
2381 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2382 _group_items_recalc(it->wd);
2384 if ((it->wd->reorder_pan_move) ||
2385 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2386 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2388 it->item->old_scrl_y = it->item->scrl_y;
2389 it->item->move_effect_enabled = EINA_FALSE;
2390 it->wd->reorder_move_animator = NULL;
2391 return ECORE_CALLBACK_CANCEL;
2393 return ECORE_CALLBACK_RENEW;
2397 _item_position(Elm_Gen_Item *it,
2405 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2406 evas_object_resize(view, it->item->w, it->item->h);
2407 evas_object_move(view, it_x, it_y);
2408 evas_object_show(view);
2409 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2410 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2414 _item_block_position(Item_Block *itb,
2420 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2421 Eina_Bool vis = EINA_FALSE;
2423 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2424 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2425 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2427 EINA_LIST_FOREACH(itb->items, l, it)
2429 if (it->generation < it->wd->generation) continue;
2430 else if (it->wd->reorder_it == it) continue;
2433 it->item->w = itb->w;
2434 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2435 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2437 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2438 cvx, cvy, cvw, cvh));
2441 if ((itb->realized) && (!it->realized))
2443 if (vis) _item_realize(it, in, EINA_FALSE);
2447 if (vis || it->dragging)
2449 if (it->wd->reorder_mode)
2450 y += _get_space_for_reorder_item(it);
2451 git = it->item->group_item;
2454 if (git->item->scrl_y < oy)
2455 git->item->scrl_y = oy;
2456 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2457 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2458 git->item->want_realize = EINA_TRUE;
2460 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2462 if (!it->item->move_effect_enabled)
2464 it->item->move_effect_enabled = EINA_TRUE;
2465 it->wd->reorder_move_animator =
2467 _reorder_move_animator_cb, it);
2470 if (!it->item->move_effect_enabled)
2472 if ((it->wd->decorate_mode) && (it->itc->decorate_all_item_style))
2473 _decorate_mode_item_position(it, it->item->scrl_x,
2477 if (it->item->mode_view)
2478 _item_position(it, it->item->mode_view,
2482 _item_position(it, VIEW(it), it->item->scrl_x,
2485 it->item->old_scrl_y = it->item->scrl_y;
2490 if (!it->wd->tree_effect_animator)
2491 _elm_genlist_item_unrealize(it, EINA_FALSE);
2498 if (vis) it->item->want_realize = EINA_TRUE;
2502 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2503 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2507 _group_items_recalc(void *data)
2509 Widget_Data *wd = data;
2513 evas_event_freeze(evas_object_evas_get(wd->obj));
2514 EINA_LIST_FOREACH(wd->group_items, l, git)
2516 if (git->item->want_realize)
2519 _item_realize(git, 0, EINA_FALSE);
2520 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2521 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2522 evas_object_show(VIEW(git));
2523 evas_object_raise(VIEW(git));
2525 else if (!git->item->want_realize && git->realized)
2528 _elm_genlist_item_unrealize(git, EINA_FALSE);
2531 evas_event_thaw(evas_object_evas_get(wd->obj));
2532 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2536 _must_recalc_idler(void *data)
2538 Widget_Data *wd = data;
2539 if (wd->calc_job) ecore_job_del(wd->calc_job);
2540 wd->calc_job = ecore_job_add(_calc_job, wd);
2541 wd->must_recalc_idler = NULL;
2542 return ECORE_CALLBACK_CANCEL;
2546 _scroll_item(Widget_Data *wd)
2548 Elm_Gen_Item *it = NULL;
2549 Evas_Coord gith = 0;
2550 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2551 if (!wd->show_item) return;
2553 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2555 dx = it->x + it->item->block->x;
2556 dy = it->y + it->item->block->y;
2557 dw = it->item->block->w;
2559 switch (wd->scrollto_type)
2561 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2562 if (it->item->group_item) gith = it->item->group_item->item->h;
2565 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2566 dy += (it->item->h / 2 - oh / 2);
2568 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2570 if ((wd->expanded_item) &&
2571 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2572 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2574 it = wd->expanded_item;
2575 if (it->item->group_item) gith = it->item->group_item->item->h;
2576 dx = it->x + it->item->block->x;
2577 dy = it->y + it->item->block->y - gith;
2578 dw = it->item->block->w;
2582 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2583 gith = it->item->group_item->item->h;
2590 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2592 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2594 it->item->showme = EINA_FALSE;
2595 wd->show_item = NULL;
2596 wd->auto_scroll_enabled = EINA_FALSE;
2597 wd->check_scroll = EINA_FALSE;
2601 _calc_job(void *data)
2603 Widget_Data *wd = data;
2604 Item_Block *itb, *chb = NULL;
2605 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2606 Evas_Coord pan_w = 0, pan_h = 0;
2608 Eina_Bool minw_change = EINA_FALSE;
2609 Eina_Bool did_must_recalc = EINA_FALSE;
2612 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2613 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2618 evas_event_freeze(evas_object_evas_get(wd->obj));
2619 EINA_INLIST_FOREACH(wd->blocks, itb)
2621 Eina_Bool showme = EINA_FALSE;
2624 showme = itb->showme;
2625 itb->showme = EINA_FALSE;
2628 if (itb->realized) _item_block_unrealize(itb);
2630 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2632 if (itb->must_recalc)
2636 EINA_LIST_FOREACH(itb->items, l, it)
2637 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2638 itb->changed = EINA_TRUE;
2639 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2640 if (itb->realized) _item_block_unrealize(itb);
2641 itb->must_recalc = EINA_FALSE;
2643 showme = _item_block_recalc(itb, in, EINA_FALSE);
2649 if (minw == -1) minw = itb->minw;
2650 else if ((!itb->must_recalc) && (minw < itb->minw))
2653 minw_change = EINA_TRUE;
2658 minw_change = EINA_TRUE;
2664 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2665 wd->check_scroll = EINA_TRUE;
2669 EINA_INLIST_FOREACH(wd->blocks, itb)
2675 if ((chb) && (EINA_INLIST_GET(chb)->next))
2677 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2679 if (itb->realized) _item_block_unrealize(itb);
2682 wd->realminw = minw;
2683 if (minw < wd->w) minw = wd->w;
2684 if ((minw != wd->minw) || (minh != wd->minh))
2688 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2689 _sizing_eval(wd->obj);
2690 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2695 it = wd->anchor_item;
2696 it_y = wd->anchor_y;
2697 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2698 it->item->block->y + it->y + it_y);
2699 wd->anchor_item = it;
2700 wd->anchor_y = it_y;
2703 if (did_must_recalc)
2705 if (!wd->must_recalc_idler)
2706 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2708 if (wd->check_scroll)
2710 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2711 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2712 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2713 switch (wd->scrollto_type)
2715 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2718 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2721 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2728 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2729 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2735 wd->calc_job = NULL;
2736 evas_object_smart_changed(wd->pan_smart);
2737 evas_event_thaw(evas_object_evas_get(wd->obj));
2738 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2742 _update_job(void *data)
2744 Widget_Data *wd = data;
2748 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2750 wd->update_job = NULL;
2753 evas_event_freeze(evas_object_evas_get(wd->obj));
2754 EINA_INLIST_FOREACH(wd->blocks, itb)
2756 Evas_Coord itminw, itminh;
2763 _item_block_position(itb, num);
2767 recalc = EINA_FALSE;
2768 EINA_LIST_FOREACH(itb->items, l2, it)
2770 if (it->item->updateme)
2772 itminw = it->item->minw;
2773 itminh = it->item->minh;
2775 it->item->updateme = EINA_FALSE;
2778 _elm_genlist_item_unrealize(it, EINA_FALSE);
2779 _item_realize(it, num, EINA_FALSE);
2780 position = EINA_TRUE;
2784 _item_realize(it, num, EINA_TRUE);
2785 _elm_genlist_item_unrealize(it, EINA_TRUE);
2787 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2792 itb->updateme = EINA_FALSE;
2795 position = EINA_TRUE;
2796 itb->changed = EINA_TRUE;
2797 _item_block_recalc(itb, num0, EINA_FALSE);
2798 _item_block_position(itb, num0);
2803 if (wd->calc_job) ecore_job_del(wd->calc_job);
2804 wd->calc_job = ecore_job_add(_calc_job, wd);
2806 evas_event_thaw(evas_object_evas_get(wd->obj));
2807 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2811 _pan_set(Evas_Object *obj,
2815 Pan *sd = evas_object_smart_data_get(obj);
2819 // Evas_Coord ow, oh;
2820 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2821 // ow = sd->wd->minw - ow;
2822 // if (ow < 0) ow = 0;
2823 // oh = sd->wd->minh - oh;
2824 // if (oh < 0) oh = 0;
2825 // if (x < 0) x = 0;
2826 // if (y < 0) y = 0;
2827 // if (x > ow) x = ow;
2828 // if (y > oh) y = oh;
2829 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2833 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2835 if ((itb->y + itb->h) > y)
2840 EINA_LIST_FOREACH(itb->items, l2, it)
2842 if ((itb->y + it->y) >= y)
2844 sd->wd->anchor_item = it;
2845 sd->wd->anchor_y = -(itb->y + it->y - y);
2852 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2856 _pan_get(Evas_Object *obj,
2860 Pan *sd = evas_object_smart_data_get(obj);
2863 if (x) *x = sd->wd->pan_x;
2864 if (y) *y = sd->wd->pan_y;
2868 _pan_max_get(Evas_Object *obj,
2872 Pan *sd = evas_object_smart_data_get(obj);
2876 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2877 ow = sd->wd->minw - ow;
2879 oh = sd->wd->minh - oh;
2886 _pan_min_get(Evas_Object *obj __UNUSED__,
2895 _pan_child_size_get(Evas_Object *obj,
2899 Pan *sd = evas_object_smart_data_get(obj);
2902 if (w) *w = sd->wd->minw;
2903 if (h) *h = sd->wd->minh;
2907 _pan_add(Evas_Object *obj)
2910 Evas_Object_Smart_Clipped_Data *cd;
2913 cd = evas_object_smart_data_get(obj);
2916 sd->__clipped_data = *cd;
2918 evas_object_smart_data_set(obj, sd);
2922 _pan_del(Evas_Object *obj)
2924 Pan *sd = evas_object_smart_data_get(obj);
2929 ecore_job_del(sd->resize_job);
2930 sd->resize_job = NULL;
2936 _pan_resize_job(void *data)
2940 _sizing_eval(sd->wd->obj);
2941 sd->resize_job = NULL;
2945 _pan_resize(Evas_Object *obj,
2949 Pan *sd = evas_object_smart_data_get(obj);
2953 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2954 if ((ow == w) && (oh == h)) return;
2955 if ((sd->wd->mode == ELM_LIST_COMPRESS) && (ow != w))
2958 if (sd->resize_job) ecore_job_del(sd->resize_job);
2959 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2961 sd->wd->pan_changed = EINA_TRUE;
2962 evas_object_smart_changed(obj);
2963 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2964 sd->wd->calc_job = NULL;
2966 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2967 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2972 _pan_calculate(Evas_Object *obj)
2974 Pan *sd = evas_object_smart_data_get(obj);
2976 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2982 evas_event_freeze(evas_object_evas_get(obj));
2984 if (sd->wd->pan_changed)
2987 sd->wd->pan_changed = EINA_FALSE;
2990 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2991 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2992 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2994 git->item->want_realize = EINA_FALSE;
2996 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2998 itb->w = sd->wd->minw;
2999 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
3000 itb->y - sd->wd->pan_y + oy,
3002 cvx, cvy, cvw, cvh))
3004 if ((!itb->realized) || (itb->changed))
3005 _item_block_realize(itb);
3006 _item_block_position(itb, in);
3010 if (itb->realized) _item_block_unrealize(itb);
3014 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
3015 _group_items_recalc(sd->wd);
3016 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
3018 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
3019 sd->wd->reorder_pan_move = EINA_TRUE;
3020 else sd->wd->reorder_pan_move = EINA_FALSE;
3021 evas_object_raise(sd->wd->VIEW(reorder_it));
3022 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
3023 sd->wd->start_time = ecore_loop_time_get();
3026 if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
3028 if (!sd->wd->tree_effect_animator)
3030 _item_tree_effect_before(sd->wd->expanded_item);
3031 evas_object_raise(sd->wd->alpha_bg);
3032 evas_object_show(sd->wd->alpha_bg);
3033 sd->wd->start_time = ecore_time_get();
3034 sd->wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, sd->wd);
3038 _item_auto_scroll(sd->wd);
3040 evas_event_thaw(evas_object_evas_get(obj));
3041 evas_event_thaw_eval(evas_object_evas_get(obj));
3045 _pan_move(Evas_Object *obj,
3046 Evas_Coord x __UNUSED__,
3047 Evas_Coord y __UNUSED__)
3049 Pan *sd = evas_object_smart_data_get(obj);
3053 sd->wd->pan_changed = EINA_TRUE;
3054 evas_object_smart_changed(obj);
3055 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3056 sd->wd->calc_job = NULL;
3060 _hold_on(void *data __UNUSED__,
3062 void *event_info __UNUSED__)
3064 Widget_Data *wd = elm_widget_data_get(obj);
3066 elm_smart_scroller_hold_set(wd->scr, 1);
3070 _hold_off(void *data __UNUSED__,
3072 void *event_info __UNUSED__)
3074 Widget_Data *wd = elm_widget_data_get(obj);
3076 elm_smart_scroller_hold_set(wd->scr, 0);
3080 _freeze_on(void *data __UNUSED__,
3082 void *event_info __UNUSED__)
3084 Widget_Data *wd = elm_widget_data_get(obj);
3086 elm_smart_scroller_freeze_set(wd->scr, 1);
3090 _freeze_off(void *data __UNUSED__,
3092 void *event_info __UNUSED__)
3094 Widget_Data *wd = elm_widget_data_get(obj);
3096 elm_smart_scroller_freeze_set(wd->scr, 0);
3100 _scr_anim_start(void *data,
3101 Evas_Object *obj __UNUSED__,
3102 void *event_info __UNUSED__)
3104 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3108 _scr_anim_stop(void *data,
3109 Evas_Object *obj __UNUSED__,
3110 void *event_info __UNUSED__)
3112 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3116 _scr_drag_start(void *data,
3117 Evas_Object *obj __UNUSED__,
3118 void *event_info __UNUSED__)
3120 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3124 _scr_drag_stop(void *data,
3125 Evas_Object *obj __UNUSED__,
3126 void *event_info __UNUSED__)
3128 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3132 _edge_left(void *data,
3133 Evas_Object *scr __UNUSED__,
3134 void *event_info __UNUSED__)
3136 Evas_Object *obj = data;
3137 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3141 _edge_right(void *data,
3142 Evas_Object *scr __UNUSED__,
3143 void *event_info __UNUSED__)
3145 Evas_Object *obj = data;
3146 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3150 _edge_top(void *data,
3151 Evas_Object *scr __UNUSED__,
3152 void *event_info __UNUSED__)
3154 Evas_Object *obj = data;
3155 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3159 _edge_bottom(void *data,
3160 Evas_Object *scr __UNUSED__,
3161 void *event_info __UNUSED__)
3163 Evas_Object *obj = data;
3164 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3168 _mode_item_realize(Elm_Gen_Item *it)
3172 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
3174 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3175 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3176 edje_object_scale_set(it->item->mode_view,
3177 elm_widget_scale_get(WIDGET(it)) *
3178 _elm_config->scale);
3179 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
3180 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
3182 strncpy(buf, "item", sizeof(buf));
3183 if (it->wd->mode == ELM_LIST_COMPRESS)
3184 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3186 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3187 strncat(buf, "/", sizeof(buf) - strlen(buf));
3188 strncat(buf, it->itc->decorate_item_style, sizeof(buf) - strlen(buf));
3190 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
3191 elm_widget_style_get(WIDGET(it)));
3192 edje_object_mirrored_set(it->item->mode_view,
3193 elm_widget_mirrored_get(WIDGET(it)));
3195 /* signal callback add */
3196 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
3198 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
3200 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
3203 /* text_get, content_get, state_get */
3204 /* FIXME: If you see that assert, please notify us and we
3205 will clean our mess */
3206 assert(eina_list_count(it->item->mode_content_objs) == 0);
3208 _item_text_realize(it, it->item->mode_view, &it->item->mode_texts, NULL);
3209 it->item->mode_content_objs =
3210 _item_content_realize(it, it->item->mode_view,
3211 &it->item->mode_contents, NULL);
3212 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
3214 edje_object_part_swallow(it->item->mode_view,
3215 edje_object_data_get(it->item->mode_view, "mode_part"),
3218 it->want_unrealize = EINA_FALSE;
3219 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3220 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3224 _mode_item_unrealize(Elm_Gen_Item *it)
3226 Widget_Data *wd = it->wd;
3227 Evas_Object *content;
3228 if (!it->item->mode_view) return;
3230 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3231 elm_widget_stringlist_free(it->item->mode_texts);
3232 it->item->mode_texts = NULL;
3233 elm_widget_stringlist_free(it->item->mode_contents);
3234 it->item->mode_contents = NULL;
3235 elm_widget_stringlist_free(it->item->mode_states);
3237 EINA_LIST_FREE(it->item->mode_content_objs, content)
3238 evas_object_del(content);
3240 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
3241 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3242 evas_object_del(it->item->mode_view);
3243 it->item->mode_view = NULL;
3245 if (wd->mode_item == it)
3246 wd->mode_item = NULL;
3247 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3248 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3252 _item_mode_set(Elm_Gen_Item *it)
3255 Widget_Data *wd = it->wd;
3260 it->item->nocache_once = EINA_TRUE;
3262 if (wd->scr_hold_timer)
3264 ecore_timer_del(wd->scr_hold_timer);
3265 wd->scr_hold_timer = NULL;
3267 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3268 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3270 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3271 _mode_item_realize(it);
3272 if (it->item->group_item)
3273 evas_object_raise(it->item->VIEW(group_item));
3274 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
3275 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3276 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3278 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->decorate_type);
3279 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3283 _item_mode_unset(Widget_Data *wd)
3286 if (!wd->mode_item) return;
3287 char buf[1024], buf2[1024];
3291 it->item->nocache_once = EINA_TRUE;
3293 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->decorate_type);
3294 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->decorate_type);
3296 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3297 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
3299 wd->mode_item = NULL;
3303 _decorate_mode_item_position(Elm_Gen_Item *it, int itx, int ity)
3305 if ((!it) || (!it->wd->decorate_mode)) return;
3306 evas_object_resize(it->edit_obj, it->item->w, it->item->h);
3307 evas_object_move(it->edit_obj, itx, ity);
3311 _decorate_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3314 const char *stacking_even;
3315 const char *stacking;
3317 if ((!it) || (it->item->decorate_mode_item_realized) ||
3318 (it->generation < it->wd->generation))
3321 it->edit_obj = edje_object_add(evas_object_evas_get(WIDGET(it)));
3322 edje_object_scale_set(it->edit_obj, elm_widget_scale_get(WIDGET(it)) *
3323 _elm_config->scale);
3324 evas_object_smart_member_add(it->edit_obj, it->wd->pan_smart);
3325 elm_widget_sub_object_add(WIDGET(it), it->edit_obj);
3327 if (it->item->type & ELM_GENLIST_ITEM_TREE)
3328 strncpy(buf, "tree", sizeof(buf));
3329 else strncpy(buf, "item", sizeof(buf));
3330 if (it->wd->mode == ELM_LIST_COMPRESS)
3331 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3333 strncat(buf, "/", sizeof(buf) - strlen(buf));
3334 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf));
3336 _elm_theme_object_set(WIDGET(it), it->edit_obj, "genlist", buf,
3337 elm_widget_style_get(WIDGET(it)));
3339 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3340 if (!stacking_even) stacking_even = "above";
3341 it->item->stacking_even = !!strcmp("above", stacking_even);
3343 stacking = edje_object_data_get(VIEW(it), "stacking");
3344 if (!stacking) stacking = "yes";
3345 it->item->nostacking = !!strcmp("yes", stacking);
3347 edje_object_mirrored_set(it->edit_obj,
3348 elm_widget_mirrored_get(WIDGET(it)));
3350 _elm_genlist_item_odd_even_update(it);
3351 _elm_genlist_item_state_update(it, NULL);
3353 if (effect_on) edje_object_signal_emit(it->edit_obj, "elm,state,edit,enabled,effect", "elm");
3354 else edje_object_signal_emit(it->edit_obj, "elm,state,edit,enabled", "elm");
3356 _item_mouse_callbacks_del(it, VIEW(it));
3357 _item_mouse_callbacks_add(it, it->edit_obj);
3359 _item_text_realize(it, it->edit_obj, &it->item->edit_texts, NULL);
3360 if (it->flipped) edje_object_signal_emit(it->edit_obj, "elm,state,flip,enabled", "elm");
3361 it->item->edit_content_objs =
3362 _item_content_realize(it, it->edit_obj, &it->item->edit_contents, NULL);
3363 _item_state_realize(it, it->edit_obj, &it->item->edit_states, NULL);
3364 edje_object_part_swallow(it->edit_obj, "elm.swallow.edit.content", VIEW(it));
3366 _decorate_mode_item_position(it, it->item->scrl_x, it->item->scrl_y);
3367 evas_object_show(it->edit_obj);
3369 it->item->decorate_mode_item_realized = EINA_TRUE;
3370 it->want_unrealize = EINA_FALSE;
3374 _decorate_mode_item_unrealize(Elm_Gen_Item *it)
3377 if ((!it) || (!it->item->decorate_mode_item_realized)) return;
3379 edje_object_part_unswallow(it->edit_obj, VIEW(it));
3380 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3381 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3382 _elm_genlist_item_odd_even_update(it);
3383 _elm_genlist_item_state_update(it, NULL);
3385 evas_object_del(it->edit_obj);
3386 it->edit_obj = NULL;
3387 elm_widget_stringlist_free(it->item->edit_texts);
3388 it->item->edit_texts = NULL;
3389 elm_widget_stringlist_free(it->item->edit_contents);
3390 it->item->edit_contents = NULL;
3391 elm_widget_stringlist_free(it->item->edit_states);
3392 it->item->edit_states = NULL;
3393 EINA_LIST_FREE(it->item->edit_content_objs, icon)
3394 evas_object_del(icon);
3395 edje_object_message_signal_process(it->edit_obj);
3396 _item_mouse_callbacks_del(it, it->edit_obj);
3397 _item_mouse_callbacks_add(it, VIEW(it));
3399 it->item->decorate_mode_item_realized = EINA_FALSE;
3403 _item_auto_scroll(Widget_Data *wd)
3406 Elm_Gen_Item *tmp_item = NULL;
3408 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3410 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3411 if (!tmp_item) return;
3412 wd->show_item = tmp_item;
3413 wd->bring_in = EINA_TRUE;
3414 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3415 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3417 wd->show_item->item->showme = EINA_TRUE;
3418 wd->auto_scroll_enabled = EINA_FALSE;
3426 elm_genlist_add(Evas_Object *parent)
3431 Evas_Coord minw, minh;
3432 static Evas_Smart *smart = NULL;
3436 static Evas_Smart_Class sc;
3438 evas_object_smart_clipped_smart_set(&_pan_sc);
3440 sc.name = "elm_genlist_pan";
3441 sc.version = EVAS_SMART_CLASS_VERSION;
3444 sc.resize = _pan_resize;
3445 sc.move = _pan_move;
3446 sc.calculate = _pan_calculate;
3447 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3450 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3452 ELM_SET_WIDTYPE(widtype, "genlist");
3454 elm_widget_type_set(obj, "genlist");
3455 elm_widget_sub_object_add(parent, obj);
3456 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3457 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3458 elm_widget_data_set(obj, wd);
3459 elm_widget_del_hook_set(obj, _del_hook);
3460 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3461 elm_widget_theme_hook_set(obj, _theme_hook);
3462 elm_widget_can_focus_set(obj, EINA_TRUE);
3463 elm_widget_event_hook_set(obj, _event_hook);
3464 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3465 elm_widget_translate_hook_set(obj, _translate_hook);
3468 wd->scr = elm_smart_scroller_add(e);
3469 elm_smart_scroller_widget_set(wd->scr, obj);
3470 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3471 elm_widget_style_get(obj));
3472 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3473 _elm_config->thumbscroll_bounce_enable);
3474 elm_widget_resize_object_set(obj, wd->scr);
3476 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3477 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3478 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3479 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3480 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3481 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3482 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3483 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3486 wd->mode = ELM_LIST_SCROLL;
3487 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3488 wd->item_cache_max = wd->max_items_per_block * 2;
3489 wd->longpress_timeout = _elm_config->longpress_timeout;
3490 wd->highlight = EINA_TRUE;
3492 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3493 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3494 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3495 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3497 wd->pan_smart = evas_object_smart_add(e, smart);
3498 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3501 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3502 _pan_set, _pan_get, _pan_max_get,
3503 _pan_min_get, _pan_child_size_get);
3505 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3507 evas_object_size_hint_min_set(obj, minw, minh);
3509 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3511 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3517 _item_select(Elm_Gen_Item *it)
3519 if ((it->generation < it->wd->generation) || (it->mode_set) ||
3520 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3521 (it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3525 it->selected = EINA_TRUE;
3526 it->wd->selected = eina_list_append(it->wd->selected, it);
3528 else if (it->wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) return;
3530 evas_object_ref(WIDGET(it));
3533 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3534 if (it->generation == it->wd->generation)
3535 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3538 if ((it->wd->clear_me) && (!it->wd->walking))
3539 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3542 if ((!it->walking) && (it->generation < it->wd->generation))
3547 elm_widget_item_free(it);
3551 it->wd->last_selected_item = (Elm_Object_Item *)it;
3553 evas_object_unref(WIDGET(it));
3556 static Evas_Object *
3557 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3559 return edje_object_part_swallow_get(VIEW(it), part);
3563 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3565 if (content && part)
3567 it->content_objs = eina_list_append(it->content_objs, content);
3568 edje_object_part_swallow(VIEW(it), part, content);
3572 static Evas_Object *
3573 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3576 obj = edje_object_part_swallow_get(VIEW(it), part);
3577 if (!obj) return NULL;
3578 it->content_objs = eina_list_remove(it->content_objs, obj);
3579 edje_object_part_unswallow(VIEW(it), obj);
3584 _item_text_hook(Elm_Gen_Item *it, const char *part)
3586 if (!it->itc->func.text_get) return NULL;
3587 return edje_object_part_text_get(VIEW(it), part);
3591 _item_disable_hook(Elm_Object_Item *it)
3595 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3597 if (_it->generation < _it->wd->generation) return;
3600 elm_genlist_item_selected_set(it, EINA_FALSE);
3604 if (elm_widget_item_disabled_get(it))
3606 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
3608 edje_object_signal_emit(_it->edit_obj, "elm,state,disabled", "elm");
3612 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
3614 edje_object_signal_emit(_it->edit_obj, "elm,state,enabled", "elm");
3616 EINA_LIST_FOREACH(_it->content_objs, l, obj)
3617 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
3622 _item_del_pre_hook(Elm_Object_Item *it)
3624 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
3626 if ((_it->relcount > 0) || (_it->walking > 0))
3628 elm_genlist_item_subitems_clear(it);
3629 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
3630 _elm_genlist_item_del_notserious(_it);
3631 if (_it->item->block)
3633 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
3634 _it->item->block->changed = EINA_TRUE;
3635 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
3636 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
3640 _it->parent->item->items =
3641 eina_list_remove(_it->parent->item->items, it);
3651 _item_signal_emit_hook(Elm_Object_Item *it,
3652 const char *emission,
3655 edje_object_signal_emit(VIEW(it), emission, source);
3659 _elm_genlist_item_new(Widget_Data *wd,
3660 const Elm_Gen_Item_Class *itc,
3662 Elm_Gen_Item *parent,
3664 const void *func_data)
3668 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3669 if (!it) return NULL;
3671 it->generation = wd->generation;
3673 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
3674 it->base.data = data;
3675 it->parent = parent;
3676 it->func.func = func;
3677 it->func.data = func_data;
3678 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3679 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3680 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3681 elm_widget_item_text_get_hook_set(it, _item_text_hook);
3682 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3683 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3684 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
3687 it->sel_cb = (Ecore_Cb)_item_select;
3692 static Elm_Gen_Item *
3693 _item_new(Widget_Data *wd,
3694 const Elm_Genlist_Item_Class *itc,
3696 Elm_Gen_Item *parent,
3697 Elm_Genlist_Item_Type type,
3699 const void *func_data)
3701 Elm_Gen_Item *it, *it2;
3704 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3705 if (!it) return NULL;
3706 it->item = ELM_NEW(Elm_Gen_Item_Type);
3707 it->item->type = type;
3708 if (type & ELM_GENLIST_ITEM_GROUP) it->group++;
3709 it->item->expanded_depth = 0;
3710 ELM_GEN_ITEM_SETUP(it);
3713 if (it->parent->group)
3714 it->item->group_item = parent;
3715 else if (it->parent->item->group_item)
3716 it->item->group_item = it->parent->item->group_item;
3718 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3720 if (!it2->parent->group) depth += 1;
3722 it->item->expanded_depth = depth;
3728 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3732 itb = calloc(1, sizeof(Item_Block));
3733 if (!itb) return NULL;
3737 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3738 _item_block_position_update(wd->blocks, 0);
3742 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3743 itb->position_update = EINA_TRUE;
3744 if (wd->blocks != EINA_INLIST_GET(itb))
3746 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3757 _item_block_add(Widget_Data *wd,
3760 Item_Block *itb = NULL;
3767 itb = calloc(1, sizeof(Item_Block));
3768 if (!itb) return EINA_FALSE;
3770 if (!it->item->rel->item->block)
3773 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3774 itb->items = eina_list_append(itb->items, it);
3775 itb->position_update = EINA_TRUE;
3776 it->position = eina_list_count(itb->items);
3777 it->position_update = EINA_TRUE;
3779 if (wd->blocks != EINA_INLIST_GET(itb))
3781 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3792 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3793 if (it->item->before)
3795 wd->blocks = eina_inlist_prepend_relative
3796 (wd->blocks, EINA_INLIST_GET(itb),
3797 EINA_INLIST_GET(it->item->rel->item->block));
3799 eina_list_prepend_relative_list(itb->items, it, tmp);
3801 /* Update index from where we prepended */
3802 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3803 _item_block_position_update(EINA_INLIST_GET(itb),
3804 it->item->rel->item->block->position);
3808 wd->blocks = eina_inlist_append_relative
3809 (wd->blocks, EINA_INLIST_GET(itb),
3810 EINA_INLIST_GET(it->item->rel->item->block));
3812 eina_list_append_relative_list(itb->items, it, tmp);
3814 /* Update block index from where we appended */
3815 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3816 _item_block_position_update(EINA_INLIST_GET(itb),
3817 it->item->rel->item->block->position + 1);
3823 if (it->item->before)
3827 itb = (Item_Block *)(wd->blocks);
3828 if (itb->count >= wd->max_items_per_block)
3830 itb = _item_block_new(wd, EINA_TRUE);
3831 if (!itb) return EINA_FALSE;
3836 itb = _item_block_new(wd, EINA_TRUE);
3837 if (!itb) return EINA_FALSE;
3839 itb->items = eina_list_prepend(itb->items, it);
3841 _item_position_update(itb->items, 0);
3847 itb = (Item_Block *)(wd->blocks->last);
3848 if (itb->count >= wd->max_items_per_block)
3850 itb = _item_block_new(wd, EINA_FALSE);
3851 if (!itb) return EINA_FALSE;
3856 itb = _item_block_new(wd, EINA_FALSE);
3857 if (!itb) return EINA_FALSE;
3859 itb->items = eina_list_append(itb->items, it);
3860 it->position = eina_list_count(itb->items);
3868 if (it->item->rel->item->queued)
3870 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3871 on sorted insertion order, so the queue is not always ordered like the item list.
3872 This lead to issue where we depend on an item that is not yet created. As a quick
3873 work around, we reschedule the calc of the item and stop reordering the list to
3874 prevent any nasty issue to show up here.
3876 wd->queue = eina_list_append(wd->queue, it);
3877 wd->requeued = EINA_TRUE;
3878 it->item->queued = EINA_TRUE;
3881 itb = it->item->rel->item->block;
3882 if (!itb) goto newblock;
3883 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3884 if (it->item->before)
3886 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3887 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3891 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3892 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3896 itb->changed = EINA_TRUE;
3897 it->item->block = itb;
3898 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3899 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3902 it->item->rel->relcount--;
3903 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3905 _item_del(it->item->rel);
3906 elm_widget_item_free(it->item->rel);
3908 it->item->rel = NULL;
3910 if (itb->count > itb->wd->max_items_per_block)
3915 Eina_Bool done = EINA_FALSE;
3917 newc = itb->count / 2;
3919 if (EINA_INLIST_GET(itb)->prev)
3921 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3923 if (itbp->count + newc < wd->max_items_per_block / 2)
3925 /* moving items to previous block */
3926 while ((itb->count > newc) && (itb->items))
3928 it2 = eina_list_data_get(itb->items);
3929 itb->items = eina_list_remove_list(itb->items, itb->items);
3932 itbp->items = eina_list_append(itbp->items, it2);
3933 it2->item->block = itbp;
3941 if (!done && EINA_INLIST_GET(itb)->next)
3943 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3945 if (itbn->count + newc < wd->max_items_per_block / 2)
3947 /* moving items to next block */
3948 while ((itb->count > newc) && (itb->items))
3952 l = eina_list_last(itb->items);
3953 it2 = eina_list_data_get(l);
3954 itb->items = eina_list_remove_list(itb->items, l);
3957 itbn->items = eina_list_prepend(itbn->items, it2);
3958 it2->item->block = itbn;
3968 /* moving items to new block */
3969 itb2 = calloc(1, sizeof(Item_Block));
3970 if (!itb2) return EINA_FALSE;
3973 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3974 EINA_INLIST_GET(itb));
3975 itb2->changed = EINA_TRUE;
3976 while ((itb->count > newc) && (itb->items))
3980 l = eina_list_last(itb->items);
3982 itb->items = eina_list_remove_list(itb->items, l);
3985 itb2->items = eina_list_prepend(itb2->items, it2);
3986 it2->item->block = itb2;
3996 _queue_process(Widget_Data *wd)
3999 Eina_Bool showme = EINA_FALSE;
4002 t0 = ecore_loop_time_get();
4003 //evas_event_freeze(evas_object_evas_get(wd->obj));
4004 for (n = 0; (wd->queue) && (n < 128); n++)
4008 it = eina_list_data_get(wd->queue);
4009 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
4010 it->item->queued = EINA_FALSE;
4011 if (!_item_block_add(wd, it)) continue;
4013 _item_block_realize(it->item->block);
4014 t = ecore_time_get();
4015 if (it->item->block->changed)
4017 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
4018 it->item->block->changed = 0;
4019 if (wd->pan_changed)
4021 if (wd->calc_job) ecore_job_del(wd->calc_job);
4022 wd->calc_job = NULL;
4024 wd->pan_changed = EINA_FALSE;
4027 if (showme) it->item->block->showme = EINA_TRUE;
4028 /* same as eina_inlist_count > 1 */
4029 if (wd->blocks && wd->blocks->next)
4031 if ((t - t0) > (ecore_animator_frametime_get())) break;
4034 //evas_event_thaw(evas_object_evas_get(wd->obj));
4035 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4040 _idle_process(void *data, Eina_Bool *wakeup)
4042 Widget_Data *wd = data;
4045 //static double q_start = 0.0;
4046 //if (q_start == 0.0) q_start = ecore_time_get();
4048 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
4052 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
4054 return ECORE_CALLBACK_CANCEL;
4056 return ECORE_CALLBACK_RENEW;
4060 _item_idle_enterer(void *data)
4062 Widget_Data *wd = data;
4063 Eina_Bool wakeup = EINA_FALSE;
4064 Eina_Bool ok = _idle_process(data, &wakeup);
4069 if (wd->calc_job) ecore_job_del(wd->calc_job);
4070 wd->calc_job = ecore_job_add(_calc_job, wd);
4072 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4077 _item_queue(Widget_Data *wd,
4081 if (it->item->queued) return;
4082 it->item->queued = EINA_TRUE;
4083 if (cb && !wd->requeued)
4084 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4086 wd->queue = eina_list_append(wd->queue, it);
4087 // FIXME: why does a freeze then thaw here cause some genlist
4088 // elm_genlist_item_append() to be much much slower?
4089 // evas_event_freeze(evas_object_evas_get(wd->obj));
4090 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4092 if (wd->queue_idle_enterer)
4094 ecore_idle_enterer_del(wd->queue_idle_enterer);
4095 wd->queue_idle_enterer = NULL;
4099 // evas_event_thaw(evas_object_evas_get(wd->obj));
4100 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4101 if (!wd->queue_idle_enterer)
4102 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4106 _elm_genlist_item_compare(const void *data, const void *data1)
4108 const Elm_Gen_Item *it, *item1;
4109 it = ELM_GEN_ITEM_FROM_INLIST(data);
4110 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4111 return it->wd->item_compare_cb(it, item1);
4115 _elm_genlist_item_list_compare(const void *data, const void *data1)
4117 const Elm_Gen_Item *it = data;
4118 const Elm_Gen_Item *item1 = data1;
4119 return it->wd->item_compare_cb(it, item1);
4123 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4128 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4129 _item_block_del(it);
4131 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4132 it->item->rel = after;
4133 it->item->rel->relcount++;
4134 it->item->before = EINA_FALSE;
4135 if (after->item->group_item) it->item->group_item = after->item->group_item;
4136 _item_queue(it->wd, it, NULL);
4138 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4142 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4145 if (!before) return;
4147 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4148 _item_block_del(it);
4149 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4150 it->item->rel = before;
4151 it->item->rel->relcount++;
4152 it->item->before = EINA_TRUE;
4153 if (before->item->group_item) it->item->group_item = before->item->group_item;
4154 _item_queue(it->wd, it, NULL);
4156 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4160 elm_genlist_items_count(const Evas_Object *obj)
4162 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4163 Widget_Data *wd = elm_widget_data_get(obj);
4165 return wd->item_count;
4168 EAPI Elm_Object_Item *
4169 elm_genlist_item_append(Evas_Object *obj,
4170 const Elm_Genlist_Item_Class *itc,
4172 Elm_Object_Item *parent,
4173 Elm_Genlist_Item_Type type,
4175 const void *func_data)
4177 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4178 Widget_Data *wd = elm_widget_data_get(obj);
4179 if (!wd) return NULL;
4180 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4182 if (!it) return NULL;
4186 wd->group_items = eina_list_append(wd->group_items, it);
4187 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4188 it->item->rel = NULL;
4192 Elm_Gen_Item *it2 = NULL;
4193 Eina_List *ll = eina_list_last(it->parent->item->items);
4194 if (ll) it2 = ll->data;
4195 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4196 if (!it2) it2 = it->parent;
4198 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4199 EINA_INLIST_GET(it2));
4200 it->item->rel = it2;
4201 it->item->rel->relcount++;
4203 it->item->before = EINA_FALSE;
4204 _item_queue(wd, it, NULL);
4205 return (Elm_Object_Item *)it;
4208 EAPI Elm_Object_Item *
4209 elm_genlist_item_prepend(Evas_Object *obj,
4210 const Elm_Genlist_Item_Class *itc,
4212 Elm_Object_Item *parent,
4213 Elm_Genlist_Item_Type type,
4215 const void *func_data)
4217 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4218 Widget_Data *wd = elm_widget_data_get(obj);
4219 if (!wd) return NULL;
4220 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4222 if (!it) return NULL;
4226 wd->group_items = eina_list_prepend(wd->group_items, it);
4227 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4228 it->item->rel = NULL;
4232 Elm_Gen_Item *it2 = NULL;
4233 Eina_List *ll = it->parent->item->items;
4234 if (ll) it2 = ll->data;
4235 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4236 if (!it2) it2 = it->parent;
4238 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4239 EINA_INLIST_GET(it2));
4240 it->item->rel = it2;
4241 it->item->rel->relcount++;
4243 it->item->before = EINA_TRUE;
4244 _item_queue(wd, it, NULL);
4245 return (Elm_Object_Item *)it;
4248 EAPI Elm_Object_Item *
4249 elm_genlist_item_insert_after(Evas_Object *obj,
4250 const Elm_Genlist_Item_Class *itc,
4252 Elm_Object_Item *parent,
4253 Elm_Object_Item *after,
4254 Elm_Genlist_Item_Type type,
4256 const void *func_data)
4258 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4259 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4260 Widget_Data *wd = elm_widget_data_get(obj);
4261 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4262 if (!wd) return NULL;
4263 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4264 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4266 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4268 if (!it) return NULL;
4271 if ((it->group) && (_after->group))
4272 wd->group_items = eina_list_append_relative(wd->group_items, it,
4277 it->parent->item->items =
4278 eina_list_append_relative(it->parent->item->items, it, _after);
4280 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4281 EINA_INLIST_GET(_after));
4282 it->item->rel = _after;
4283 it->item->rel->relcount++;
4284 it->item->before = EINA_FALSE;
4285 _item_queue(wd, it, NULL);
4286 return (Elm_Object_Item *)it;
4289 EAPI Elm_Object_Item *
4290 elm_genlist_item_insert_before(Evas_Object *obj,
4291 const Elm_Genlist_Item_Class *itc,
4293 Elm_Object_Item *parent,
4294 Elm_Object_Item *before,
4295 Elm_Genlist_Item_Type type,
4297 const void *func_data)
4299 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4300 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4301 Widget_Data *wd = elm_widget_data_get(obj);
4302 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4303 if (!wd) return NULL;
4304 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4305 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4307 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4309 if (!it) return NULL;
4312 if (it->group && _before->group)
4313 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4318 it->parent->item->items =
4319 eina_list_prepend_relative(it->parent->item->items, it, _before);
4321 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4322 EINA_INLIST_GET(_before));
4323 it->item->rel = _before;
4324 it->item->rel->relcount++;
4325 it->item->before = EINA_TRUE;
4326 _item_queue(wd, it, NULL);
4327 return (Elm_Object_Item *)it;
4330 EAPI Elm_Object_Item *
4331 elm_genlist_item_sorted_insert(Evas_Object *obj,
4332 const Elm_Genlist_Item_Class *itc,
4334 Elm_Object_Item *parent,
4335 Elm_Genlist_Item_Type type,
4336 Eina_Compare_Cb comp,
4338 const void *func_data)
4340 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4341 Widget_Data *wd = elm_widget_data_get(obj);
4342 if (!wd) return NULL;
4343 Elm_Gen_Item *rel = NULL;
4344 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, type,
4346 if (!it) return NULL;
4348 wd->item_compare_cb = comp;
4355 l = eina_list_search_sorted_near_list(it->parent->item->items,
4356 _elm_genlist_item_list_compare,
4360 rel = eina_list_data_get(l);
4364 if (cmp_result >= 0)
4366 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4367 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4368 it->item->before = EINA_FALSE;
4370 else if (cmp_result < 0)
4372 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4373 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4374 it->item->before = EINA_TRUE;
4381 wd->state = eina_inlist_sorted_state_new();
4382 eina_inlist_sorted_state_init(wd->state, wd->items);
4383 wd->requeued = EINA_FALSE;
4387 wd->group_items = eina_list_append(wd->group_items, it);
4389 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4390 _elm_genlist_item_compare, wd->state);
4392 if (EINA_INLIST_GET(it)->next)
4394 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4395 it->item->before = EINA_TRUE;
4397 else if (EINA_INLIST_GET(it)->prev)
4399 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4400 it->item->before = EINA_FALSE;
4406 it->item->rel = rel;
4407 it->item->rel->relcount++;
4410 _item_queue(wd, it, _elm_genlist_item_list_compare);
4412 return (Elm_Object_Item *)it;
4416 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4418 Eina_Inlist *next, *l;
4419 Widget_Data *wd = elm_widget_data_get(obj);
4422 if (!standby) wd->generation++;
4426 eina_inlist_sorted_state_free(wd->state);
4430 if (wd->walking > 0)
4432 wd->clear_me = EINA_TRUE;
4435 evas_event_freeze(evas_object_evas_get(wd->obj));
4436 for (l = wd->items, next = l ? l->next : NULL;
4438 l = next, next = next ? next->next : NULL)
4440 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4442 if (it->generation < wd->generation)
4444 Elm_Gen_Item *itn = NULL;
4446 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4447 if (itn) itn->walking++; /* prevent early death of subitem */
4449 elm_widget_item_free(it);
4450 if (itn) itn->walking--;
4453 wd->clear_me = EINA_FALSE;
4454 wd->pan_changed = EINA_TRUE;
4457 ecore_job_del(wd->calc_job);
4458 wd->calc_job = NULL;
4460 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4461 if (wd->clear_cb) wd->clear_cb(wd);
4467 if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
4468 wd->alpha_bg = NULL;
4472 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4473 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4475 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4476 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4477 evas_event_thaw(evas_object_evas_get(wd->obj));
4478 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4482 elm_genlist_clear(Evas_Object *obj)
4484 ELM_CHECK_WIDTYPE(obj, widtype);
4485 _elm_genlist_clear(obj, EINA_FALSE);
4489 elm_genlist_multi_select_set(Evas_Object *obj,
4492 ELM_CHECK_WIDTYPE(obj, widtype);
4493 Widget_Data *wd = elm_widget_data_get(obj);
4495 wd->multi = !!multi;
4499 elm_genlist_multi_select_get(const Evas_Object *obj)
4501 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4502 Widget_Data *wd = elm_widget_data_get(obj);
4503 if (!wd) return EINA_FALSE;
4507 EAPI Elm_Object_Item *
4508 elm_genlist_selected_item_get(const Evas_Object *obj)
4510 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4511 Widget_Data *wd = elm_widget_data_get(obj);
4512 if (!wd) return NULL;
4513 if (wd->selected) return wd->selected->data;
4517 EAPI const Eina_List *
4518 elm_genlist_selected_items_get(const Evas_Object *obj)
4520 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4521 Widget_Data *wd = elm_widget_data_get(obj);
4522 if (!wd) return NULL;
4523 return wd->selected;
4527 elm_genlist_realized_items_get(const Evas_Object *obj)
4529 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4530 Widget_Data *wd = elm_widget_data_get(obj);
4531 Eina_List *list = NULL;
4533 Eina_Bool done = EINA_FALSE;
4534 if (!wd) return NULL;
4535 EINA_INLIST_FOREACH(wd->blocks, itb)
4543 EINA_LIST_FOREACH(itb->items, l, it)
4545 if (it->realized) list = eina_list_append(list, it);
4556 EAPI Elm_Object_Item *
4557 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4562 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4563 Widget_Data *wd = elm_widget_data_get(obj);
4564 Evas_Coord ox, oy, ow, oh;
4567 if (!wd) return NULL;
4568 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4570 EINA_INLIST_FOREACH(wd->blocks, itb)
4575 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4576 oy + itb->y - itb->wd->pan_y,
4577 itb->w, itb->h, x, y, 1, 1))
4579 EINA_LIST_FOREACH(itb->items, l, it)
4581 Evas_Coord itx, ity;
4583 itx = ox + itb->x + it->x - itb->wd->pan_x;
4584 ity = oy + itb->y + it->y - itb->wd->pan_y;
4585 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4589 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4590 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4594 return (Elm_Object_Item *)it;
4596 lasty = ity + it->item->h;
4601 if (y > lasty) *posret = 1;
4607 EAPI Elm_Object_Item *
4608 elm_genlist_first_item_get(const Evas_Object *obj)
4610 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4611 Widget_Data *wd = elm_widget_data_get(obj);
4612 if (!wd) return NULL;
4613 if (!wd->items) return NULL;
4614 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4615 while ((it) && (it->generation < wd->generation))
4616 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4617 return (Elm_Object_Item *)it;
4620 EAPI Elm_Object_Item *
4621 elm_genlist_last_item_get(const Evas_Object *obj)
4623 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4624 Widget_Data *wd = elm_widget_data_get(obj);
4625 if (!wd) return NULL;
4626 if (!wd->items) return NULL;
4627 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4628 while ((it) && (it->generation < wd->generation))
4629 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4630 return (Elm_Object_Item *)it;
4633 EAPI Elm_Object_Item *
4634 elm_genlist_item_next_get(const Elm_Object_Item *it)
4636 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4637 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4640 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
4641 if ((_it) && (_it->generation == _it->wd->generation)) break;
4643 return (Elm_Object_Item *) _it;
4646 EAPI Elm_Object_Item *
4647 elm_genlist_item_prev_get(const Elm_Object_Item *it)
4649 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4650 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4653 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
4654 if ((_it) && (_it->generation == _it->wd->generation)) break;
4656 return (Elm_Object_Item *) _it;
4659 EAPI Elm_Object_Item *
4660 elm_genlist_item_parent_get(const Elm_Object_Item *it)
4662 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4663 return (Elm_Object_Item *) ((Elm_Gen_Item *)it)->parent;
4667 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
4669 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4670 Widget_Data *wd = elm_widget_data_get(WIDGET(it));
4672 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4674 if (!wd->tree_effect_enabled || !wd->move_effect_mode)
4675 _item_subitems_clear(_it);
4678 if (!wd->tree_effect_animator)
4680 wd->expanded_item = _it;
4681 _item_tree_effect_before(_it);
4682 evas_object_raise(wd->alpha_bg);
4683 evas_object_show(wd->alpha_bg);
4684 wd->start_time = ecore_time_get();
4685 wd->tree_effect_animator = ecore_animator_add(_tree_effect_animator_cb, wd);
4688 _item_subitems_clear(_it);
4693 elm_genlist_item_selected_set(Elm_Object_Item *it,
4696 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4697 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4698 Widget_Data *wd = _it->wd;
4700 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
4702 selected = !!selected;
4703 if (_it->selected == selected) return;
4709 while (wd->selected)
4711 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
4712 _it->unsel_cb(wd->selected->data);
4715 _it->highlight_cb(_it);
4719 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
4724 elm_genlist_item_selected_get(const Elm_Object_Item *it)
4726 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4727 return ((Elm_Gen_Item *)it)->selected;
4731 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
4734 if (it->item->expanded)
4736 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4740 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
4743 if (it->item->expanded_depth >= it2->item->expanded_depth) break;
4744 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4751 _elm_genlist_move_items_set(Elm_Gen_Item *it)
4754 Elm_Gen_Item *it2 = NULL;
4755 Evas_Coord ox, oy, ow, oh, dh = 0;
4757 it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
4759 if (it->item->expanded)
4761 it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
4762 EINA_LIST_FOREACH(it->wd->move_items, l, it2)
4764 if (it2 == it->wd->expanded_next_item) break;
4765 it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
4770 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
4771 it2 = it->wd->expanded_next_item;
4772 while (it2 && (dh < oy + oh))
4775 it->wd->move_items = eina_list_append(it->wd->move_items, it2);
4776 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
4782 elm_genlist_item_expanded_set(Elm_Object_Item *it,
4785 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4786 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4787 expanded = !!expanded;
4788 if (_it->item->expanded == expanded) return;
4789 _it->item->expanded = expanded;
4790 _it->wd->expanded_item = _it;
4791 _elm_genlist_move_items_set(_it);
4793 if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
4794 _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
4796 if (_it->item->expanded)
4798 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
4800 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
4801 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
4802 _it->wd->auto_scroll_enabled = EINA_TRUE;
4806 _it->wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
4808 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
4809 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
4810 _it->wd->auto_scroll_enabled = EINA_FALSE;
4815 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
4817 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4818 return ((Elm_Gen_Item *)it)->item->expanded;
4822 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
4824 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
4825 return ((Elm_Gen_Item *)it)->item->expanded_depth;
4829 _elm_genlist_item_compute_coordinates(Elm_Object_Item *it,
4830 Elm_Genlist_Item_Scrollto_Type type,
4836 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4837 Evas_Coord gith = 0;
4838 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4839 if ((_it->item->queued) || (!_it->item->mincalcd))
4841 _it->wd->show_item = _it;
4842 _it->wd->bring_in = EINA_FALSE;
4843 _it->wd->scrollto_type = type;
4844 _it->item->showme = EINA_TRUE;
4847 if (_it->wd->show_item)
4849 _it->wd->show_item->item->showme = EINA_FALSE;
4850 _it->wd->show_item = NULL;
4853 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, w, h);
4856 case ELM_GENLIST_ITEM_SCROLLTO_IN:
4857 if ((_it->item->group_item) &&
4858 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4859 gith = _it->item->group_item->item->h;
4862 *y = _it->y + _it->item->block->y - gith;
4864 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
4865 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4866 *y = _it->y + _it->item->block->y - gith;
4868 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
4869 *y = _it->y + _it->item->block->y - *h / 2 + _it->item->h / 2;
4875 *x = _it->x + _it->item->block->x;
4876 *w = _it->item->block->w;
4881 elm_genlist_item_promote(Elm_Object_Item *it)
4883 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4884 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4885 if (_it->generation < _it->wd->generation) return;
4886 _item_move_before(_it,
4887 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
4891 elm_genlist_item_demote(Elm_Object_Item *it)
4893 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4894 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4895 if (_it->generation < _it->wd->generation) return;
4896 _item_move_after(_it,
4897 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
4901 elm_genlist_item_show(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4903 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4904 Evas_Coord x, y, w, h;
4905 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4907 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
4908 elm_smart_scroller_child_region_show(_it->wd->scr, x, y, w, h);
4912 elm_genlist_item_bring_in(Elm_Object_Item *it, Elm_Genlist_Item_Scrollto_Type type)
4915 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4916 Evas_Coord x, y, w, h;
4917 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4919 if (_elm_genlist_item_compute_coordinates(it, type, &x, &y, &w, &h))
4920 elm_smart_scroller_region_bring_in(_it->wd->scr,x, y, w, h);
4924 elm_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **l)
4926 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4928 Evas_Object *content;
4929 EINA_LIST_FREE(((Elm_Gen_Item *)it)->content_objs, content)
4931 elm_widget_sub_object_del(WIDGET(it), content);
4932 evas_object_smart_member_del(content);
4933 evas_object_hide(content);
4935 *l = eina_list_append(*l, content);
4940 elm_genlist_item_update(Elm_Object_Item *it)
4942 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4943 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4945 if (!_it->item->block) return;
4946 if (_it->generation < _it->wd->generation) return;
4947 _it->item->mincalcd = EINA_FALSE;
4948 _it->item->updateme = EINA_TRUE;
4949 _it->item->block->updateme = EINA_TRUE;
4950 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
4951 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
4955 elm_genlist_item_fields_update(Elm_Object_Item *it,
4957 Elm_Genlist_Item_Field_Type itf)
4959 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4960 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4962 if (!_it->item->block) return;
4963 if (_it->generation < _it->wd->generation) return;
4965 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
4966 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
4967 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
4969 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
4970 &_it->contents, parts);
4971 _it->content_objs = _item_content_realize(_it, VIEW(_it),
4972 &_it->contents, parts);
4974 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
4975 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
4979 elm_genlist_item_item_class_update(Elm_Object_Item *it,
4980 const Elm_Genlist_Item_Class *itc)
4982 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4983 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4985 if (!_it->item->block) return;
4986 EINA_SAFETY_ON_NULL_RETURN(itc);
4987 if (_it->generation < _it->wd->generation) return;
4989 _it->item->nocache_once = EINA_TRUE;
4990 elm_genlist_item_update(it);
4993 EAPI const Elm_Genlist_Item_Class *
4994 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
4996 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4997 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
4998 if (_it->generation < _it->wd->generation) return NULL;
5002 static Evas_Object *
5003 _elm_genlist_item_label_create(void *data,
5004 Evas_Object *obj __UNUSED__,
5005 Evas_Object *tooltip,
5006 void *it __UNUSED__)
5008 Evas_Object *label = elm_label_add(tooltip);
5011 elm_object_style_set(label, "tooltip");
5012 elm_object_text_set(label, data);
5017 _elm_genlist_item_label_del_cb(void *data,
5018 Evas_Object *obj __UNUSED__,
5019 void *event_info __UNUSED__)
5021 eina_stringshare_del(data);
5025 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5028 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5029 text = eina_stringshare_add(text);
5030 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5032 _elm_genlist_item_label_del_cb);
5036 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5037 Elm_Tooltip_Item_Content_Cb func,
5039 Evas_Smart_Cb del_cb)
5041 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5042 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5044 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5047 if (_it->tooltip.del_cb)
5048 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5050 _it->tooltip.content_cb = func;
5051 _it->tooltip.data = data;
5052 _it->tooltip.del_cb = del_cb;
5056 elm_widget_item_tooltip_content_cb_set(_it,
5057 _it->tooltip.content_cb,
5058 _it->tooltip.data, NULL);
5059 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5060 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5066 if (del_cb) del_cb((void *)data, NULL, NULL);
5070 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5072 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5073 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5075 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5076 elm_widget_item_tooltip_unset(_it);
5078 if (_it->tooltip.del_cb)
5079 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5080 _it->tooltip.del_cb = NULL;
5081 _it->tooltip.content_cb = NULL;
5082 _it->tooltip.data = NULL;
5083 _it->tooltip.free_size = EINA_FALSE;
5084 if (_it->tooltip.style)
5085 elm_genlist_item_tooltip_style_set(it, NULL);
5089 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5092 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5093 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5095 eina_stringshare_replace(&_it->tooltip.style, style);
5096 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5100 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5102 return elm_object_item_tooltip_style_get(it);
5106 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5109 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5110 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5112 _it->tooltip.free_size = disable;
5113 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5118 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5120 return elm_object_tooltip_window_mode_get(VIEW(it));
5124 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5127 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5128 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5129 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5130 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5134 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5136 return elm_widget_item_cursor_get(it);
5140 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5142 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5143 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5145 if (!_it->mouse_cursor) return;
5147 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5149 eina_stringshare_del(_it->mouse_cursor);
5150 _it->mouse_cursor = NULL;
5154 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5157 elm_widget_item_cursor_style_set(it, style);
5161 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5163 return elm_widget_item_cursor_style_get(it);
5167 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5168 Eina_Bool engine_only)
5170 elm_widget_item_cursor_engine_only_set(it, engine_only);
5174 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5176 return elm_widget_item_cursor_engine_only_get(it);
5180 elm_genlist_item_index_get(const Elm_Object_Item *it)
5182 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5183 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5185 if (_it->item->block)
5186 return _it->position + (_it->item->block->position * _it->wd->max_items_per_block);
5191 elm_genlist_mode_set(Evas_Object *obj,
5194 ELM_CHECK_WIDTYPE(obj, widtype);
5195 Widget_Data *wd = elm_widget_data_get(obj);
5197 if (wd->mode == mode) return;
5199 if (wd->mode == ELM_LIST_COMPRESS)
5200 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5206 elm_genlist_mode_get(const Evas_Object *obj)
5208 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5209 Widget_Data *wd = elm_widget_data_get(obj);
5210 if (!wd) return ELM_LIST_LAST;
5215 elm_genlist_bounce_set(Evas_Object *obj,
5219 ELM_CHECK_WIDTYPE(obj, widtype);
5220 Widget_Data *wd = elm_widget_data_get(obj);
5222 wd->h_bounce = !!h_bounce;
5223 wd->v_bounce = !!v_bounce;
5224 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5228 elm_genlist_bounce_get(const Evas_Object *obj,
5229 Eina_Bool *h_bounce,
5230 Eina_Bool *v_bounce)
5232 ELM_CHECK_WIDTYPE(obj, widtype);
5233 Widget_Data *wd = elm_widget_data_get(obj);
5235 if (h_bounce) *h_bounce = wd->h_bounce;
5236 if (v_bounce) *v_bounce = wd->v_bounce;
5240 elm_genlist_homogeneous_set(Evas_Object *obj,
5241 Eina_Bool homogeneous)
5243 ELM_CHECK_WIDTYPE(obj, widtype);
5244 Widget_Data *wd = elm_widget_data_get(obj);
5246 wd->homogeneous = !!homogeneous;
5250 elm_genlist_homogeneous_get(const Evas_Object *obj)
5252 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5253 Widget_Data *wd = elm_widget_data_get(obj);
5254 if (!wd) return EINA_FALSE;
5255 return wd->homogeneous;
5259 elm_genlist_block_count_set(Evas_Object *obj,
5262 ELM_CHECK_WIDTYPE(obj, widtype);
5263 Widget_Data *wd = elm_widget_data_get(obj);
5265 wd->max_items_per_block = count;
5266 wd->item_cache_max = wd->max_items_per_block * 2;
5267 _item_cache_clean(wd);
5271 elm_genlist_block_count_get(const Evas_Object *obj)
5273 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5274 Widget_Data *wd = elm_widget_data_get(obj);
5276 return wd->max_items_per_block;
5280 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5283 ELM_CHECK_WIDTYPE(obj, widtype);
5284 Widget_Data *wd = elm_widget_data_get(obj);
5286 wd->longpress_timeout = timeout;
5290 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5292 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5293 Widget_Data *wd = elm_widget_data_get(obj);
5295 return wd->longpress_timeout;
5299 elm_genlist_scroller_policy_set(Evas_Object *obj,
5300 Elm_Scroller_Policy policy_h,
5301 Elm_Scroller_Policy policy_v)
5303 ELM_CHECK_WIDTYPE(obj, widtype);
5304 Widget_Data *wd = elm_widget_data_get(obj);
5305 if ((!wd) || (!wd->scr)) return;
5306 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5307 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5309 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5313 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5314 Elm_Scroller_Policy *policy_h,
5315 Elm_Scroller_Policy *policy_v)
5317 ELM_CHECK_WIDTYPE(obj, widtype);
5318 Widget_Data *wd = elm_widget_data_get(obj);
5319 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5320 if ((!wd) || (!wd->scr)) return;
5321 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5322 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5323 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5327 elm_genlist_realized_items_update(Evas_Object *obj)
5329 ELM_CHECK_WIDTYPE(obj, widtype);
5331 Eina_List *list, *l;
5332 Elm_Object_Item *it;
5334 list = elm_genlist_realized_items_get(obj);
5335 EINA_LIST_FOREACH(list, l, it)
5336 elm_genlist_item_update(it);
5340 elm_genlist_item_decorate_mode_set(Elm_Object_Item *it,
5341 const char *decorate_type,
5344 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5345 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5347 Widget_Data *wd = _it->wd;
5349 Elm_Object_Item *it2;
5352 if (!decorate_type) return;
5353 if ((_it->generation < _it->wd->generation) ||
5354 elm_widget_item_disabled_get(_it)) return;
5355 if (wd->decorate_mode) return;
5357 if ((wd->mode_item == _it) &&
5358 (!strcmp(decorate_type, wd->decorate_type)) &&
5361 if (!_it->itc->decorate_item_style) return;
5362 _it->mode_set = mode_set;
5366 EINA_LIST_FOREACH(wd->selected, l, it2)
5367 if (((Elm_Gen_Item *)it2)->realized)
5368 elm_genlist_item_selected_set(it2, EINA_FALSE);
5372 it2 = elm_genlist_selected_item_get(wd->obj);
5373 if ((it2) && (((Elm_Gen_Item *)it2)->realized))
5374 elm_genlist_item_selected_set(it2, EINA_FALSE);
5377 if (((wd->decorate_type) && (strcmp(decorate_type, wd->decorate_type))) ||
5379 ((_it == wd->mode_item) && (!mode_set)))
5380 _item_mode_unset(wd);
5382 eina_stringshare_replace(&wd->decorate_type, decorate_type);
5383 if (mode_set) _item_mode_set(_it);
5387 elm_genlist_item_decorate_mode_get(const Elm_Object_Item *it)
5389 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5390 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5391 return _it->wd->decorate_type;
5394 EAPI const Elm_Object_Item *
5395 elm_genlist_decorated_item_get(const Evas_Object *obj)
5397 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5398 Widget_Data *wd = elm_widget_data_get(obj);
5399 if (!wd) return NULL;
5400 return (Elm_Object_Item *) wd->mode_item;
5404 elm_genlist_decorate_mode_get(const Evas_Object *obj)
5406 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5407 Widget_Data *wd = elm_widget_data_get(obj);
5408 if (!wd) return EINA_FALSE;
5410 return wd->decorate_mode;
5414 elm_genlist_decorate_mode_set(Evas_Object *obj, Eina_Bool decorated)
5416 ELM_CHECK_WIDTYPE(obj, widtype);
5417 Eina_List *list, *l;
5420 Widget_Data *wd = elm_widget_data_get(obj);
5422 decorated = !!decorated;
5423 if (wd->decorate_mode == decorated) return;
5424 wd->decorate_mode = decorated;
5426 list = elm_genlist_realized_items_get(obj);
5427 if (!wd->decorate_mode)
5429 EINA_LIST_FOREACH(list, l, it)
5431 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5432 _decorate_mode_item_unrealize(it);
5434 _item_cache_zero(wd);
5438 EINA_LIST_FOREACH(list, l, it)
5440 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
5442 if (it->selected) _item_unselect(it);
5443 if (it->itc->decorate_all_item_style)
5444 _decorate_mode_item_realize(it, EINA_TRUE);
5448 if (wd->calc_job) ecore_job_del(wd->calc_job);
5449 wd->calc_job = ecore_job_add(_calc_job, wd);
5453 elm_genlist_reorder_mode_set(Evas_Object *obj,
5454 Eina_Bool reorder_mode)
5456 ELM_CHECK_WIDTYPE(obj, widtype);
5457 Widget_Data *wd = elm_widget_data_get(obj);
5459 wd->reorder_mode = !!reorder_mode;
5463 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5465 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5466 Widget_Data *wd = elm_widget_data_get(obj);
5467 if (!wd) return EINA_FALSE;
5468 return wd->reorder_mode;
5471 EAPI Elm_Genlist_Item_Type
5472 elm_genlist_item_type_get(const Elm_Object_Item *it)
5474 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5475 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5476 return _it->item->type;
5479 EAPI Elm_Genlist_Item_Class *
5480 elm_genlist_item_class_new(void)
5482 Elm_Genlist_Item_Class *itc;
5484 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5487 itc->version = CLASS_ALLOCATED;
5489 itc->delete_me = EINA_FALSE;
5495 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5497 if (itc && (itc->version == CLASS_ALLOCATED))
5499 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5500 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5510 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5512 if (itc && (itc->version == CLASS_ALLOCATED))
5515 if (itc->refcount == 0) itc->refcount--;
5520 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5522 if (itc && (itc->version == CLASS_ALLOCATED))
5524 if (itc->refcount > 0) itc->refcount--;
5525 if (itc->delete_me && (!itc->refcount))
5526 elm_genlist_item_class_free(itc);
5530 void _flip_job(void *data)
5532 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
5533 _elm_genlist_item_unrealize(it, EINA_FALSE);
5534 if (it->selected) _item_unselect(it);
5535 it->flipped = EINA_TRUE;
5536 it->item->nocache = EINA_TRUE;
5540 elm_genlist_item_flip_set(Elm_Object_Item *it,
5543 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5544 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5547 if (_it->flipped == flip) return;
5551 ecore_job_add(_flip_job, _it);
5552 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
5553 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
5557 _it->flipped = flip;
5558 _item_cache_zero(_it->wd);
5559 elm_genlist_item_update(it);
5560 _it->item->nocache = EINA_FALSE;
5565 elm_genlist_item_flip_get(const Elm_Object_Item *it)
5567 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5568 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5569 return _it->flipped;
5573 elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode)
5575 ELM_CHECK_WIDTYPE(obj, widtype);
5576 Widget_Data *wd = elm_widget_data_get(obj);
5578 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5580 if (wd->select_mode != mode)
5581 wd->select_mode = mode;
5584 EAPI Elm_Object_Select_Mode
5585 elm_genlist_select_mode_get(const Evas_Object *obj)
5587 ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
5588 Widget_Data *wd = elm_widget_data_get(obj);
5589 if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
5590 return wd->select_mode;
5594 elm_genlist_highlight_mode_set(Evas_Object *obj,
5595 Eina_Bool highlight)
5597 ELM_CHECK_WIDTYPE(obj, widtype);
5598 Widget_Data *wd = elm_widget_data_get(obj);
5600 wd->highlight = !!highlight;
5604 elm_genlist_highlight_mode_get(const Evas_Object *obj)
5606 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5607 Widget_Data *wd = elm_widget_data_get(obj);
5608 if (!wd) return EINA_FALSE;
5609 return wd->highlight;
5613 elm_genlist_item_select_mode_set(Elm_Object_Item *it,
5614 Elm_Object_Select_Mode mode)
5616 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5617 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5619 if (_it->generation < _it->wd->generation) return;
5620 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
5622 if (_it->select_mode != mode)
5623 _it->select_mode = mode;
5625 if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
5627 _it->item->mincalcd = EINA_FALSE;
5628 _it->item->updateme = EINA_TRUE;
5629 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
5630 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
5631 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
5635 EAPI Elm_Object_Select_Mode
5636 elm_genlist_item_select_mode_get(const Elm_Object_Item *it)
5638 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
5639 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5640 if (!_it) return ELM_OBJECT_SELECT_MODE_MAX;
5641 return _it->select_mode;
5644 /* for gengrid as of now */
5646 _elm_genlist_page_relative_set(Evas_Object *obj,
5650 Evas_Coord pagesize_h;
5651 Evas_Coord pagesize_v;
5653 ELM_CHECK_WIDTYPE(obj, widtype);
5654 Widget_Data *wd = elm_widget_data_get(obj);
5657 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5658 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5662 /* for gengrid as of now */
5664 _elm_genlist_page_relative_get(const Evas_Object *obj,
5668 ELM_CHECK_WIDTYPE(obj, widtype);
5669 Widget_Data *wd = elm_widget_data_get(obj);
5672 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5675 /* for gengrid as of now */
5677 _elm_genlist_page_size_set(Evas_Object *obj,
5678 Evas_Coord h_pagesize,
5679 Evas_Coord v_pagesize)
5684 ELM_CHECK_WIDTYPE(obj, widtype);
5685 Widget_Data *wd = elm_widget_data_get(obj);
5687 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5688 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5692 /* for gengrid as of now */
5694 _elm_genlist_current_page_get(const Evas_Object *obj,
5698 ELM_CHECK_WIDTYPE(obj, widtype);
5699 Widget_Data *wd = elm_widget_data_get(obj);
5701 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5704 /* for gengrid as of now */
5706 _elm_genlist_last_page_get(const Evas_Object *obj,
5710 ELM_CHECK_WIDTYPE(obj, widtype);
5711 Widget_Data *wd = elm_widget_data_get(obj);
5713 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5716 /* for gengrid as of now */
5718 _elm_genlist_page_show(const Evas_Object *obj,
5722 ELM_CHECK_WIDTYPE(obj, widtype);
5723 Widget_Data *wd = elm_widget_data_get(obj);
5725 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5728 /* for gengrid as of now */
5730 _elm_genlist_page_bring_in(const Evas_Object *obj,
5734 ELM_CHECK_WIDTYPE(obj, widtype);
5735 Widget_Data *wd = elm_widget_data_get(obj);
5737 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5741 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5744 Evas_Object *content;
5746 if (!it->realized) return;
5747 if (it->wd->reorder_it == it) return;
5749 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5751 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5754 ecore_timer_del(it->long_timer);
5755 it->long_timer = NULL;
5758 elm_widget_stringlist_free(it->texts);
5760 elm_widget_stringlist_free(it->contents);
5761 it->contents = NULL;
5762 elm_widget_stringlist_free(it->states);
5765 EINA_LIST_FREE(it->content_objs, content)
5766 evas_object_del(content);
5768 it->unrealize_cb(it);
5770 it->realized = EINA_FALSE;
5771 it->want_unrealize = EINA_FALSE;
5772 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5773 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5777 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5779 elm_widget_item_pre_notify_del(it);
5780 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5781 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5783 if (it->itc->func.del)
5784 it->itc->func.del((void *)it->base.data, WIDGET(it));
5788 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5790 _elm_genlist_item_del_notserious(it);
5791 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5792 if (it->tooltip.del_cb)
5793 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5794 it->wd->walking -= it->walking;
5795 if (it->long_timer) ecore_timer_del(it->long_timer);
5797 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5801 eina_inlist_sorted_state_free(it->wd->state);
5802 it->wd->state = NULL;
5804 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5805 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5809 if (it->wd->last_selected_item == (Elm_Object_Item *)it)
5810 it->wd->last_selected_item = NULL;
5811 it->wd->item_count--;
5815 elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
5817 ELM_CHECK_WIDTYPE(obj, widtype);
5818 Widget_Data *wd = elm_widget_data_get(obj);
5820 wd->tree_effect_enabled = !!enabled;
5824 elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
5826 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5827 Widget_Data *wd = elm_widget_data_get(obj);
5828 if (!wd) return EINA_FALSE;
5829 return wd->tree_effect_enabled;
5833 _create_tray_alpha_bg(const Evas_Object *obj)
5835 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5836 Widget_Data *wd = elm_widget_data_get(obj);
5837 if (!wd) return NULL;
5839 Evas_Object *bg = NULL;
5840 Evas_Coord ox, oy, ow, oh;
5842 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5843 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
5844 evas_object_color_set(bg,0,0,0,0);
5845 evas_object_resize(bg , ow, oh);
5846 evas_object_move(bg , ox, oy);
5851 _item_contract_emit(Elm_Gen_Item *it)
5856 edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
5857 it->item->tree_effect_finished = EINA_FALSE;
5859 EINA_LIST_FOREACH(it->item->items, l, it2)
5860 if (it2) _item_contract_emit(it2);
5864 _item_tree_effect_before(Elm_Gen_Item *it)
5869 EINA_LIST_FOREACH(it->item->items, l, it2)
5871 if (it2->parent && (it == it2->parent))
5873 if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
5874 edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
5875 else if (it->wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
5876 _item_contract_emit(it2);
5879 return ECORE_CALLBACK_CANCEL;
5883 _item_tree_effect(Widget_Data *wd, int y)
5885 Elm_Gen_Item *it = NULL, *expanded_next_it;
5887 expanded_next_it = wd->expanded_next_item;
5889 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
5891 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
5894 if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
5895 if (it->item->scrl_y && (it->item->scrl_y < expanded_next_it->item->old_scrl_y + y) &&
5896 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
5898 if (!it->item->tree_effect_finished)
5900 edje_object_signal_emit(VIEW(it), "flip_item", "");
5901 evas_object_show(VIEW(it));
5902 it->item->tree_effect_finished = EINA_TRUE;
5905 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
5908 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
5910 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
5913 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
5914 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
5916 if (!it->item->tree_effect_finished)
5918 edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
5919 it->item->tree_effect_finished = EINA_TRUE;
5924 it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
5930 _item_tree_effect_finish(Widget_Data *wd)
5933 Elm_Gen_Item *it = NULL;
5936 if (wd->tree_effect_animator)
5938 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
5939 _item_subitems_clear(wd->expanded_item);
5940 EINA_INLIST_FOREACH(wd->blocks, itb)
5942 EINA_LIST_FOREACH(itb->items, l, it)
5944 it->item->tree_effect_finished = EINA_TRUE;
5945 it->item->old_scrl_y = it->item->scrl_y;
5949 _item_auto_scroll(wd);
5950 evas_object_lower(wd->alpha_bg);
5951 evas_object_hide(wd->alpha_bg);
5952 wd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
5953 if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
5955 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
5956 evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
5957 evas_object_smart_changed(wd->pan_smart);
5959 wd->tree_effect_animator = NULL;
5963 _tree_effect_animator_cb(void *data)
5965 Widget_Data *wd = data;
5966 if (!wd) return EINA_FALSE;
5967 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
5968 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
5970 double effect_duration = 0.5, t;
5971 int y = 0, dy = 0, dh = 0;
5972 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
5975 t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
5976 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5977 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
5978 if (t > effect_duration) end = EINA_TRUE;
5980 // Below while statement is needed, when the genlist is resized.
5981 it2 = wd->expanded_item;
5984 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
5985 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
5986 cvx, cvy, cvw, cvh));
5987 it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
5990 if (wd->expanded_next_item)
5992 expanded_next_it = wd->expanded_next_item;
5995 EINA_LIST_FOREACH(wd->move_items, l, it)
5997 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
5999 expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
6000 if (expanded_next_it->item->scrl_y < expanded_next_it->item->old_scrl_y) //did not calculate next item position
6001 expanded_next_it->item->scrl_y = cvy + cvh;
6003 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
6004 cvy + cvh : expanded_next_it->item->scrl_y) -
6005 expanded_next_it->item->old_scrl_y;
6007 else if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
6009 if (expanded_next_it->item->scrl_y > expanded_next_it->item->old_scrl_y) //did not calculate next item position
6010 expanded_next_it->item->old_scrl_y = cvy + cvh;
6012 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
6014 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6016 expanded_next_it->item->old_scrl_y = cvy + cvh;
6020 dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
6021 expanded_next_it->item->old_scrl_y;
6025 if (t <= effect_duration)
6027 y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
6037 _item_realize(it, in, 0);
6041 if (it != expanded_next_it)
6043 it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
6047 if ((it->item->old_scrl_y + y) < (cvy + cvh))
6048 _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
6051 _item_tree_effect(wd, y);
6055 int expanded_item_num = 0;
6058 if (wd->expanded_item)
6059 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
6064 expanded_item_num++;
6065 it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
6071 if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
6072 if (wd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
6074 if (!it->item->tree_effect_finished)
6076 if (t >= (((num - 1) * effect_duration) / expanded_item_num))
6078 edje_object_signal_emit(VIEW(it), "flip_item", "");
6079 evas_object_show(VIEW(it));
6080 it->item->tree_effect_finished = EINA_TRUE;
6084 it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
6090 _item_tree_effect_finish(wd);
6091 return ECORE_CALLBACK_CANCEL;
6093 return ECORE_CALLBACK_RENEW;