3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_genlist.h"
9 #define MAX_ITEMS_PER_BLOCK 32
10 #define REORDER_EFFECT_TIME 0.5
12 #define ELM_GEN_SETUP(wd) \
13 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
14 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
15 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
17 #define ELM_GEN_ITEM_SETUP(it) \
18 (it)->del_cb = (Ecore_Cb)_item_del; \
19 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
20 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
21 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
22 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
24 typedef struct _Item_Block Item_Block;
25 typedef struct _Item_Cache Item_Cache;
27 struct Elm_Gen_Item_Type
32 Evas_Coord w, h, minw, minh;
33 Elm_Gen_Item *group_item;
34 Elm_Genlist_Item_Flags flags;
35 Eina_List *mode_texts, *mode_contents, *mode_states, *mode_content_objs;
36 Ecore_Timer *swipe_timer;
37 Evas_Coord scrl_x, scrl_y, old_scrl_y;
40 Evas_Object *mode_view;
46 Eina_Bool want_realize : 1;
47 Eina_Bool expanded : 1;
48 Eina_Bool mincalcd : 1;
51 Eina_Bool updateme : 1;
52 Eina_Bool nocache : 1;
53 Eina_Bool stacking_even : 1;
54 Eina_Bool nostacking : 1;
55 Eina_Bool move_effect_enabled : 1;
66 Evas_Coord x, y, w, h, minw, minh;
67 Eina_Bool want_unrealize : 1;
68 Eina_Bool realized : 1;
69 Eina_Bool changed : 1;
70 Eina_Bool updateme : 1;
72 Eina_Bool must_recalc : 1;
79 Evas_Object *base_view, *spacer;
81 const char *item_style; // it->itc->item_style
82 Eina_Bool tree : 1; // it->group
83 Eina_Bool compress : 1; // it->wd->compress
85 Eina_Bool selected : 1; // it->selected
86 Eina_Bool disabled : 1; // it->disabled
87 Eina_Bool expanded : 1; // it->item->expanded
90 static const char *widtype = NULL;
91 static void _item_cache_zero(Widget_Data *wd);
92 static void _del_hook(Evas_Object *obj);
93 static void _mirrored_set(Evas_Object *obj,
95 static void _theme_hook(Evas_Object *obj);
96 static void _show_region_hook(void *data,
98 static void _sizing_eval(Evas_Object *obj);
99 static void _item_realize(Elm_Gen_Item *it,
102 static void _item_unrealize_cb(Elm_Gen_Item *it);
103 static void _item_block_unrealize(Item_Block *itb);
104 static void _calc_job(void *data);
105 static void _on_focus_hook(void *data,
107 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
108 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
109 static Eina_Bool _item_single_select_up(Widget_Data *wd);
110 static Eina_Bool _item_single_select_down(Widget_Data *wd);
111 static Eina_Bool _event_hook(Evas_Object *obj,
113 Evas_Callback_Type type,
115 static void _signal_emit_hook(Evas_Object *obj,
116 const char *emission,
118 static Eina_Bool _deselect_all_items(Widget_Data *wd);
119 static void _pan_calculate(Evas_Object *obj);
120 static void _pan_max_get(Evas_Object *obj,
123 static void _item_position(Elm_Gen_Item *it,
127 static void _mode_item_realize(Elm_Gen_Item *it);
128 static void _mode_item_unrealize(Elm_Gen_Item *it);
129 static void _item_mode_set(Elm_Gen_Item *it);
130 static void _item_mode_unset(Widget_Data *wd);
131 static void _group_items_recalc(void *data);
132 static void _item_move_after(Elm_Gen_Item *it,
133 Elm_Gen_Item *after);
134 static void _item_move_before(Elm_Gen_Item *it,
135 Elm_Gen_Item *before);
136 static void _item_auto_scroll(Widget_Data *wd);
137 static void _elm_genlist_clear(Evas_Object *obj,
139 static void _pan_child_size_get(Evas_Object *obj,
143 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
145 static const char SIG_ACTIVATED[] = "activated";
146 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
147 static const char SIG_SELECTED[] = "selected";
148 static const char SIG_UNSELECTED[] = "unselected";
149 static const char SIG_EXPANDED[] = "expanded";
150 static const char SIG_CONTRACTED[] = "contracted";
151 static const char SIG_EXPAND_REQUEST[] = "expand,request";
152 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
153 static const char SIG_REALIZED[] = "realized";
154 static const char SIG_UNREALIZED[] = "unrealized";
155 static const char SIG_DRAG_START_UP[] = "drag,start,up";
156 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
157 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
158 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
159 static const char SIG_DRAG_STOP[] = "drag,stop";
160 static const char SIG_DRAG[] = "drag";
161 static const char SIG_LONGPRESSED[] = "longpressed";
162 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
163 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
164 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
165 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
166 static const char SIG_EDGE_TOP[] = "edge,top";
167 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
168 static const char SIG_EDGE_LEFT[] = "edge,left";
169 static const char SIG_EDGE_RIGHT[] = "edge,right";
170 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
171 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
172 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
173 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
174 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
175 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
176 static const char SIG_SWIPE[] = "swipe";
177 static const char SIG_MOVED[] = "moved";
179 static const Evas_Smart_Cb_Description _signals[] = {
180 {SIG_CLICKED_DOUBLE, ""},
183 {SIG_UNSELECTED, ""},
185 {SIG_CONTRACTED, ""},
186 {SIG_EXPAND_REQUEST, ""},
187 {SIG_CONTRACT_REQUEST, ""},
189 {SIG_UNREALIZED, ""},
190 {SIG_DRAG_START_UP, ""},
191 {SIG_DRAG_START_DOWN, ""},
192 {SIG_DRAG_START_LEFT, ""},
193 {SIG_DRAG_START_RIGHT, ""},
196 {SIG_LONGPRESSED, ""},
197 {SIG_SCROLL_ANIM_START, ""},
198 {SIG_SCROLL_ANIM_STOP, ""},
199 {SIG_SCROLL_DRAG_START, ""},
200 {SIG_SCROLL_DRAG_STOP, ""},
202 {SIG_EDGE_BOTTOM, ""},
204 {SIG_EDGE_RIGHT, ""},
205 {SIG_MULTI_SWIPE_LEFT, ""},
206 {SIG_MULTI_SWIPE_RIGHT, ""},
207 {SIG_MULTI_SWIPE_UP, ""},
208 {SIG_MULTI_SWIPE_DOWN, ""},
209 {SIG_MULTI_PINCH_OUT, ""},
210 {SIG_MULTI_PINCH_IN, ""},
217 #undef ELM_CHECK_WIDTYPE
218 #define ELM_CHECK_WIDTYPE(obj, widtype) \
219 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
220 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
221 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
222 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
223 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
225 static const char *_gengrid = NULL;
226 static const char *_genlist = NULL;
228 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
230 elm_genlist_type_check(const Evas_Object *obj,
233 const char *provided, *expected = "(unknown)";
234 static int abort_on_warn = -1;
235 provided = elm_widget_type_get(obj);
236 if (!_genlist) _genlist = eina_stringshare_add("genlist");
237 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
238 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
240 if ((!provided) || (!provided[0]))
242 provided = evas_object_type_get(obj);
243 if ((!provided) || (!provided[0]))
244 provided = "(unknown)";
246 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
247 if (abort_on_warn == -1)
249 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
250 else abort_on_warn = 0;
252 if (abort_on_warn == 1) abort();
257 _event_hook(Evas_Object *obj,
258 Evas_Object *src __UNUSED__,
259 Evas_Callback_Type type,
262 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
263 Evas_Event_Key_Down *ev = event_info;
264 Widget_Data *wd = elm_widget_data_get(obj);
265 Evas_Coord pan_max_x = 0, pan_max_y = 0;
266 if (!wd) return EINA_FALSE;
267 if (!wd->items) return EINA_FALSE;
268 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
269 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
271 Elm_Gen_Item *it = NULL;
274 Evas_Coord step_x = 0;
275 Evas_Coord step_y = 0;
278 Evas_Coord page_x = 0;
279 Evas_Coord page_y = 0;
281 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
282 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
283 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
284 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
286 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
290 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
294 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
296 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
297 (_item_multi_select_up(wd)))
298 || (_item_single_select_up(wd)))
300 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
306 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
308 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
309 (_item_multi_select_down(wd)))
310 || (_item_single_select_down(wd)))
312 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
318 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
320 it = elm_genlist_first_item_get(obj);
321 elm_genlist_item_bring_in(it);
322 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
325 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
327 it = elm_genlist_last_item_get(obj);
328 elm_genlist_item_bring_in(it);
329 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
332 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
335 y -= -(page_y * v_h) / 100;
339 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
342 y += -(page_y * v_h) / 100;
346 else if (!strcmp(ev->keyname, "Escape"))
348 if (!_deselect_all_items(wd)) return EINA_FALSE;
349 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
352 else if (((!strcmp(ev->keyname, "Return")) ||
353 (!strcmp(ev->keyname, "KP_Enter")) ||
354 (!strcmp(ev->keyname, "space")))
355 && (!wd->multi) && (wd->selected))
357 it = elm_genlist_selected_item_get(obj);
358 elm_genlist_item_expanded_set(it,
359 !elm_genlist_item_expanded_get(it));
360 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
362 else return EINA_FALSE;
364 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
365 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
367 if (x > pan_max_x) x = pan_max_x;
369 if (y > pan_max_y) y = pan_max_y;
370 elm_smart_scroller_child_pos_set(wd->scr, x, y);
375 _deselect_all_items(Widget_Data *wd)
377 if (!wd->selected) return EINA_FALSE;
379 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
385 _item_multi_select_up(Widget_Data *wd)
387 if (!wd->selected) return EINA_FALSE;
388 if (!wd->multi) return EINA_FALSE;
390 Elm_Gen_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
391 if (!prev) return EINA_TRUE;
393 if (elm_genlist_item_selected_get(prev))
395 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
396 wd->last_selected_item = prev;
397 elm_genlist_item_show(wd->last_selected_item);
401 elm_genlist_item_selected_set(prev, EINA_TRUE);
402 elm_genlist_item_show(prev);
408 _item_multi_select_down(Widget_Data *wd)
410 if (!wd->selected) return EINA_FALSE;
411 if (!wd->multi) return EINA_FALSE;
413 Elm_Gen_Item *next = elm_genlist_item_next_get(wd->last_selected_item);
414 if (!next) return EINA_TRUE;
416 if (elm_genlist_item_selected_get(next))
418 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
419 wd->last_selected_item = next;
420 elm_genlist_item_show(wd->last_selected_item);
424 elm_genlist_item_selected_set(next, EINA_TRUE);
425 elm_genlist_item_show(next);
431 _item_single_select_up(Widget_Data *wd)
436 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
437 while ((prev) && (prev->generation < wd->generation))
438 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
440 else prev = elm_genlist_item_prev_get(wd->last_selected_item);
442 if (!prev) return EINA_FALSE;
444 _deselect_all_items(wd);
446 elm_genlist_item_selected_set(prev, EINA_TRUE);
447 elm_genlist_item_show(prev);
452 _item_single_select_down(Widget_Data *wd)
457 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
458 while ((next) && (next->generation < wd->generation))
459 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
461 else next = elm_genlist_item_next_get(wd->last_selected_item);
463 if (!next) return EINA_FALSE;
465 _deselect_all_items(wd);
467 elm_genlist_item_selected_set(next, EINA_TRUE);
468 elm_genlist_item_show(next);
473 _on_focus_hook(void *data __UNUSED__,
476 Widget_Data *wd = elm_widget_data_get(obj);
478 if (elm_widget_focus_get(obj))
480 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
481 evas_object_focus_set(wd->obj, EINA_TRUE);
482 if ((wd->selected) && (!wd->last_selected_item))
483 wd->last_selected_item = eina_list_data_get(wd->selected);
487 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
488 evas_object_focus_set(wd->obj, EINA_FALSE);
493 _del_hook(Evas_Object *obj)
495 Widget_Data *wd = elm_widget_data_get(obj);
497 _item_cache_zero(wd);
498 if (wd->calc_job) ecore_job_del(wd->calc_job);
499 if (wd->update_job) ecore_job_del(wd->update_job);
500 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
501 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
502 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
503 if (wd->mode_type) eina_stringshare_del(wd->mode_type);
504 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
509 _del_pre_hook(Evas_Object *obj)
511 Widget_Data *wd = elm_widget_data_get(obj);
513 elm_genlist_clear(obj);
514 evas_object_del(wd->pan_smart);
515 wd->pan_smart = NULL;
519 _mirrored_set(Evas_Object *obj,
522 Widget_Data *wd = elm_widget_data_get(obj);
524 _item_cache_zero(wd);
525 elm_smart_scroller_mirrored_set(wd->scr, rtl);
529 _theme_hook(Evas_Object *obj)
531 Widget_Data *wd = elm_widget_data_get(obj);
534 evas_event_freeze(evas_object_evas_get(wd->obj));
535 _item_cache_zero(wd);
536 _elm_widget_mirrored_reload(obj);
537 _mirrored_set(obj, elm_widget_mirrored_get(obj));
538 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
539 elm_widget_style_get(obj));
540 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
541 wd->item_width = wd->item_height = 0;
542 wd->group_item_width = wd->group_item_height = 0;
543 wd->minw = wd->minh = wd->realminw = 0;
544 EINA_INLIST_FOREACH(wd->blocks, itb)
549 if (itb->realized) _item_block_unrealize(itb);
550 EINA_LIST_FOREACH(itb->items, l, it)
551 it->item->mincalcd = EINA_FALSE;
553 itb->changed = EINA_TRUE;
555 if (wd->calc_job) ecore_job_del(wd->calc_job);
556 wd->calc_job = ecore_job_add(_calc_job, wd);
558 evas_event_thaw(evas_object_evas_get(wd->obj));
559 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
563 _show_region_hook(void *data,
566 Widget_Data *wd = elm_widget_data_get(data);
567 Evas_Coord x, y, w, h;
569 elm_widget_show_region_get(obj, &x, &y, &w, &h);
570 //x & y are screen coordinates, Add with pan coordinates
573 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
577 _translate_hook(Evas_Object *obj)
579 evas_object_smart_callback_call(obj, "language,changed", NULL);
583 _sizing_eval(Evas_Object *obj)
585 Widget_Data *wd = elm_widget_data_get(obj);
586 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
588 evas_object_size_hint_min_get(wd->scr, &minw, &minh);
589 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
591 if (wd->height_for_width)
595 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
596 if ((vw != 0) && (vw != wd->prev_viewport_w))
600 wd->prev_viewport_w = vw;
601 EINA_INLIST_FOREACH(wd->blocks, itb)
603 itb->must_recalc = EINA_TRUE;
605 if (wd->calc_job) ecore_job_del(wd->calc_job);
606 wd->calc_job = ecore_job_add(_calc_job, wd);
609 if (wd->mode == ELM_LIST_LIMIT)
615 edje_object_size_min_calc
616 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
623 edje_object_size_min_calc
624 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
628 evas_object_size_hint_min_set(obj, minw, minh);
629 evas_object_size_hint_max_set(obj, maxw, maxh);
633 _signal_emit_hook(Evas_Object *obj,
634 const char *emission,
637 Widget_Data *wd = elm_widget_data_get(obj);
638 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
643 _item_highlight(Elm_Gen_Item *it)
645 const char *selectraise;
646 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->highlighted) ||
647 (it->disabled) || (it->display_only) || (it->item->mode_view))
649 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
650 selectraise = edje_object_data_get(VIEW(it), "selectraise");
651 if ((selectraise) && (!strcmp(selectraise, "on")))
653 evas_object_raise(VIEW(it));
654 if ((it->item->group_item) && (it->item->group_item->realized))
655 evas_object_raise(it->item->VIEW(group_item));
657 it->highlighted = EINA_TRUE;
661 _item_unhighlight(Elm_Gen_Item *it)
663 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
664 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
665 if (!it->item->nostacking)
667 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even) evas_object_lower(VIEW(it));
668 else evas_object_raise(VIEW(it));
670 it->highlighted = EINA_FALSE;
674 _item_block_del(Elm_Gen_Item *it)
677 Item_Block *itb = it->item->block;
679 itb->items = eina_list_remove(itb->items, it);
681 itb->changed = EINA_TRUE;
682 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
683 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
686 il = EINA_INLIST_GET(itb);
687 Item_Block *itbn = (Item_Block *)(il->next);
689 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
691 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
693 if (itbn) itbn->changed = EINA_TRUE;
697 if (itb->count < itb->wd->max_items_per_block/2)
699 il = EINA_INLIST_GET(itb);
700 Item_Block *itbp = (Item_Block *)(il->prev);
701 Item_Block *itbn = (Item_Block *)(il->next);
702 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
706 EINA_LIST_FREE(itb->items, it2)
708 it2->item->block = itbp;
709 itbp->items = eina_list_append(itbp->items, it2);
711 itbp->changed = EINA_TRUE;
713 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
714 EINA_INLIST_GET(itb));
717 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
721 Eina_List *last = eina_list_last(itb->items);
722 Elm_Gen_Item *it2 = last->data;
724 it2->item->block = itbn;
725 itb->items = eina_list_remove_list(itb->items, last);
726 itbn->items = eina_list_prepend(itbn->items, it2);
728 itbn->changed = EINA_TRUE;
731 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
739 _item_del(Elm_Gen_Item *it)
741 Evas_Object *obj = WIDGET(it);
743 evas_event_freeze(evas_object_evas_get(obj));
744 elm_genlist_item_subitems_clear(it);
745 if (it->wd->show_item == it) it->wd->show_item = NULL;
746 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
747 if (it->item->block) _item_block_del(it);
748 if (it->item->queued)
749 it->wd->queue = eina_list_remove(it->wd->queue, it);
750 if (it->wd->anchor_item == it)
752 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
753 if (!it->wd->anchor_item)
754 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
757 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
758 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
759 _elm_genlist_item_del_serious(it);
760 evas_event_thaw(evas_object_evas_get(obj));
761 evas_event_thaw_eval(evas_object_evas_get(obj));
765 _clear_cb(Widget_Data *wd)
767 wd->anchor_item = NULL;
770 Item_Block *itb = (Item_Block *)(wd->blocks);
772 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
773 if (itb->items) eina_list_free(itb->items);
776 if (wd->queue_idle_enterer)
778 ecore_idle_enterer_del(wd->queue_idle_enterer);
779 wd->queue_idle_enterer = NULL;
781 if (wd->must_recalc_idler)
783 ecore_idler_del(wd->must_recalc_idler);
784 wd->must_recalc_idler = NULL;
786 if (wd->queue) wd->queue = eina_list_free(wd->queue);
787 if (wd->reorder_move_animator)
789 ecore_animator_del(wd->reorder_move_animator);
790 wd->reorder_move_animator = NULL;
792 wd->show_item = NULL;
793 wd->reorder_old_pan_y = 0;
797 _item_unselect(Elm_Gen_Item *it)
799 if ((it->generation < it->wd->generation) || (!it->selected)) return;
800 it->selected = EINA_FALSE;
801 it->wd->selected = eina_list_remove(it->wd->selected, it);
802 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
806 _mouse_move(void *data,
807 Evas *evas __UNUSED__,
811 Elm_Gen_Item *it = data;
812 Evas_Event_Mouse_Move *ev = event_info;
813 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
814 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
816 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
818 if (!it->wd->on_hold)
820 it->wd->on_hold = EINA_TRUE;
821 if (!it->wd->wasselected)
823 _item_unhighlight(it);
828 if (it->wd->multitouched)
830 it->wd->cur_x = ev->cur.canvas.x;
831 it->wd->cur_y = ev->cur.canvas.y;
834 if ((it->dragging) && (it->down))
836 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
839 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
840 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
841 if (abs((it->wd->history[it->wd->movements].x -
842 it->wd->history[0].x)) > 40)
843 it->wd->swipe = EINA_TRUE;
849 ecore_timer_del(it->long_timer);
850 it->long_timer = NULL;
852 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
855 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
859 ecore_timer_del(it->long_timer);
860 it->long_timer = NULL;
862 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
864 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
865 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
867 if (!it->wd->reorder_start_y)
868 it->wd->reorder_start_y = it->item->block->y + it->y;
872 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
873 y_pos = oy + oh - it->wd->reorder_it->item->h;
877 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
879 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
880 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
884 if (!it->display_only)
885 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
886 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
887 x = ev->cur.canvas.x - x;
888 y = ev->cur.canvas.y - y;
891 if (adx < 0) adx = -dx;
894 if (ady < 0) ady = -dy;
897 if ((adx > minw) || (ady > minh))
899 it->dragging = EINA_TRUE;
902 ecore_timer_del(it->long_timer);
903 it->long_timer = NULL;
905 if (!it->wd->wasselected)
907 _item_unhighlight(it);
913 evas_object_smart_callback_call(WIDGET(it),
914 SIG_DRAG_START_UP, it);
918 evas_object_smart_callback_call(WIDGET(it),
919 SIG_DRAG_START_LEFT, it);
921 evas_object_smart_callback_call(WIDGET(it),
922 SIG_DRAG_START_RIGHT, it);
928 evas_object_smart_callback_call(WIDGET(it),
929 SIG_DRAG_START_DOWN, it);
933 evas_object_smart_callback_call(WIDGET(it),
934 SIG_DRAG_START_LEFT, it);
936 evas_object_smart_callback_call(WIDGET(it),
937 SIG_DRAG_START_RIGHT, it);
944 _long_press(void *data)
946 Elm_Gen_Item *it = data, *it_tmp;
949 it->long_timer = NULL;
950 if ((it->disabled) || (it->dragging) || (it->display_only))
951 return ECORE_CALLBACK_CANCEL;
952 it->wd->longpressed = EINA_TRUE;
953 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
954 if ((it->wd->reorder_mode) && (!it->group))
956 it->wd->reorder_it = it;
957 it->wd->reorder_start_y = 0;
959 evas_object_raise(VIEW(it));
960 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
961 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
963 list = elm_genlist_realized_items_get(it->wd->obj);
964 EINA_LIST_FOREACH(list, l, it_tmp)
966 if (it != it_tmp) _item_unselect(it_tmp);
968 if (elm_genlist_item_expanded_get(it))
970 elm_genlist_item_expanded_set(it, EINA_FALSE);
971 return ECORE_CALLBACK_RENEW;
973 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
975 return ECORE_CALLBACK_CANCEL;
979 _swipe(Elm_Gen_Item *it)
984 if ((it->display_only) || (it->disabled)) return;
985 it->wd->swipe = EINA_FALSE;
986 for (i = 0; i < it->wd->movements; i++)
988 sum += it->wd->history[i].x;
989 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
992 sum /= it->wd->movements;
993 if (abs(sum - it->wd->history[0].x) <= 10) return;
994 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
998 _swipe_cancel(void *data)
1000 Elm_Gen_Item *it = data;
1002 if (!it) return ECORE_CALLBACK_CANCEL;
1003 it->wd->swipe = EINA_FALSE;
1004 it->wd->movements = 0;
1005 return ECORE_CALLBACK_RENEW;
1009 _multi_cancel(void *data)
1011 Widget_Data *wd = data;
1013 if (!wd) return ECORE_CALLBACK_CANCEL;
1014 wd->multi_timeout = EINA_TRUE;
1015 return ECORE_CALLBACK_RENEW;
1019 _multi_touch_gesture_eval(void *data)
1021 Elm_Gen_Item *it = data;
1023 it->wd->multitouched = EINA_FALSE;
1024 if (it->wd->multi_timer)
1026 ecore_timer_del(it->wd->multi_timer);
1027 it->wd->multi_timer = NULL;
1029 if (it->wd->multi_timeout)
1031 it->wd->multi_timeout = EINA_FALSE;
1035 Evas_Coord minw = 0, minh = 0;
1036 Evas_Coord off_x, off_y, off_mx, off_my;
1038 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1039 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1040 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1041 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1042 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1044 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1046 if ((off_x + off_mx) > (off_y + off_my))
1048 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1049 evas_object_smart_callback_call(WIDGET(it),
1050 SIG_MULTI_SWIPE_RIGHT, it);
1051 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1052 evas_object_smart_callback_call(WIDGET(it),
1053 SIG_MULTI_SWIPE_LEFT, it);
1054 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1055 evas_object_smart_callback_call(WIDGET(it),
1056 SIG_MULTI_PINCH_OUT, it);
1058 evas_object_smart_callback_call(WIDGET(it),
1059 SIG_MULTI_PINCH_IN, it);
1063 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1064 evas_object_smart_callback_call(WIDGET(it),
1065 SIG_MULTI_SWIPE_DOWN, it);
1066 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1067 evas_object_smart_callback_call(WIDGET(it),
1068 SIG_MULTI_SWIPE_UP, it);
1069 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1070 evas_object_smart_callback_call(WIDGET(it),
1071 SIG_MULTI_PINCH_OUT, it);
1073 evas_object_smart_callback_call(WIDGET(it),
1074 SIG_MULTI_PINCH_IN, it);
1077 it->wd->multi_timeout = EINA_FALSE;
1081 _multi_down(void *data,
1082 Evas *evas __UNUSED__,
1083 Evas_Object *obj __UNUSED__,
1086 Elm_Gen_Item *it = data;
1087 Evas_Event_Multi_Down *ev = event_info;
1089 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1090 it->wd->multi_device = ev->device;
1091 it->wd->multi_down = EINA_TRUE;
1092 it->wd->multitouched = EINA_TRUE;
1093 it->wd->prev_mx = ev->canvas.x;
1094 it->wd->prev_my = ev->canvas.y;
1095 if (!it->wd->wasselected)
1097 _item_unhighlight(it);
1100 it->wd->wasselected = EINA_FALSE;
1101 it->wd->longpressed = EINA_FALSE;
1104 ecore_timer_del(it->long_timer);
1105 it->long_timer = NULL;
1109 it->dragging = EINA_FALSE;
1110 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1112 if (it->item->swipe_timer)
1114 ecore_timer_del(it->item->swipe_timer);
1115 it->item->swipe_timer = NULL;
1117 if (it->wd->on_hold)
1119 it->wd->swipe = EINA_FALSE;
1120 it->wd->movements = 0;
1121 it->wd->on_hold = EINA_FALSE;
1126 _multi_up(void *data,
1127 Evas *evas __UNUSED__,
1128 Evas_Object *obj __UNUSED__,
1131 Elm_Gen_Item *it = data;
1132 Evas_Event_Multi_Up *ev = event_info;
1134 if (it->wd->multi_device != ev->device) return;
1135 it->wd->multi_device = 0;
1136 it->wd->multi_down = EINA_FALSE;
1137 if (it->wd->mouse_down) return;
1138 _multi_touch_gesture_eval(data);
1142 _multi_move(void *data,
1143 Evas *evas __UNUSED__,
1144 Evas_Object *obj __UNUSED__,
1147 Elm_Gen_Item *it = data;
1148 Evas_Event_Multi_Move *ev = event_info;
1150 if (it->wd->multi_device != ev->device) return;
1151 it->wd->cur_mx = ev->cur.canvas.x;
1152 it->wd->cur_my = ev->cur.canvas.y;
1156 _mouse_down(void *data,
1157 Evas *evas __UNUSED__,
1161 Elm_Gen_Item *it = data;
1162 Evas_Event_Mouse_Down *ev = event_info;
1165 if (ev->button != 1) return;
1166 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1168 it->wd->on_hold = EINA_TRUE;
1171 it->down = EINA_TRUE;
1172 it->dragging = EINA_FALSE;
1173 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1174 it->dx = ev->canvas.x - x;
1175 it->dy = ev->canvas.y - y;
1176 it->wd->mouse_down = EINA_TRUE;
1177 if (!it->wd->multitouched)
1179 it->wd->prev_x = ev->canvas.x;
1180 it->wd->prev_y = ev->canvas.y;
1181 it->wd->multi_timeout = EINA_FALSE;
1182 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1183 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1185 it->wd->longpressed = EINA_FALSE;
1186 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1187 else it->wd->on_hold = EINA_FALSE;
1188 if (it->wd->on_hold) return;
1189 it->wd->wasselected = it->selected;
1190 _item_highlight(it);
1191 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1192 if ((!it->disabled) && (!it->display_only))
1194 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1195 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1197 if (it->long_timer) ecore_timer_del(it->long_timer);
1198 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1199 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1201 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1204 it->long_timer = NULL;
1205 it->wd->swipe = EINA_FALSE;
1206 it->wd->movements = 0;
1210 _mouse_up(void *data,
1211 Evas *evas __UNUSED__,
1212 Evas_Object *obj __UNUSED__,
1215 Elm_Gen_Item *it = data;
1216 Evas_Event_Mouse_Up *ev = event_info;
1217 Eina_Bool dragged = EINA_FALSE;
1219 if (ev->button != 1) return;
1220 it->down = EINA_FALSE;
1221 it->wd->mouse_down = EINA_FALSE;
1222 if (it->wd->multitouched)
1224 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1225 if (it->wd->multi_down) return;
1226 _multi_touch_gesture_eval(data);
1229 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1230 else it->wd->on_hold = EINA_FALSE;
1233 ecore_timer_del(it->long_timer);
1234 it->long_timer = NULL;
1238 it->dragging = EINA_FALSE;
1239 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1242 if (it->item->swipe_timer)
1244 ecore_timer_del(it->item->swipe_timer);
1245 it->item->swipe_timer = NULL;
1247 if (it->wd->multi_timer)
1249 ecore_timer_del(it->wd->multi_timer);
1250 it->wd->multi_timer = NULL;
1251 it->wd->multi_timeout = EINA_FALSE;
1253 if (it->wd->on_hold)
1255 if (it->wd->swipe) _swipe(data);
1256 it->wd->longpressed = EINA_FALSE;
1257 it->wd->on_hold = EINA_FALSE;
1260 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1262 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1264 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1266 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1267 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1269 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1273 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1274 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1276 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1277 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1278 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1279 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1281 if (it->wd->longpressed)
1283 it->wd->longpressed = EINA_FALSE;
1284 if (!it->wd->wasselected)
1286 _item_unhighlight(it);
1289 it->wd->wasselected = EINA_FALSE;
1294 if (it->want_unrealize)
1296 _elm_genlist_item_unrealize(it, EINA_FALSE);
1297 if (it->item->block->want_unrealize)
1298 _item_block_unrealize(it->item->block);
1301 if ((it->disabled) || (dragged) || (it->display_only)) return;
1302 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1307 _item_highlight(it);
1312 _item_unhighlight(it);
1320 Widget_Data *wd = it->wd;
1323 while (wd->selected)
1325 _item_unhighlight(wd->selected->data);
1326 _item_unselect(wd->selected->data);
1332 const Eina_List *l, *l_next;
1335 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1338 _item_unhighlight(it2);
1339 _item_unselect(it2);
1341 //_item_highlight(it);
1344 _item_highlight(it);
1350 _signal_expand_toggle(void *data,
1351 Evas_Object *obj __UNUSED__,
1352 const char *emission __UNUSED__,
1353 const char *source __UNUSED__)
1355 Elm_Gen_Item *it = data;
1357 if (it->item->expanded)
1358 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1360 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1364 _signal_expand(void *data,
1365 Evas_Object *obj __UNUSED__,
1366 const char *emission __UNUSED__,
1367 const char *source __UNUSED__)
1369 Elm_Gen_Item *it = data;
1371 if (!it->item->expanded)
1372 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1376 _signal_contract(void *data,
1377 Evas_Object *obj __UNUSED__,
1378 const char *emission __UNUSED__,
1379 const char *source __UNUSED__)
1381 Elm_Gen_Item *it = data;
1383 if (it->item->expanded)
1384 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1388 _scr_hold_timer_cb(void *data)
1390 if (!data) return ECORE_CALLBACK_CANCEL;
1391 Widget_Data *wd = data;
1392 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1393 wd->scr_hold_timer = NULL;
1394 return ECORE_CALLBACK_CANCEL;
1398 _mode_finished_signal_cb(void *data,
1400 const char *emission __UNUSED__,
1401 const char *source __UNUSED__)
1405 Elm_Gen_Item *it = data;
1406 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1408 Evas *te = evas_object_evas_get(obj);
1410 evas_event_freeze(te);
1411 it->item->nocache = EINA_FALSE;
1412 _mode_item_unrealize(it);
1413 if (it->item->group_item)
1414 evas_object_raise(it->item->VIEW(group_item));
1415 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->mode_type);
1416 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1417 evas_event_thaw(te);
1418 evas_event_thaw_eval(te);
1422 _item_cache_clean(Widget_Data *wd)
1424 evas_event_freeze(evas_object_evas_get(wd->obj));
1425 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1429 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1430 wd->item_cache = eina_inlist_remove(wd->item_cache,
1431 wd->item_cache->last);
1432 wd->item_cache_count--;
1433 if (itc->spacer) evas_object_del(itc->spacer);
1434 if (itc->base_view) evas_object_del(itc->base_view);
1435 if (itc->item_style) eina_stringshare_del(itc->item_style);
1438 evas_event_thaw(evas_object_evas_get(wd->obj));
1439 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1443 _item_cache_zero(Widget_Data *wd)
1445 int pmax = wd->item_cache_max;
1446 wd->item_cache_max = 0;
1447 _item_cache_clean(wd);
1448 wd->item_cache_max = pmax;
1452 _item_cache_add(Elm_Gen_Item *it)
1456 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1457 if (it->wd->item_cache_max <= 0)
1459 evas_object_del(VIEW(it));
1461 evas_object_del(it->spacer);
1463 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1464 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1468 it->wd->item_cache_count++;
1469 itc = calloc(1, sizeof(Item_Cache));
1470 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1471 EINA_INLIST_GET(itc));
1472 itc->spacer = it->spacer;
1474 itc->base_view = VIEW(it);
1476 evas_object_hide(itc->base_view);
1477 evas_object_move(itc->base_view, -9999, -9999);
1478 itc->item_style = eina_stringshare_add(it->itc->item_style);
1479 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) itc->tree = 1;
1480 itc->compress = (it->wd->compress);
1481 itc->selected = it->selected;
1482 itc->disabled = it->disabled;
1483 itc->expanded = it->item->expanded;
1486 ecore_timer_del(it->long_timer);
1487 it->long_timer = NULL;
1489 if (it->item->swipe_timer)
1491 ecore_timer_del(it->item->swipe_timer);
1492 it->item->swipe_timer = NULL;
1494 // FIXME: other callbacks?
1495 edje_object_signal_callback_del_full(itc->base_view,
1496 "elm,action,expand,toggle",
1497 "elm", _signal_expand_toggle, it);
1498 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1500 _signal_expand, it);
1501 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1502 "elm", _signal_contract, it);
1503 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1505 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1507 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1509 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1511 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1513 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1515 _item_cache_clean(it->wd);
1516 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1517 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1521 _item_cache_find(Elm_Gen_Item *it)
1526 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) tree = 1;
1527 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1529 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1531 if ((itc->tree == tree) &&
1532 (itc->compress == it->wd->compress) &&
1533 (!strcmp(it->itc->item_style, itc->item_style)))
1535 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1536 EINA_INLIST_GET(itc));
1537 it->wd->item_cache_count--;
1545 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1547 if (!it->item->nostacking)
1549 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1550 evas_object_lower(VIEW(it));
1552 evas_object_raise(VIEW(it));
1555 if (it->item->order_num_in & 0x1)
1556 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1558 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1562 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1566 if (it->selected != itc->selected)
1569 edje_object_signal_emit(VIEW(it),
1570 "elm,state,selected", "elm");
1572 if (it->disabled != itc->disabled)
1575 edje_object_signal_emit(VIEW(it),
1576 "elm,state,disabled", "elm");
1578 if (it->item->expanded != itc->expanded)
1580 if (it->item->expanded)
1581 edje_object_signal_emit(VIEW(it),
1582 "elm,state,expanded", "elm");
1588 edje_object_signal_emit(VIEW(it),
1589 "elm,state,selected", "elm");
1591 edje_object_signal_emit(VIEW(it),
1592 "elm,state,disabled", "elm");
1593 if (it->item->expanded)
1594 edje_object_signal_emit(VIEW(it),
1595 "elm,state,expanded", "elm");
1600 _item_cache_free(Item_Cache *itc)
1602 if (itc->spacer) evas_object_del(itc->spacer);
1603 if (itc->base_view) evas_object_del(itc->base_view);
1604 if (itc->item_style) eina_stringshare_del(itc->item_style);
1609 _item_del_hook(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1611 Elm_Gen_Item *it = event_info;
1613 if (it->wd->last_selected_item == it)
1614 it->wd->last_selected_item = NULL;
1618 _item_text_realize(Elm_Gen_Item *it,
1619 Evas_Object *target,
1623 if (it->itc->func.text_get)
1628 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1629 EINA_LIST_FOREACH(*source, l, key)
1631 if (parts && fnmatch(parts, key, FNM_PERIOD))
1634 char *s = it->itc->func.text_get
1635 ((void *)it->base.data, WIDGET(it), key);
1639 edje_object_part_text_set(target, key, s);
1644 edje_object_part_text_set(target, key, "");
1651 _item_content_unrealize(Elm_Gen_Item *it,
1652 Evas_Object *target,
1656 Eina_List *res = it->content_objs;
1658 if (it->itc->func.content_get)
1662 Evas_Object *ic = NULL;
1664 EINA_LIST_FOREACH(*source, l, key)
1666 if (parts && fnmatch(parts, key, FNM_PERIOD))
1669 ic = edje_object_part_swallow_get(target, key);
1672 res = eina_list_remove(res, ic);
1673 edje_object_part_unswallow(target, ic);
1674 evas_object_del(ic);
1683 _item_content_realize(Elm_Gen_Item *it,
1684 Evas_Object *target,
1688 Eina_List *res = NULL;
1690 if (it->itc->func.content_get)
1694 Evas_Object *ic = NULL;
1696 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1698 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
1699 res = it->content_objs;
1701 EINA_LIST_FOREACH(*source, l, key)
1703 if (parts && fnmatch(parts, key, FNM_PERIOD))
1706 if (it->itc->func.content_get)
1707 ic = it->itc->func.content_get
1708 ((void *)it->base.data, WIDGET(it), key);
1711 res = eina_list_append(res, ic);
1712 edje_object_part_swallow(target, key, ic);
1713 evas_object_show(ic);
1714 elm_widget_sub_object_add(WIDGET(it), ic);
1716 elm_widget_disabled_set(ic, EINA_TRUE);
1725 _item_state_realize(Elm_Gen_Item *it,
1726 Evas_Object *target,
1730 if (it->itc->func.state_get)
1736 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
1737 EINA_LIST_FOREACH(*source, l, key)
1739 if (parts && fnmatch(parts, key, FNM_PERIOD))
1742 Eina_Bool on = it->itc->func.state_get
1743 ((void *)it->base.data, WIDGET(it), key);
1747 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1748 edje_object_signal_emit(target, buf, "elm");
1752 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1753 edje_object_signal_emit(target, buf, "elm");
1760 _item_realize(Elm_Gen_Item *it,
1764 const char *treesize;
1767 Item_Cache *itc = NULL;
1769 if (it->generation < it->wd->generation) return;
1770 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1773 if (it->item->order_num_in != in)
1775 it->item->order_num_in = in;
1776 _elm_genlist_item_odd_even_update(it);
1777 _elm_genlist_item_state_update(it, NULL);
1779 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1780 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1783 it->item->order_num_in = in;
1785 if (it->item->nocache)
1786 it->item->nocache = EINA_FALSE;
1788 itc = _item_cache_find(it);
1791 VIEW(it) = itc->base_view;
1792 itc->base_view = NULL;
1793 it->spacer = itc->spacer;
1798 const char *stacking_even;
1799 const char *stacking;
1801 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1802 edje_object_scale_set(VIEW(it),
1803 elm_widget_scale_get(WIDGET(it)) *
1804 _elm_config->scale);
1805 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
1806 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1808 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
1809 strncpy(buf, "tree", sizeof(buf));
1810 else strncpy(buf, "item", sizeof(buf));
1811 if (it->wd->compress)
1812 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1814 strncat(buf, "/", sizeof(buf) - strlen(buf));
1815 strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1817 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
1818 elm_widget_style_get(WIDGET(it)));
1820 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1821 if (!stacking_even) stacking_even = "above";
1822 it->item->stacking_even = !!strcmp("above", stacking_even);
1824 stacking = edje_object_data_get(VIEW(it), "stacking");
1825 if (!stacking) stacking = "yes";
1826 it->item->nostacking = !!strcmp("yes", stacking);
1828 edje_object_mirrored_set(VIEW(it),
1829 elm_widget_mirrored_get(WIDGET(it)));
1831 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1832 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1833 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1836 _elm_genlist_item_odd_even_update(it);
1838 treesize = edje_object_data_get(VIEW(it), "treesize");
1839 if (treesize) tsize = atoi(treesize);
1840 evas_object_size_hint_min_set(it->spacer,
1841 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
1842 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1845 edje_object_signal_callback_add(VIEW(it),
1846 "elm,action,expand,toggle",
1847 "elm", _signal_expand_toggle, it);
1848 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
1849 "elm", _signal_expand, it);
1850 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
1851 "elm", _signal_contract, it);
1852 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
1854 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
1856 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1858 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
1860 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
1862 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
1865 _elm_genlist_item_state_update(it, itc);
1868 if ((calc) && (it->wd->homogeneous) &&
1869 ((it->wd->item_width) ||
1870 ((it->wd->item_width) && (it->wd->group_item_width))))
1872 /* homogenous genlist shortcut */
1873 if (!it->item->mincalcd)
1877 it->item->w = it->item->minw = it->wd->group_item_width;
1878 it->item->h = it->item->minh = it->wd->group_item_height;
1882 it->item->w = it->item->minw = it->wd->item_width;
1883 it->item->h = it->item->minh = it->wd->item_height;
1885 it->item->mincalcd = EINA_TRUE;
1890 /* FIXME: If you see that assert, please notify us and we
1891 will clean our mess */
1892 assert(eina_list_count(it->content_objs) == 0);
1894 _item_text_realize(it, VIEW(it), &it->texts, NULL);
1895 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
1896 _item_state_realize(it, VIEW(it), &it->states, NULL);
1898 if (!it->item->mincalcd)
1900 Evas_Coord mw = -1, mh = -1;
1902 if (!it->display_only)
1903 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1904 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
1905 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
1907 if (!it->display_only)
1908 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1909 it->item->w = it->item->minw = mw;
1910 it->item->h = it->item->minh = mh;
1911 it->item->mincalcd = EINA_TRUE;
1913 if ((!it->wd->group_item_width) && (it->group))
1915 it->wd->group_item_width = mw;
1916 it->wd->group_item_height = mh;
1918 else if ((!it->wd->item_width) && (it->item->flags == ELM_GENLIST_ITEM_NONE))
1920 it->wd->item_width = mw;
1921 it->wd->item_height = mh;
1924 if (!calc) evas_object_show(VIEW(it));
1927 if (it->tooltip.content_cb)
1929 elm_widget_item_tooltip_content_cb_set(it,
1930 it->tooltip.content_cb,
1931 it->tooltip.data, NULL);
1932 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1933 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1936 if (it->mouse_cursor)
1937 elm_widget_item_cursor_set(it, it->mouse_cursor);
1939 it->realized = EINA_TRUE;
1940 it->want_unrealize = EINA_FALSE;
1942 if (itc) _item_cache_free(itc);
1943 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1944 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1946 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1947 edje_object_message_signal_process(VIEW(it));
1951 _item_unrealize_cb(Elm_Gen_Item *it)
1953 if (it->item->nocache)
1955 evas_object_del(VIEW(it));
1957 evas_object_del(it->spacer);
1962 edje_object_mirrored_set(VIEW(it),
1963 elm_widget_mirrored_get(WIDGET(it)));
1964 edje_object_scale_set(VIEW(it),
1965 elm_widget_scale_get(WIDGET(it))
1966 * _elm_config->scale);
1967 _item_cache_add(it);
1970 _mode_item_unrealize(it);
1972 it->realized = EINA_FALSE;
1973 it->want_unrealize = EINA_FALSE;
1977 _item_block_recalc(Item_Block *itb,
1983 Evas_Coord minw = 0, minh = 0;
1984 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
1987 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
1989 EINA_LIST_FOREACH(itb->items, l, it)
1991 if (it->generation < it->wd->generation) continue;
1992 showme |= it->item->showme;
1997 if (!it->item->mincalcd) changed = EINA_TRUE;
2000 _item_realize(it, in, EINA_TRUE);
2001 _elm_genlist_item_unrealize(it, EINA_TRUE);
2006 _item_realize(it, in, EINA_TRUE);
2007 _elm_genlist_item_unrealize(it, EINA_TRUE);
2011 _item_realize(it, in, EINA_FALSE);
2012 minh += it->item->minh;
2013 if (minw < it->item->minw) minw = it->item->minw;
2021 itb->changed = EINA_FALSE;
2022 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2023 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2028 _item_block_realize(Item_Block *itb)
2030 if (itb->realized) return;
2031 itb->realized = EINA_TRUE;
2032 itb->want_unrealize = EINA_FALSE;
2036 _item_block_unrealize(Item_Block *itb)
2040 Eina_Bool dragging = EINA_FALSE;
2042 if (!itb->realized) return;
2043 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2044 EINA_LIST_FOREACH(itb->items, l, it)
2046 if (itb->must_recalc || !it->group)
2050 dragging = EINA_TRUE;
2051 it->want_unrealize = EINA_TRUE;
2054 _elm_genlist_item_unrealize(it, EINA_FALSE);
2059 itb->realized = EINA_FALSE;
2060 itb->want_unrealize = EINA_TRUE;
2063 itb->want_unrealize = EINA_FALSE;
2064 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2065 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2069 _get_space_for_reorder_item(Elm_Gen_Item *it)
2071 Evas_Coord rox, roy, row, roh, oy, oh;
2072 Eina_Bool top = EINA_FALSE;
2073 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2074 if (!reorder_it) return 0;
2076 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2077 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2079 if ((it->wd->reorder_start_y < it->item->block->y) &&
2080 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2082 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2083 if (it->item->block->count == 1)
2084 it->wd->reorder_rel = it;
2086 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2087 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2089 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2092 it->item->block->reorder_offset = 0;
2094 it->item->scrl_y += it->item->block->reorder_offset;
2096 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2097 rox, roy + (roh / 2), row, 1));
2100 it->wd->reorder_rel = it;
2101 it->item->scrl_y += it->wd->reorder_it->item->h;
2102 return it->wd->reorder_it->item->h;
2109 _reorder_move_animator_cb(void *data)
2111 Elm_Gen_Item *it = data;
2112 Eina_Bool down = EINA_FALSE;
2114 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2116 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2118 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2121 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2122 if (diff > it->item->h) y = diff / 2;
2124 if (it->item->old_scrl_y < it->item->scrl_y)
2126 it->item->old_scrl_y += y;
2129 else if (it->item->old_scrl_y > it->item->scrl_y)
2131 it->item->old_scrl_y -= y;
2134 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2135 _group_items_recalc(it->wd);
2137 if ((it->wd->reorder_pan_move) ||
2138 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2139 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2141 it->item->old_scrl_y = it->item->scrl_y;
2142 it->item->move_effect_enabled = EINA_FALSE;
2143 it->wd->reorder_move_animator = NULL;
2144 return ECORE_CALLBACK_CANCEL;
2146 return ECORE_CALLBACK_RENEW;
2150 _item_position(Elm_Gen_Item *it,
2158 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2159 evas_object_resize(view, it->item->w, it->item->h);
2160 evas_object_move(view, it_x, it_y);
2161 evas_object_show(view);
2162 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2163 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2167 _item_block_position(Item_Block *itb,
2173 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2174 Eina_Bool vis = EINA_FALSE;
2176 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2177 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2178 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2180 EINA_LIST_FOREACH(itb->items, l, it)
2182 if (it->generation < it->wd->generation) continue;
2183 else if (it->wd->reorder_it == it) continue;
2186 it->item->w = itb->w;
2187 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2188 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2190 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2191 cvx, cvy, cvw, cvh));
2194 if ((itb->realized) && (!it->realized))
2196 if (vis) _item_realize(it, in, EINA_FALSE);
2202 if (it->wd->reorder_mode)
2203 y += _get_space_for_reorder_item(it);
2204 git = it->item->group_item;
2207 if (git->item->scrl_y < oy)
2208 git->item->scrl_y = oy;
2209 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2210 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2211 git->item->want_realize = EINA_TRUE;
2213 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2215 if (!it->item->move_effect_enabled)
2217 it->item->move_effect_enabled = EINA_TRUE;
2218 it->wd->reorder_move_animator =
2220 _reorder_move_animator_cb, it);
2223 if (!it->item->move_effect_enabled)
2225 if (it->item->mode_view)
2226 _item_position(it, it->item->mode_view, it->item->scrl_x,
2229 _item_position(it, VIEW(it), it->item->scrl_x,
2231 it->item->old_scrl_y = it->item->scrl_y;
2236 if (!it->dragging) _elm_genlist_item_unrealize(it, EINA_FALSE);
2243 if (vis) it->item->want_realize = EINA_TRUE;
2247 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2248 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2252 _group_items_recalc(void *data)
2254 Widget_Data *wd = data;
2258 evas_event_freeze(evas_object_evas_get(wd->obj));
2259 EINA_LIST_FOREACH(wd->group_items, l, git)
2261 if (git->item->want_realize)
2264 _item_realize(git, 0, EINA_FALSE);
2265 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2266 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2267 evas_object_show(VIEW(git));
2268 evas_object_raise(VIEW(git));
2270 else if (!git->item->want_realize && git->realized)
2273 _elm_genlist_item_unrealize(git, EINA_FALSE);
2276 evas_event_thaw(evas_object_evas_get(wd->obj));
2277 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2281 _must_recalc_idler(void *data)
2283 Widget_Data *wd = data;
2284 if (wd->calc_job) ecore_job_del(wd->calc_job);
2285 wd->calc_job = ecore_job_add(_calc_job, wd);
2286 wd->must_recalc_idler = NULL;
2287 return ECORE_CALLBACK_CANCEL;
2291 _scroll_item(Widget_Data *wd)
2293 Elm_Genlist_Item *it = NULL;
2294 Evas_Coord gith = 0;
2295 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2297 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2299 dx = it->x + it->item->block->x;
2300 dy = it->y + it->item->block->y;
2301 dw = it->item->block->w;
2303 switch (wd->scrollto_type)
2305 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2306 if (it->item->group_item) gith = it->item->group_item->item->h;
2309 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2310 dy += (it->item->h / 2 - oh / 2);
2312 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2314 if ((wd->expanded_item) &&
2315 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2316 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2318 it = wd->expanded_item;
2319 if (it->item->group_item) gith = it->item->group_item->item->h;
2320 dx = it->x + it->item->block->x;
2321 dy = it->y + it->item->block->y - gith;
2322 dw = it->item->block->w;
2326 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2327 gith = it->item->group_item->item->h;
2334 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2336 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2338 it->item->showme = EINA_FALSE;
2339 wd->show_item = NULL;
2340 wd->auto_scroll_enabled = EINA_FALSE;
2341 wd->check_scroll = EINA_FALSE;
2345 _calc_job(void *data)
2347 Widget_Data *wd = data;
2348 Item_Block *itb, *chb = NULL;
2349 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0;
2350 Evas_Coord pan_w = 0, pan_h = 0;
2352 Eina_Bool minw_change = EINA_FALSE;
2353 Eina_Bool did_must_recalc = EINA_FALSE;
2356 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2360 evas_event_freeze(evas_object_evas_get(wd->obj));
2361 EINA_INLIST_FOREACH(wd->blocks, itb)
2363 Eina_Bool showme = EINA_FALSE;
2366 showme = itb->showme;
2367 itb->showme = EINA_FALSE;
2370 if (itb->realized) _item_block_unrealize(itb);
2372 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2374 if (itb->must_recalc)
2378 EINA_LIST_FOREACH(itb->items, l, it)
2379 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2380 itb->changed = EINA_TRUE;
2381 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2382 if (itb->realized) _item_block_unrealize(itb);
2383 itb->must_recalc = EINA_FALSE;
2385 showme = _item_block_recalc(itb, in, EINA_FALSE);
2391 if (minw == -1) minw = itb->minw;
2392 else if ((!itb->must_recalc) && (minw < itb->minw))
2395 minw_change = EINA_TRUE;
2401 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2402 wd->check_scroll = EINA_TRUE;
2406 EINA_INLIST_FOREACH(wd->blocks, itb)
2412 if ((chb) && (EINA_INLIST_GET(chb)->next))
2414 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2416 if (itb->realized) _item_block_unrealize(itb);
2419 wd->realminw = minw;
2420 if (minw < wd->w) minw = wd->w;
2421 if ((minw != wd->minw) || (minh != wd->minh))
2425 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2426 _sizing_eval(wd->obj);
2427 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2432 it = wd->anchor_item;
2433 it_y = wd->anchor_y;
2434 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2435 it->item->block->y + it->y + it_y);
2436 wd->anchor_item = it;
2437 wd->anchor_y = it_y;
2440 if (did_must_recalc)
2442 if (!wd->must_recalc_idler)
2443 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2445 if (wd->check_scroll)
2447 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2448 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2449 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2450 switch (wd->scrollto_type)
2452 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2455 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2458 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2463 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2464 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2469 wd->calc_job = NULL;
2470 evas_object_smart_changed(wd->pan_smart);
2471 evas_event_thaw(evas_object_evas_get(wd->obj));
2472 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2476 _update_job(void *data)
2478 Widget_Data *wd = data;
2482 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2484 wd->update_job = NULL;
2487 evas_event_freeze(evas_object_evas_get(wd->obj));
2488 EINA_INLIST_FOREACH(wd->blocks, itb)
2490 Evas_Coord itminw, itminh;
2497 _item_block_position(itb, num);
2501 recalc = EINA_FALSE;
2502 EINA_LIST_FOREACH(itb->items, l2, it)
2504 if (it->item->updateme)
2506 itminw = it->item->minw;
2507 itminh = it->item->minh;
2509 it->item->updateme = EINA_FALSE;
2512 _elm_genlist_item_unrealize(it, EINA_FALSE);
2513 _item_realize(it, num, EINA_FALSE);
2514 position = EINA_TRUE;
2518 _item_realize(it, num, EINA_TRUE);
2519 _elm_genlist_item_unrealize(it, EINA_TRUE);
2521 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2526 itb->updateme = EINA_FALSE;
2529 position = EINA_TRUE;
2530 itb->changed = EINA_TRUE;
2531 _item_block_recalc(itb, num0, EINA_FALSE);
2532 _item_block_position(itb, num0);
2537 if (wd->calc_job) ecore_job_del(wd->calc_job);
2538 wd->calc_job = ecore_job_add(_calc_job, wd);
2540 evas_event_thaw(evas_object_evas_get(wd->obj));
2541 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2545 _pan_set(Evas_Object *obj,
2549 Pan *sd = evas_object_smart_data_get(obj);
2553 // Evas_Coord ow, oh;
2554 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2555 // ow = sd->wd->minw - ow;
2556 // if (ow < 0) ow = 0;
2557 // oh = sd->wd->minh - oh;
2558 // if (oh < 0) oh = 0;
2559 // if (x < 0) x = 0;
2560 // if (y < 0) y = 0;
2561 // if (x > ow) x = ow;
2562 // if (y > oh) y = oh;
2563 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2567 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2569 if ((itb->y + itb->h) > y)
2574 EINA_LIST_FOREACH(itb->items, l2, it)
2576 if ((itb->y + it->y) >= y)
2578 sd->wd->anchor_item = it;
2579 sd->wd->anchor_y = -(itb->y + it->y - y);
2586 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2590 _pan_get(Evas_Object *obj,
2594 Pan *sd = evas_object_smart_data_get(obj);
2597 if (x) *x = sd->wd->pan_x;
2598 if (y) *y = sd->wd->pan_y;
2602 _pan_max_get(Evas_Object *obj,
2606 Pan *sd = evas_object_smart_data_get(obj);
2610 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2611 ow = sd->wd->minw - ow;
2613 oh = sd->wd->minh - oh;
2620 _pan_min_get(Evas_Object *obj __UNUSED__,
2629 _pan_child_size_get(Evas_Object *obj,
2633 Pan *sd = evas_object_smart_data_get(obj);
2636 if (w) *w = sd->wd->minw;
2637 if (h) *h = sd->wd->minh;
2641 _pan_add(Evas_Object *obj)
2644 Evas_Object_Smart_Clipped_Data *cd;
2647 cd = evas_object_smart_data_get(obj);
2650 sd->__clipped_data = *cd;
2652 evas_object_smart_data_set(obj, sd);
2656 _pan_del(Evas_Object *obj)
2658 Pan *sd = evas_object_smart_data_get(obj);
2663 ecore_job_del(sd->resize_job);
2664 sd->resize_job = NULL;
2670 _pan_resize_job(void *data)
2674 _sizing_eval(sd->wd->obj);
2675 sd->resize_job = NULL;
2679 _pan_resize(Evas_Object *obj,
2683 Pan *sd = evas_object_smart_data_get(obj);
2687 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2688 if ((ow == w) && (oh == h)) return;
2689 if ((sd->wd->height_for_width) && (ow != w))
2692 if (sd->resize_job) ecore_job_del(sd->resize_job);
2693 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2695 sd->wd->pan_changed = EINA_TRUE;
2696 evas_object_smart_changed(obj);
2697 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2698 sd->wd->calc_job = NULL;
2700 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2701 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2706 _pan_calculate(Evas_Object *obj)
2708 Pan *sd = evas_object_smart_data_get(obj);
2710 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2716 evas_event_freeze(evas_object_evas_get(obj));
2718 if (sd->wd->pan_changed)
2721 sd->wd->pan_changed = EINA_FALSE;
2724 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2725 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2726 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2728 git->item->want_realize = EINA_FALSE;
2730 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2732 itb->w = sd->wd->minw;
2733 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2734 itb->y - sd->wd->pan_y + oy,
2736 cvx, cvy, cvw, cvh))
2738 if ((!itb->realized) || (itb->changed))
2739 _item_block_realize(itb);
2740 _item_block_position(itb, in);
2744 if (itb->realized) _item_block_unrealize(itb);
2748 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2749 _group_items_recalc(sd->wd);
2750 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2752 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2753 sd->wd->reorder_pan_move = EINA_TRUE;
2754 else sd->wd->reorder_pan_move = EINA_FALSE;
2755 evas_object_raise(sd->wd->VIEW(reorder_it));
2756 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2757 sd->wd->start_time = ecore_loop_time_get();
2759 _item_auto_scroll(sd->wd);
2760 evas_event_thaw(evas_object_evas_get(obj));
2761 evas_event_thaw_eval(evas_object_evas_get(obj));
2765 _pan_move(Evas_Object *obj,
2766 Evas_Coord x __UNUSED__,
2767 Evas_Coord y __UNUSED__)
2769 Pan *sd = evas_object_smart_data_get(obj);
2773 sd->wd->pan_changed = EINA_TRUE;
2774 evas_object_smart_changed(obj);
2775 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2776 sd->wd->calc_job = NULL;
2780 _hold_on(void *data __UNUSED__,
2782 void *event_info __UNUSED__)
2784 Widget_Data *wd = elm_widget_data_get(obj);
2786 elm_smart_scroller_hold_set(wd->scr, 1);
2790 _hold_off(void *data __UNUSED__,
2792 void *event_info __UNUSED__)
2794 Widget_Data *wd = elm_widget_data_get(obj);
2796 elm_smart_scroller_hold_set(wd->scr, 0);
2800 _freeze_on(void *data __UNUSED__,
2802 void *event_info __UNUSED__)
2804 Widget_Data *wd = elm_widget_data_get(obj);
2806 elm_smart_scroller_freeze_set(wd->scr, 1);
2810 _freeze_off(void *data __UNUSED__,
2812 void *event_info __UNUSED__)
2814 Widget_Data *wd = elm_widget_data_get(obj);
2816 elm_smart_scroller_freeze_set(wd->scr, 0);
2820 _scr_anim_start(void *data,
2821 Evas_Object *obj __UNUSED__,
2822 void *event_info __UNUSED__)
2824 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
2828 _scr_anim_stop(void *data,
2829 Evas_Object *obj __UNUSED__,
2830 void *event_info __UNUSED__)
2832 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
2836 _scr_drag_start(void *data,
2837 Evas_Object *obj __UNUSED__,
2838 void *event_info __UNUSED__)
2840 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
2844 _scr_drag_stop(void *data,
2845 Evas_Object *obj __UNUSED__,
2846 void *event_info __UNUSED__)
2848 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
2852 _edge_left(void *data,
2853 Evas_Object *scr __UNUSED__,
2854 void *event_info __UNUSED__)
2856 Evas_Object *obj = data;
2857 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2861 _edge_right(void *data,
2862 Evas_Object *scr __UNUSED__,
2863 void *event_info __UNUSED__)
2865 Evas_Object *obj = data;
2866 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2870 _edge_top(void *data,
2871 Evas_Object *scr __UNUSED__,
2872 void *event_info __UNUSED__)
2874 Evas_Object *obj = data;
2875 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2879 _edge_bottom(void *data,
2880 Evas_Object *scr __UNUSED__,
2881 void *event_info __UNUSED__)
2883 Evas_Object *obj = data;
2884 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2888 _mode_item_realize(Elm_Gen_Item *it)
2892 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
2894 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2895 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
2896 edje_object_scale_set(it->item->mode_view,
2897 elm_widget_scale_get(WIDGET(it)) *
2898 _elm_config->scale);
2899 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
2900 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
2902 strncpy(buf, "item", sizeof(buf));
2903 if (it->wd->compress)
2904 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
2906 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
2907 strncat(buf, "/", sizeof(buf) - strlen(buf));
2908 strncat(buf, it->wd->mode_item_style, sizeof(buf) - strlen(buf));
2910 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
2911 elm_widget_style_get(WIDGET(it)));
2912 edje_object_mirrored_set(it->item->mode_view,
2913 elm_widget_mirrored_get(WIDGET(it)));
2915 /* signal callback add */
2916 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
2918 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
2920 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
2923 /* text_get, content_get, state_get */
2924 /* FIXME: If you see that assert, please notify us and we
2925 will clean our mess */
2926 assert(eina_list_count(it->item->mode_content_objs) == 0);
2928 _item_text_realize(it, it->item->mode_view, &it->item->mode_texts, NULL);
2929 it->item->mode_content_objs =
2930 _item_content_realize(it, it->item->mode_view,
2931 &it->item->mode_contents, NULL);
2932 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
2934 edje_object_part_swallow(it->item->mode_view,
2935 edje_object_data_get(it->item->mode_view, "mode_part"),
2938 it->want_unrealize = EINA_FALSE;
2939 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2940 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2944 _mode_item_unrealize(Elm_Gen_Item *it)
2946 Widget_Data *wd = it->wd;
2947 Evas_Object *content;
2948 if (!it->item->mode_view) return;
2950 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2951 elm_widget_stringlist_free(it->item->mode_texts);
2952 it->item->mode_texts = NULL;
2953 elm_widget_stringlist_free(it->item->mode_contents);
2954 it->item->mode_contents = NULL;
2955 elm_widget_stringlist_free(it->item->mode_states);
2957 EINA_LIST_FREE(it->item->mode_content_objs, content)
2958 evas_object_del(content);
2960 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
2961 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
2962 evas_object_del(it->item->mode_view);
2963 it->item->mode_view = NULL;
2965 if (wd->mode_item == it)
2966 wd->mode_item = NULL;
2967 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2968 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2972 _item_mode_set(Elm_Gen_Item *it)
2975 Widget_Data *wd = it->wd;
2980 it->item->nocache = EINA_TRUE;
2982 if (wd->scr_hold_timer)
2984 ecore_timer_del(wd->scr_hold_timer);
2985 wd->scr_hold_timer = NULL;
2987 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
2988 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
2990 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2991 _mode_item_realize(it);
2992 if (it->item->group_item)
2993 evas_object_raise(it->item->VIEW(group_item));
2994 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
2995 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2996 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2998 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
2999 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3003 _item_mode_unset(Widget_Data *wd)
3006 if (!wd->mode_item) return;
3007 char buf[1024], buf2[1024];
3011 it->item->nocache = EINA_TRUE;
3013 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
3014 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
3016 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3017 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
3019 wd->mode_item = NULL;
3023 _item_auto_scroll(Widget_Data *wd)
3026 Elm_Gen_Item *tmp_item = NULL;
3028 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3030 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3031 if (!tmp_item) return;
3032 wd->show_item = tmp_item;
3033 wd->bring_in = EINA_TRUE;
3034 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3035 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3037 wd->show_item->item->showme = EINA_TRUE;
3038 wd->auto_scroll_enabled = EINA_FALSE;
3046 elm_genlist_add(Evas_Object *parent)
3051 Evas_Coord minw, minh;
3052 static Evas_Smart *smart = NULL;
3056 static Evas_Smart_Class sc;
3058 evas_object_smart_clipped_smart_set(&_pan_sc);
3060 sc.name = "elm_genlist_pan";
3061 sc.version = EVAS_SMART_CLASS_VERSION;
3064 sc.resize = _pan_resize;
3065 sc.move = _pan_move;
3066 sc.calculate = _pan_calculate;
3067 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3070 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3072 ELM_SET_WIDTYPE(widtype, "genlist");
3074 elm_widget_type_set(obj, "genlist");
3075 elm_widget_sub_object_add(parent, obj);
3076 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3077 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3078 elm_widget_data_set(obj, wd);
3079 elm_widget_del_hook_set(obj, _del_hook);
3080 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3081 elm_widget_theme_hook_set(obj, _theme_hook);
3082 elm_widget_can_focus_set(obj, EINA_TRUE);
3083 elm_widget_event_hook_set(obj, _event_hook);
3084 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3085 elm_widget_translate_hook_set(obj, _translate_hook);
3088 wd->scr = elm_smart_scroller_add(e);
3089 elm_smart_scroller_widget_set(wd->scr, obj);
3090 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3091 elm_widget_style_get(obj));
3092 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3093 _elm_config->thumbscroll_bounce_enable);
3094 elm_widget_resize_object_set(obj, wd->scr);
3096 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3097 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3098 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3099 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3100 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3101 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3102 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3103 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3106 wd->mode = ELM_LIST_SCROLL;
3107 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3108 wd->item_cache_max = wd->max_items_per_block * 2;
3109 wd->longpress_timeout = _elm_config->longpress_timeout;
3111 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3112 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3113 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3114 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3116 wd->pan_smart = evas_object_smart_add(e, smart);
3117 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3120 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3121 _pan_set, _pan_get, _pan_max_get,
3122 _pan_min_get, _pan_child_size_get);
3124 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3126 evas_object_size_hint_min_set(obj, minw, minh);
3128 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3130 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3136 _item_select(Elm_Gen_Item *it)
3138 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3141 it->selected = EINA_TRUE;
3142 it->wd->selected = eina_list_append(it->wd->selected, it);
3144 else if (!it->wd->always_select) return;
3146 evas_object_ref(WIDGET(it));
3149 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3150 if (it->generation == it->wd->generation)
3151 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3154 evas_object_unref(WIDGET(it));
3155 if ((it->wd->clear_me) && (!it->wd->walking))
3156 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3159 if ((!it->walking) && (it->generation < it->wd->generation))
3161 if (!it->relcount) it->del_cb(it);
3164 it->wd->last_selected_item = it;
3168 static Evas_Object *
3169 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3171 return edje_object_part_swallow_get(VIEW(it), part);
3175 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3177 edje_object_part_swallow(VIEW(it), part, content);
3180 static Evas_Object *
3181 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3185 obj = edje_object_part_swallow_get(VIEW(it), part);
3186 if (!obj) return NULL;
3187 edje_object_part_unswallow(VIEW(it), obj);
3192 _item_text_hook(Elm_Gen_Item *it, const char *part)
3194 if (!it->itc->func.text_get) return NULL;
3195 return edje_object_part_text_get(VIEW(it), part);
3199 _elm_genlist_item_new(Widget_Data *wd,
3200 const Elm_Gen_Item_Class *itc,
3202 Elm_Gen_Item *parent,
3204 const void *func_data)
3208 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3209 if (!it) return NULL;
3211 it->generation = wd->generation;
3213 it->base.data = data;
3214 it->parent = parent;
3215 it->func.func = func;
3216 it->func.data = func_data;
3217 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3218 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3219 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3221 it->sel_cb = (Ecore_Cb)_item_select;
3223 elm_widget_item_text_get_hook_set(it, _item_text_hook);
3227 static Elm_Gen_Item *
3228 _item_new(Widget_Data *wd,
3229 const Elm_Genlist_Item_Class *itc,
3231 Elm_Gen_Item *parent,
3232 Elm_Genlist_Item_Flags flags,
3234 const void *func_data)
3236 Elm_Gen_Item *it, *it2;
3239 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3240 if (!it) return NULL;
3241 it->item = ELM_NEW(Elm_Gen_Item_Type);
3242 it->item->flags = flags;
3243 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3244 it->item->expanded_depth = 0;
3245 elm_widget_item_del_cb_set(it, _item_del_hook);
3246 ELM_GEN_ITEM_SETUP(it);
3249 if (it->parent->group)
3250 it->item->group_item = parent;
3251 else if (it->parent->item->group_item)
3252 it->item->group_item = it->parent->item->group_item;
3254 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3256 if (!it2->parent->group) depth += 1;
3258 it->item->expanded_depth = depth;
3263 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3267 itb = calloc(1, sizeof(Item_Block));
3268 if (!itb) return NULL;
3271 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3273 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3278 _item_block_add(Widget_Data *wd,
3281 Item_Block *itb = NULL;
3288 itb = calloc(1, sizeof(Item_Block));
3289 if (!itb) return EINA_FALSE;
3291 if (!it->item->rel->item->block)
3294 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3295 itb->items = eina_list_append(itb->items, it);
3299 if (it->item->before)
3301 wd->blocks = eina_inlist_prepend_relative
3302 (wd->blocks, EINA_INLIST_GET(itb),
3303 EINA_INLIST_GET(it->item->rel->item->block));
3305 eina_list_prepend_relative(itb->items, it, it->item->rel);
3309 wd->blocks = eina_inlist_append_relative
3310 (wd->blocks, EINA_INLIST_GET(itb),
3311 EINA_INLIST_GET(it->item->rel->item->block));
3313 eina_list_append_relative(itb->items, it, it->item->rel);
3319 if (it->item->before)
3323 itb = (Item_Block *)(wd->blocks);
3324 if (itb->count >= wd->max_items_per_block)
3326 itb = _item_block_new(wd, EINA_TRUE);
3327 if (!itb) return EINA_FALSE;
3332 itb = _item_block_new(wd, EINA_TRUE);
3333 if (!itb) return EINA_FALSE;
3335 itb->items = eina_list_prepend(itb->items, it);
3341 itb = (Item_Block *)(wd->blocks->last);
3342 if (itb->count >= wd->max_items_per_block)
3344 itb = _item_block_new(wd, EINA_FALSE);
3345 if (!itb) return EINA_FALSE;
3350 itb = _item_block_new(wd, EINA_FALSE);
3351 if (!itb) return EINA_FALSE;
3353 itb->items = eina_list_append(itb->items, it);
3359 if (it->item->rel->item->queued)
3361 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3362 on sorted insertion order, so the queue is not always ordered like the item list.
3363 This lead to issue where we depend on an item that is not yet created. As a quick
3364 work around, we reschedule the calc of the item and stop reordering the list to
3365 prevent any nasty issue to show up here.
3367 wd->queue = eina_list_append(wd->queue, it);
3368 wd->requeued = EINA_TRUE;
3369 it->item->queued = EINA_TRUE;
3372 itb = it->item->rel->item->block;
3373 if (!itb) goto newblock;
3374 if (it->item->before)
3375 itb->items = eina_list_prepend_relative(itb->items, it, it->item->rel);
3377 itb->items = eina_list_append_relative(itb->items, it, it->item->rel);
3380 itb->changed = EINA_TRUE;
3381 it->item->block = itb;
3382 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3383 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3386 it->item->rel->relcount--;
3387 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3388 _item_del(it->item->rel);
3389 it->item->rel = NULL;
3391 if (itb->count > itb->wd->max_items_per_block)
3396 Eina_Bool done = EINA_FALSE;
3398 newc = itb->count / 2;
3400 if (EINA_INLIST_GET(itb)->prev)
3402 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3404 if (itbp->count + newc < wd->max_items_per_block / 2)
3406 /* moving items to previous block */
3407 while ((itb->count > newc) && (itb->items))
3409 it2 = eina_list_data_get(itb->items);
3410 itb->items = eina_list_remove_list(itb->items, itb->items);
3413 itbp->items = eina_list_append(itbp->items, it2);
3414 it2->item->block = itbp;
3422 if (!done && EINA_INLIST_GET(itb)->next)
3424 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3426 if (itbn->count + newc < wd->max_items_per_block / 2)
3428 /* moving items to next block */
3429 while ((itb->count > newc) && (itb->items))
3433 l = eina_list_last(itb->items);
3434 it2 = eina_list_data_get(l);
3435 itb->items = eina_list_remove_list(itb->items, l);
3438 itbn->items = eina_list_prepend(itbn->items, it2);
3439 it2->item->block = itbn;
3449 /* moving items to new block */
3450 itb2 = calloc(1, sizeof(Item_Block));
3451 if (!itb2) return EINA_FALSE;
3454 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3455 EINA_INLIST_GET(itb));
3456 itb2->changed = EINA_TRUE;
3457 while ((itb->count > newc) && (itb->items))
3461 l = eina_list_last(itb->items);
3463 itb->items = eina_list_remove_list(itb->items, l);
3466 itb2->items = eina_list_prepend(itb2->items, it2);
3467 it2->item->block = itb2;
3477 _queue_process(Widget_Data *wd)
3480 Eina_Bool showme = EINA_FALSE;
3483 t0 = ecore_loop_time_get();
3484 //evas_event_freeze(evas_object_evas_get(wd->obj));
3485 for (n = 0; (wd->queue) && (n < 128); n++)
3489 it = eina_list_data_get(wd->queue);
3490 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3491 it->item->queued = EINA_FALSE;
3492 if (!_item_block_add(wd, it)) continue;
3494 _item_block_realize(it->item->block);
3495 t = ecore_time_get();
3496 if (it->item->block->changed)
3498 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3499 it->item->block->changed = 0;
3502 if (wd->calc_job) ecore_job_del(wd->calc_job);
3503 wd->calc_job = NULL;
3505 wd->pan_changed = EINA_FALSE;
3508 if (showme) it->item->block->showme = EINA_TRUE;
3509 if (eina_inlist_count(wd->blocks) > 1)
3511 if ((t - t0) > (ecore_animator_frametime_get())) break;
3514 //evas_event_thaw(evas_object_evas_get(wd->obj));
3515 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3520 _idle_process(void *data, Eina_Bool *wakeup)
3522 Widget_Data *wd = data;
3525 //static double q_start = 0.0;
3526 //if (q_start == 0.0) q_start = ecore_time_get();
3528 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
3532 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
3534 return ECORE_CALLBACK_CANCEL;
3536 return ECORE_CALLBACK_RENEW;
3540 _item_idle_enterer(void *data)
3542 Widget_Data *wd = data;
3543 Eina_Bool wakeup = EINA_FALSE;
3544 Eina_Bool ok = _idle_process(data, &wakeup);
3549 if (wd->calc_job) ecore_job_del(wd->calc_job);
3550 wd->calc_job = ecore_job_add(_calc_job, wd);
3552 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
3557 _item_queue(Widget_Data *wd,
3561 if (it->item->queued) return;
3562 it->item->queued = EINA_TRUE;
3563 if (cb && !wd->requeued)
3564 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
3566 wd->queue = eina_list_append(wd->queue, it);
3567 // FIXME: why does a freeze then thaw here cause some genlist
3568 // elm_genlist_item_append() to be much much slower?
3569 // evas_event_freeze(evas_object_evas_get(wd->obj));
3570 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
3572 if (wd->queue_idle_enterer)
3574 ecore_idle_enterer_del(wd->queue_idle_enterer);
3575 wd->queue_idle_enterer = NULL;
3579 // evas_event_thaw(evas_object_evas_get(wd->obj));
3580 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3581 if (!wd->queue_idle_enterer)
3582 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
3586 _elm_genlist_item_compare_data(const void *data, const void *data1)
3588 const Elm_Gen_Item *it = data;
3589 const Elm_Gen_Item *item1 = data1;
3591 return it->wd->item_compare_data_cb(it->base.data, item1->base.data);
3595 _elm_genlist_item_compare(const void *data, const void *data1)
3597 const Elm_Gen_Item *it, *item1;
3598 it = ELM_GEN_ITEM_FROM_INLIST(data);
3599 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
3600 return it->wd->item_compare_cb(it, item1);
3604 _elm_genlist_item_list_compare(const void *data, const void *data1)
3606 const Elm_Gen_Item *it = data;
3607 const Elm_Gen_Item *item1 = data1;
3608 return it->wd->item_compare_cb(it, item1);
3612 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
3617 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3618 _item_block_del(it);
3620 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3621 it->item->rel = after;
3622 it->item->rel->relcount++;
3623 it->item->before = EINA_FALSE;
3624 if (after->item->group_item) it->item->group_item = after->item->group_item;
3625 _item_queue(it->wd, it, NULL);
3627 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3631 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
3634 if (!before) return;
3636 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3637 _item_block_del(it);
3638 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
3639 it->item->rel = before;
3640 it->item->rel->relcount++;
3641 it->item->before = EINA_TRUE;
3642 if (before->item->group_item) it->item->group_item = before->item->group_item;
3643 _item_queue(it->wd, it, NULL);
3645 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3649 elm_genlist_item_append(Evas_Object *obj,
3650 const Elm_Genlist_Item_Class *itc,
3652 Elm_Gen_Item *parent,
3653 Elm_Genlist_Item_Flags flags,
3655 const void *func_data)
3657 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3658 Widget_Data *wd = elm_widget_data_get(obj);
3659 if (!wd) return NULL;
3660 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3662 if (!it) return NULL;
3666 wd->group_items = eina_list_append(wd->group_items, it);
3667 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
3668 it->item->rel = NULL;
3672 Elm_Gen_Item *it2 = NULL;
3673 Eina_List *ll = eina_list_last(it->parent->item->items);
3674 if (ll) it2 = ll->data;
3675 it->parent->item->items = eina_list_append(it->parent->item->items, it);
3676 if (!it2) it2 = it->parent;
3678 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3679 EINA_INLIST_GET(it2));
3680 it->item->rel = it2;
3681 it->item->rel->relcount++;
3683 it->item->before = EINA_FALSE;
3684 _item_queue(wd, it, NULL);
3689 elm_genlist_item_prepend(Evas_Object *obj,
3690 const Elm_Genlist_Item_Class *itc,
3692 Elm_Gen_Item *parent,
3693 Elm_Genlist_Item_Flags flags,
3695 const void *func_data)
3697 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3698 Widget_Data *wd = elm_widget_data_get(obj);
3699 if (!wd) return NULL;
3700 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3702 if (!it) return NULL;
3706 wd->group_items = eina_list_prepend(wd->group_items, it);
3707 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
3708 it->item->rel = NULL;
3712 Elm_Gen_Item *it2 = NULL;
3713 Eina_List *ll = it->parent->item->items;
3714 if (ll) it2 = ll->data;
3715 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
3716 if (!it2) it2 = it->parent;
3718 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3719 EINA_INLIST_GET(it2));
3720 it->item->rel = it2;
3721 it->item->rel->relcount++;
3723 it->item->before = EINA_TRUE;
3724 _item_queue(wd, it, NULL);
3729 elm_genlist_item_insert_after(Evas_Object *obj,
3730 const Elm_Genlist_Item_Class *itc,
3732 Elm_Gen_Item *parent,
3733 Elm_Gen_Item *after,
3734 Elm_Genlist_Item_Flags flags,
3736 const void *func_data)
3738 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3739 EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3740 Widget_Data *wd = elm_widget_data_get(obj);
3741 if (!wd) return NULL;
3742 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
3743 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3745 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3747 if (!it) return NULL;
3752 wd->group_items = eina_list_append_relative(wd->group_items, it,
3757 it->parent->item->items = eina_list_append_relative(it->parent->item->items, it,
3760 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3761 EINA_INLIST_GET(after));
3762 it->item->rel = after;
3763 it->item->rel->relcount++;
3764 it->item->before = EINA_FALSE;
3765 _item_queue(wd, it, NULL);
3770 elm_genlist_item_insert_before(Evas_Object *obj,
3771 const Elm_Genlist_Item_Class *itc,
3773 Elm_Gen_Item *parent,
3774 Elm_Gen_Item *before,
3775 Elm_Genlist_Item_Flags flags,
3777 const void *func_data)
3779 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3780 EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
3781 Widget_Data *wd = elm_widget_data_get(obj);
3782 if (!wd) return NULL;
3783 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
3784 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3786 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3788 if (!it) return NULL;
3791 if (it->group && before->group)
3792 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
3797 it->parent->item->items = eina_list_prepend_relative(it->parent->item->items, it,
3800 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3801 EINA_INLIST_GET(before));
3802 it->item->rel = before;
3803 it->item->rel->relcount++;
3804 it->item->before = EINA_TRUE;
3805 _item_queue(wd, it, NULL);
3810 elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
3811 const Elm_Genlist_Item_Class *itc,
3813 Elm_Gen_Item *parent,
3814 Elm_Genlist_Item_Flags flags,
3815 Eina_Compare_Cb comp,
3817 const void *func_data)
3819 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3820 Widget_Data *wd = elm_widget_data_get(obj);
3821 if (!wd) return NULL;
3822 Elm_Gen_Item *rel = NULL;
3823 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3825 if (!it) return NULL;
3827 wd->item_compare_cb = comp;
3834 l = eina_list_search_sorted_near_list(it->parent->item->items,
3835 _elm_genlist_item_list_compare, it,
3838 rel = eina_list_data_get(l);
3842 if (cmp_result >= 0)
3844 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
3845 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3846 it->item->before = EINA_FALSE;
3848 else if (cmp_result < 0)
3850 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
3851 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3852 it->item->before = EINA_TRUE;
3859 wd->state = eina_inlist_sorted_state_new();
3860 eina_inlist_sorted_state_init(wd->state, wd->items);
3861 wd->requeued = EINA_FALSE;
3865 wd->group_items = eina_list_append(wd->group_items, it);
3867 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
3868 _elm_genlist_item_compare, wd->state);
3870 if (EINA_INLIST_GET(it)->next)
3872 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3873 it->item->before = EINA_TRUE;
3875 else if (EINA_INLIST_GET(it)->prev)
3877 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3878 it->item->before = EINA_FALSE;
3884 it->item->rel = rel;
3885 it->item->rel->relcount++;
3888 _item_queue(wd, it, _elm_genlist_item_list_compare);
3894 elm_genlist_item_sorted_insert(Evas_Object *obj,
3895 const Elm_Genlist_Item_Class *itc,
3897 Elm_Gen_Item *parent,
3898 Elm_Genlist_Item_Flags flags,
3899 Eina_Compare_Cb comp,
3901 const void *func_data)
3903 Widget_Data *wd = elm_widget_data_get(obj);
3904 wd->item_compare_data_cb = comp;
3906 return elm_genlist_item_direct_sorted_insert(obj, itc, data, parent, flags,
3907 _elm_genlist_item_compare_data, func, func_data);
3911 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
3913 Eina_Inlist *next, *l;
3915 ELM_CHECK_WIDTYPE(obj, widtype);
3916 Widget_Data *wd = elm_widget_data_get(obj);
3919 if (!standby) wd->generation++;
3923 eina_inlist_sorted_state_free(wd->state);
3927 if (wd->walking > 0)
3932 evas_event_freeze(evas_object_evas_get(wd->obj));
3933 for (l = wd->items, next = l ? l->next : NULL;
3935 l = next, next = next ? next->next : NULL)
3937 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
3939 if (it->generation < wd->generation)
3941 Elm_Gen_Item *itn = NULL;
3943 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
3944 if (itn) itn->walking++; /* prevent early death of subitem */
3946 if (itn) itn->walking--;
3950 wd->pan_changed = EINA_TRUE;
3953 ecore_job_del(wd->calc_job);
3954 wd->calc_job = NULL;
3956 if (wd->selected) wd->selected = eina_list_free(wd->selected);
3957 if (wd->clear_cb) wd->clear_cb(wd);
3965 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
3966 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3968 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
3969 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
3970 evas_event_thaw(evas_object_evas_get(wd->obj));
3971 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3975 elm_genlist_clear(Evas_Object *obj)
3977 _elm_genlist_clear(obj, EINA_FALSE);
3981 elm_genlist_multi_select_set(Evas_Object *obj,
3984 ELM_CHECK_WIDTYPE(obj, widtype);
3985 Widget_Data *wd = elm_widget_data_get(obj);
3991 elm_genlist_multi_select_get(const Evas_Object *obj)
3993 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3994 Widget_Data *wd = elm_widget_data_get(obj);
3995 if (!wd) return EINA_FALSE;
4000 elm_genlist_selected_item_get(const Evas_Object *obj)
4002 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4003 Widget_Data *wd = elm_widget_data_get(obj);
4004 if (!wd) return NULL;
4005 if (wd->selected) return wd->selected->data;
4009 EAPI const Eina_List *
4010 elm_genlist_selected_items_get(const Evas_Object *obj)
4012 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4013 Widget_Data *wd = elm_widget_data_get(obj);
4014 if (!wd) return NULL;
4015 return wd->selected;
4019 elm_genlist_realized_items_get(const Evas_Object *obj)
4021 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4022 Widget_Data *wd = elm_widget_data_get(obj);
4023 Eina_List *list = NULL;
4025 Eina_Bool done = EINA_FALSE;
4026 if (!wd) return NULL;
4027 EINA_INLIST_FOREACH(wd->blocks, itb)
4035 EINA_LIST_FOREACH(itb->items, l, it)
4037 if (it->realized) list = eina_list_append(list, it);
4049 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4054 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4055 Widget_Data *wd = elm_widget_data_get(obj);
4056 Evas_Coord ox, oy, ow, oh;
4059 if (!wd) return NULL;
4060 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4062 EINA_INLIST_FOREACH(wd->blocks, itb)
4067 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4068 oy + itb->y - itb->wd->pan_y,
4069 itb->w, itb->h, x, y, 1, 1))
4071 EINA_LIST_FOREACH(itb->items, l, it)
4073 Evas_Coord itx, ity;
4075 itx = ox + itb->x + it->x - itb->wd->pan_x;
4076 ity = oy + itb->y + it->y - itb->wd->pan_y;
4077 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4081 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4082 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4088 lasty = ity + it->item->h;
4093 if (y > lasty) *posret = 1;
4100 elm_genlist_first_item_get(const Evas_Object *obj)
4102 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4103 Widget_Data *wd = elm_widget_data_get(obj);
4104 if (!wd) return NULL;
4105 if (!wd->items) return NULL;
4106 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4107 while ((it) && (it->generation < wd->generation))
4108 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4113 elm_genlist_last_item_get(const Evas_Object *obj)
4115 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4116 Widget_Data *wd = elm_widget_data_get(obj);
4117 if (!wd) return NULL;
4118 if (!wd->items) return NULL;
4119 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4120 while ((it) && (it->generation < wd->generation))
4121 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4126 elm_genlist_item_next_get(const Elm_Gen_Item *it)
4128 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4131 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4132 if ((it) && (it->generation == it->wd->generation)) break;
4134 return (Elm_Gen_Item *)it;
4138 elm_genlist_item_prev_get(const Elm_Gen_Item *it)
4140 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4143 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4144 if ((it) && (it->generation == it->wd->generation)) break;
4146 return (Elm_Gen_Item *)it;
4150 elm_genlist_item_genlist_get(const Elm_Gen_Item *it)
4152 return _elm_genlist_item_widget_get(it);
4156 elm_genlist_item_parent_get(const Elm_Gen_Item *it)
4158 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4163 elm_genlist_item_subitems_clear(Elm_Gen_Item *it)
4165 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4166 Eina_List *tl = NULL, *l;
4169 EINA_LIST_FOREACH(it->item->items, l, it2)
4170 tl = eina_list_append(tl, it2);
4171 EINA_LIST_FREE(tl, it2)
4172 elm_genlist_item_del(it2);
4176 elm_genlist_item_selected_set(Elm_Gen_Item *it,
4179 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4180 Widget_Data *wd = it->wd;
4182 if ((it->generation < wd->generation) || (it->disabled)) return;
4183 selected = !!selected;
4184 if (it->selected == selected) return;
4190 while (wd->selected)
4192 if (it->unhighlight_cb) it->unhighlight_cb(wd->selected->data);
4193 it->unsel_cb(wd->selected->data);
4196 it->highlight_cb(it);
4200 if (it->unhighlight_cb) it->unhighlight_cb(it);
4205 elm_genlist_item_selected_get(const Elm_Gen_Item *it)
4207 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4208 return it->selected;
4212 elm_genlist_item_expanded_set(Elm_Gen_Item *it,
4215 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4216 if (it->item->expanded == expanded) return;
4217 it->item->expanded = expanded;
4218 it->wd->expanded_item = it;
4219 if (it->item->expanded)
4222 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
4223 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
4224 it->wd->auto_scroll_enabled = EINA_TRUE;
4229 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
4230 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
4231 it->wd->auto_scroll_enabled = EINA_FALSE;
4236 elm_genlist_item_expanded_get(const Elm_Gen_Item *it)
4238 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4239 return it->item->expanded;
4243 elm_genlist_item_expanded_depth_get(const Elm_Gen_Item *it)
4245 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, 0);
4246 return it->item->expanded_depth;
4250 elm_genlist_item_disabled_set(Elm_Gen_Item *it,
4253 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4256 if (it->disabled == disabled) return;
4257 if (it->generation < it->wd->generation) return;
4258 it->disabled = !!disabled;
4260 elm_genlist_item_selected_set(it, EINA_FALSE);
4264 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4266 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
4267 EINA_LIST_FOREACH(it->content_objs, l, obj)
4268 elm_widget_disabled_set(obj, disabled);
4273 elm_genlist_item_disabled_get(const Elm_Gen_Item *it)
4275 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4276 if (it->generation < it->wd->generation) return EINA_FALSE;
4277 return it->disabled;
4281 elm_genlist_item_display_only_set(Elm_Gen_Item *it,
4282 Eina_Bool display_only)
4284 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4285 if (it->display_only == display_only) return;
4286 if (it->generation < it->wd->generation) return;
4287 it->display_only = display_only;
4288 it->item->mincalcd = EINA_FALSE;
4289 it->item->updateme = EINA_TRUE;
4290 if (it->item->block) it->item->block->updateme = EINA_TRUE;
4291 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4292 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4296 elm_genlist_item_display_only_get(const Elm_Gen_Item *it)
4298 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4299 if (it->generation < it->wd->generation) return EINA_FALSE;
4300 return it->display_only;
4304 elm_genlist_item_show(Elm_Gen_Item *it)
4306 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4307 Evas_Coord gith = 0;
4308 if (it->generation < it->wd->generation) return;
4309 if ((it->item->queued) || (!it->item->mincalcd))
4311 it->wd->show_item = it;
4312 it->wd->bring_in = EINA_FALSE;
4313 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
4314 it->item->showme = EINA_TRUE;
4317 if (it->wd->show_item)
4319 it->wd->show_item->item->showme = EINA_FALSE;
4320 it->wd->show_item = NULL;
4322 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4323 gith = it->item->group_item->item->h;
4324 elm_smart_scroller_child_region_show(it->wd->scr,
4325 it->x + it->item->block->x,
4326 it->y + it->item->block->y - gith,
4327 it->item->block->w, it->item->h);
4331 elm_genlist_item_promote(Elm_Gen_Item *it)
4333 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4334 if (it->generation < it->wd->generation) return;
4335 _item_move_before(it, elm_genlist_first_item_get(WIDGET(it)));
4339 elm_genlist_item_demote(Elm_Gen_Item *it)
4341 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4342 if (it->generation < it->wd->generation) return;
4343 _item_move_after(it, elm_genlist_last_item_get(WIDGET(it)));
4347 elm_genlist_item_bring_in(Elm_Gen_Item *it)
4349 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4350 Evas_Coord gith = 0;
4351 if (it->generation < it->wd->generation) return;
4352 if ((it->item->queued) || (!it->item->mincalcd))
4354 it->wd->show_item = it;
4355 it->wd->bring_in = EINA_TRUE;
4356 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
4357 it->item->showme = EINA_TRUE;
4360 if (it->wd->show_item)
4362 it->wd->show_item->item->showme = EINA_FALSE;
4363 it->wd->show_item = NULL;
4365 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4366 gith = it->item->group_item->item->h;
4367 elm_smart_scroller_region_bring_in(it->wd->scr,
4368 it->x + it->item->block->x,
4369 it->y + it->item->block->y - gith,
4370 it->item->block->w, it->item->h);
4374 elm_genlist_item_top_show(Elm_Gen_Item *it)
4376 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4378 Evas_Coord gith = 0;
4380 if (it->generation < it->wd->generation) return;
4381 if ((it->item->queued) || (!it->item->mincalcd))
4383 it->wd->show_item = it;
4384 it->wd->bring_in = EINA_FALSE;
4385 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
4386 it->item->showme = EINA_TRUE;
4389 if (it->wd->show_item)
4391 it->wd->show_item->item->showme = EINA_FALSE;
4392 it->wd->show_item = NULL;
4394 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4395 if (it->item->group_item) gith = it->item->group_item->item->h;
4396 elm_smart_scroller_child_region_show(it->wd->scr,
4397 it->x + it->item->block->x,
4398 it->y + it->item->block->y - gith,
4399 it->item->block->w, oh);
4403 elm_genlist_item_top_bring_in(Elm_Gen_Item *it)
4405 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4407 Evas_Coord gith = 0;
4409 if (it->generation < it->wd->generation) return;
4410 if ((it->item->queued) || (!it->item->mincalcd))
4412 it->wd->show_item = it;
4413 it->wd->bring_in = EINA_TRUE;
4414 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
4415 it->item->showme = EINA_TRUE;
4418 if (it->wd->show_item)
4420 it->wd->show_item->item->showme = EINA_FALSE;
4421 it->wd->show_item = NULL;
4423 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4424 if (it->item->group_item) gith = it->item->group_item->item->h;
4425 elm_smart_scroller_region_bring_in(it->wd->scr,
4426 it->x + it->item->block->x,
4427 it->y + it->item->block->y - gith,
4428 it->item->block->w, oh);
4432 elm_genlist_item_middle_show(Elm_Gen_Item *it)
4434 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4437 if (it->generation < it->wd->generation) return;
4438 if ((it->item->queued) || (!it->item->mincalcd))
4440 it->wd->show_item = it;
4441 it->wd->bring_in = EINA_FALSE;
4442 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE;
4443 it->item->showme = EINA_TRUE;
4446 if (it->wd->show_item)
4448 it->wd->show_item->item->showme = EINA_FALSE;
4449 it->wd->show_item = NULL;
4451 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4452 elm_smart_scroller_child_region_show(it->wd->scr,
4453 it->x + it->item->block->x,
4454 it->y + it->item->block->y - oh / 2 +
4455 it->item->h / 2, it->item->block->w, oh);
4459 elm_genlist_item_middle_bring_in(Elm_Gen_Item *it)
4461 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4464 if (it->generation < it->wd->generation) return;
4465 if ((it->item->queued) || (!it->item->mincalcd))
4467 it->wd->show_item = it;
4468 it->wd->bring_in = EINA_TRUE;
4469 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE;
4470 it->item->showme = EINA_TRUE;
4473 if (it->wd->show_item)
4475 it->wd->show_item->item->showme = EINA_FALSE;
4476 it->wd->show_item = NULL;
4478 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4479 elm_smart_scroller_region_bring_in(it->wd->scr,
4480 it->x + it->item->block->x,
4481 it->y + it->item->block->y - oh / 2 + it->item->h / 2,
4482 it->item->block->w, oh);
4486 elm_genlist_item_del(Elm_Gen_Item *it)
4488 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4489 if ((it->relcount > 0) || (it->walking > 0))
4491 elm_genlist_item_subitems_clear(it);
4492 if (it->wd->show_item == it) it->wd->show_item = NULL;
4493 _elm_genlist_item_del_notserious(it);
4494 if (it->item->block)
4496 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
4497 it->item->block->changed = EINA_TRUE;
4498 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
4499 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
4503 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
4512 elm_genlist_item_data_set(Elm_Gen_Item *it,
4515 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4516 elm_widget_item_data_set(it, data);
4520 elm_genlist_item_data_get(const Elm_Gen_Item *it)
4522 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4523 return elm_widget_item_data_get(it);
4527 elm_genlist_item_icons_orphan(Elm_Gen_Item *it)
4529 elm_genlist_item_contents_orphan(it);
4533 elm_genlist_item_contents_orphan(Elm_Gen_Item *it)
4535 Evas_Object *content;
4536 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4537 EINA_LIST_FREE(it->content_objs, content)
4539 elm_widget_sub_object_del(WIDGET(it), content);
4540 evas_object_smart_member_del(content);
4541 evas_object_hide(content);
4545 EAPI const Evas_Object *
4546 elm_genlist_item_object_get(const Elm_Gen_Item *it)
4548 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4553 elm_genlist_item_update(Elm_Gen_Item *it)
4555 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4556 if (!it->item->block) return;
4557 if (it->generation < it->wd->generation) return;
4558 it->item->mincalcd = EINA_FALSE;
4559 it->item->updateme = EINA_TRUE;
4560 it->item->block->updateme = EINA_TRUE;
4561 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4562 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4566 elm_genlist_item_fields_update(Elm_Genlist_Item *it,
4568 Elm_Genlist_Item_Field_Flags itf)
4570 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4571 if (!it->item->block) return;
4572 if (it->generation < it->wd->generation) return;
4574 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_LABEL))
4575 _item_text_realize(it, it->base.view, &it->texts, parts);
4576 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
4578 it->content_objs = _item_content_unrealize(it, it->base.view,
4579 &it->contents, parts);
4580 it->content_objs = _item_content_realize(it, it->base.view,
4581 &it->contents, parts);
4583 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
4584 _item_state_realize(it, it->base.view, &it->states, parts);
4588 elm_genlist_item_item_class_update(Elm_Gen_Item *it,
4589 const Elm_Genlist_Item_Class *itc)
4591 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4592 if (!it->item->block) return;
4593 EINA_SAFETY_ON_NULL_RETURN(itc);
4594 if (it->generation < it->wd->generation) return;
4596 it->item->nocache = EINA_TRUE;
4597 elm_genlist_item_update(it);
4600 EAPI const Elm_Genlist_Item_Class *
4601 elm_genlist_item_item_class_get(const Elm_Gen_Item *it)
4603 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4604 if (it->generation < it->wd->generation) return NULL;
4608 static Evas_Object *
4609 _elm_genlist_item_label_create(void *data,
4610 Evas_Object *obj __UNUSED__,
4611 Evas_Object *tooltip,
4612 void *it __UNUSED__)
4614 Evas_Object *label = elm_label_add(tooltip);
4617 elm_object_style_set(label, "tooltip");
4618 elm_object_text_set(label, data);
4623 _elm_genlist_item_label_del_cb(void *data,
4624 Evas_Object *obj __UNUSED__,
4625 void *event_info __UNUSED__)
4627 eina_stringshare_del(data);
4631 elm_genlist_item_tooltip_text_set(Elm_Gen_Item *it,
4634 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4635 text = eina_stringshare_add(text);
4636 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
4638 _elm_genlist_item_label_del_cb);
4642 elm_genlist_item_tooltip_content_cb_set(Elm_Gen_Item *it,
4643 Elm_Tooltip_Item_Content_Cb func,
4645 Evas_Smart_Cb del_cb)
4647 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, error);
4649 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4652 if (it->tooltip.del_cb)
4653 it->tooltip.del_cb((void *)it->tooltip.data,
4656 it->tooltip.content_cb = func;
4657 it->tooltip.data = data;
4658 it->tooltip.del_cb = del_cb;
4662 elm_widget_item_tooltip_content_cb_set(it,
4663 it->tooltip.content_cb,
4664 it->tooltip.data, NULL);
4665 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4666 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
4672 if (del_cb) del_cb((void *)data, NULL, NULL);
4676 elm_genlist_item_tooltip_unset(Elm_Gen_Item *it)
4678 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4679 if ((VIEW(it)) && (it->tooltip.content_cb))
4680 elm_widget_item_tooltip_unset(it);
4682 if (it->tooltip.del_cb)
4683 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4684 it->tooltip.del_cb = NULL;
4685 it->tooltip.content_cb = NULL;
4686 it->tooltip.data = NULL;
4687 it->tooltip.free_size = EINA_FALSE;
4688 if (it->tooltip.style)
4689 elm_genlist_item_tooltip_style_set(it, NULL);
4693 elm_genlist_item_tooltip_style_set(Elm_Gen_Item *it,
4696 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4697 eina_stringshare_replace(&it->tooltip.style, style);
4698 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4702 elm_genlist_item_tooltip_style_get(const Elm_Gen_Item *it)
4704 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4705 return it->tooltip.style;
4709 elm_genlist_item_tooltip_window_mode_set(Elm_Gen_Item *it, Eina_Bool disable)
4711 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4712 it->tooltip.free_size = disable;
4713 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
4718 elm_genlist_item_tooltip_window_mode_get(const Elm_Gen_Item *it)
4720 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4721 return it->tooltip.free_size;
4725 elm_genlist_item_cursor_set(Elm_Gen_Item *it,
4728 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4729 eina_stringshare_replace(&it->mouse_cursor, cursor);
4730 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4734 elm_genlist_item_cursor_get(const Elm_Gen_Item *it)
4736 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4737 return elm_widget_item_cursor_get(it);
4741 elm_genlist_item_cursor_unset(Elm_Gen_Item *it)
4743 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4744 if (!it->mouse_cursor)
4748 elm_widget_item_cursor_unset(it);
4750 eina_stringshare_del(it->mouse_cursor);
4751 it->mouse_cursor = NULL;
4755 elm_genlist_item_cursor_style_set(Elm_Gen_Item *it,
4758 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4759 elm_widget_item_cursor_style_set(it, style);
4763 elm_genlist_item_cursor_style_get(const Elm_Gen_Item *it)
4765 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4766 return elm_widget_item_cursor_style_get(it);
4770 elm_genlist_item_cursor_engine_only_set(Elm_Gen_Item *it,
4771 Eina_Bool engine_only)
4773 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4774 elm_widget_item_cursor_engine_only_set(it, engine_only);
4778 elm_genlist_item_cursor_engine_only_get(const Elm_Gen_Item *it)
4780 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4781 return elm_widget_item_cursor_engine_only_get(it);
4785 elm_genlist_horizontal_set(Evas_Object *obj,
4788 ELM_CHECK_WIDTYPE(obj, widtype);
4789 Widget_Data *wd = elm_widget_data_get(obj);
4791 if (wd->mode == mode) return;
4797 elm_genlist_horizontal_mode_set(Evas_Object *obj,
4800 elm_genlist_horizontal_set(obj, mode);
4804 elm_genlist_horizontal_get(const Evas_Object *obj)
4806 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4807 Widget_Data *wd = elm_widget_data_get(obj);
4808 if (!wd) return ELM_LIST_LAST;
4813 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4815 return elm_genlist_horizontal_get(obj);
4819 elm_genlist_always_select_mode_set(Evas_Object *obj,
4820 Eina_Bool always_select)
4822 ELM_CHECK_WIDTYPE(obj, widtype);
4823 Widget_Data *wd = elm_widget_data_get(obj);
4825 wd->always_select = always_select;
4829 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4831 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4832 Widget_Data *wd = elm_widget_data_get(obj);
4833 if (!wd) return EINA_FALSE;
4834 return wd->always_select;
4838 elm_genlist_no_select_mode_set(Evas_Object *obj,
4839 Eina_Bool no_select)
4841 ELM_CHECK_WIDTYPE(obj, widtype);
4842 Widget_Data *wd = elm_widget_data_get(obj);
4844 wd->no_select = no_select;
4848 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4850 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4851 Widget_Data *wd = elm_widget_data_get(obj);
4852 if (!wd) return EINA_FALSE;
4853 return wd->no_select;
4857 elm_genlist_compress_mode_set(Evas_Object *obj,
4860 ELM_CHECK_WIDTYPE(obj, widtype);
4861 Widget_Data *wd = elm_widget_data_get(obj);
4863 wd->compress = compress;
4864 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
4868 elm_genlist_compress_mode_get(const Evas_Object *obj)
4870 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4871 Widget_Data *wd = elm_widget_data_get(obj);
4872 if (!wd) return EINA_FALSE;
4873 return wd->compress;
4877 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
4878 Eina_Bool height_for_width)
4880 ELM_CHECK_WIDTYPE(obj, widtype);
4881 Widget_Data *wd = elm_widget_data_get(obj);
4883 wd->height_for_width = !!height_for_width;
4884 if (wd->height_for_width)
4886 elm_genlist_homogeneous_set(obj, EINA_FALSE);
4887 elm_genlist_compress_mode_set(obj, EINA_TRUE);
4892 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
4894 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4895 Widget_Data *wd = elm_widget_data_get(obj);
4896 if (!wd) return EINA_FALSE;
4897 return wd->height_for_width;
4901 elm_genlist_bounce_set(Evas_Object *obj,
4905 ELM_CHECK_WIDTYPE(obj, widtype);
4906 Widget_Data *wd = elm_widget_data_get(obj);
4908 elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
4909 wd->h_bounce = h_bounce;
4910 wd->v_bounce = v_bounce;
4914 elm_genlist_bounce_get(const Evas_Object *obj,
4915 Eina_Bool *h_bounce,
4916 Eina_Bool *v_bounce)
4918 ELM_CHECK_WIDTYPE(obj, widtype);
4919 Widget_Data *wd = elm_widget_data_get(obj);
4921 if (h_bounce) *h_bounce = wd->h_bounce;
4922 if (v_bounce) *v_bounce = wd->v_bounce;
4926 elm_genlist_homogeneous_set(Evas_Object *obj,
4927 Eina_Bool homogeneous)
4929 ELM_CHECK_WIDTYPE(obj, widtype);
4930 Widget_Data *wd = elm_widget_data_get(obj);
4932 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
4933 wd->homogeneous = homogeneous;
4937 elm_genlist_homogeneous_get(const Evas_Object *obj)
4939 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4940 Widget_Data *wd = elm_widget_data_get(obj);
4941 if (!wd) return EINA_FALSE;
4942 return wd->homogeneous;
4946 elm_genlist_block_count_set(Evas_Object *obj,
4949 ELM_CHECK_WIDTYPE(obj, widtype);
4950 Widget_Data *wd = elm_widget_data_get(obj);
4952 wd->max_items_per_block = n;
4953 wd->item_cache_max = wd->max_items_per_block * 2;
4954 _item_cache_clean(wd);
4958 elm_genlist_block_count_get(const Evas_Object *obj)
4960 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4961 Widget_Data *wd = elm_widget_data_get(obj);
4963 return wd->max_items_per_block;
4967 elm_genlist_longpress_timeout_set(Evas_Object *obj,
4970 ELM_CHECK_WIDTYPE(obj, widtype);
4971 Widget_Data *wd = elm_widget_data_get(obj);
4973 wd->longpress_timeout = timeout;
4977 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
4979 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4980 Widget_Data *wd = elm_widget_data_get(obj);
4982 return wd->longpress_timeout;
4986 elm_genlist_scroller_policy_set(Evas_Object *obj,
4987 Elm_Scroller_Policy policy_h,
4988 Elm_Scroller_Policy policy_v)
4990 ELM_CHECK_WIDTYPE(obj, widtype);
4991 Widget_Data *wd = elm_widget_data_get(obj);
4992 if ((!wd) || (!wd->scr)) return;
4993 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4994 (policy_v >= ELM_SCROLLER_POLICY_LAST))
4996 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5000 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5001 Elm_Scroller_Policy *policy_h,
5002 Elm_Scroller_Policy *policy_v)
5004 ELM_CHECK_WIDTYPE(obj, widtype);
5005 Widget_Data *wd = elm_widget_data_get(obj);
5006 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5007 if ((!wd) || (!wd->scr)) return;
5008 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5009 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5010 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5014 elm_genlist_realized_items_update(Evas_Object *obj)
5016 ELM_CHECK_WIDTYPE(obj, widtype);
5018 Eina_List *list, *l;
5021 list = elm_genlist_realized_items_get(obj);
5022 EINA_LIST_FOREACH(list, l, it)
5023 elm_genlist_item_update(it);
5027 elm_genlist_item_mode_set(Elm_Gen_Item *it,
5028 const char *mode_type,
5031 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
5032 Widget_Data *wd = it->wd;
5037 if (!mode_type) return;
5038 if ((it->generation < it->wd->generation) || (it->disabled)) return;
5040 if ((wd->mode_item == it) &&
5041 (!strcmp(mode_type, wd->mode_type)) &&
5044 if (!wd->mode_item_style) return;
5045 it->mode_set = mode_set;
5049 EINA_LIST_FOREACH(wd->selected, l, it2)
5051 elm_genlist_item_selected_set(it2, EINA_FALSE);
5055 it2 = elm_genlist_selected_item_get(wd->obj);
5056 if ((it2) && (it2->realized))
5057 elm_genlist_item_selected_set(it2, EINA_FALSE);
5060 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
5062 ((it == wd->mode_item) && (!mode_set)))
5063 _item_mode_unset(wd);
5065 eina_stringshare_replace(&wd->mode_type, mode_type);
5066 if (mode_set) _item_mode_set(it);
5071 elm_genlist_mode_item_style_get(const Evas_Object *obj)
5073 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5074 Widget_Data *wd = elm_widget_data_get(obj);
5075 if (!wd) return NULL;
5076 return wd->mode_item_style;
5080 elm_genlist_mode_item_style_set(Evas_Object *obj, const char *style)
5082 ELM_CHECK_WIDTYPE(obj, widtype);
5083 Widget_Data *wd = elm_widget_data_get(obj);
5085 if ((style == wd->mode_item_style) || (style && wd->mode_item_style &&
5086 (!strcmp(style, wd->mode_item_style))))
5088 eina_stringshare_replace(&wd->mode_item_style, style);
5089 elm_genlist_realized_items_update(obj);
5093 elm_genlist_mode_get(const Evas_Object *obj)
5095 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5096 Widget_Data *wd = elm_widget_data_get(obj);
5097 if (!wd) return NULL;
5098 return wd->mode_type;
5101 EAPI const Elm_Gen_Item *
5102 elm_genlist_mode_item_get(const Evas_Object *obj)
5104 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5105 Widget_Data *wd = elm_widget_data_get(obj);
5106 if (!wd) return NULL;
5107 return wd->mode_item;
5111 elm_genlist_reorder_mode_set(Evas_Object *obj,
5112 Eina_Bool reorder_mode)
5114 ELM_CHECK_WIDTYPE(obj, widtype);
5115 Widget_Data *wd = elm_widget_data_get(obj);
5117 wd->reorder_mode = reorder_mode;
5121 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5123 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5124 Widget_Data *wd = elm_widget_data_get(obj);
5125 if (!wd) return EINA_FALSE;
5126 return wd->reorder_mode;
5129 /* for gengrid as of now */
5131 _elm_genlist_page_relative_set(Evas_Object *obj,
5135 Evas_Coord pagesize_h;
5136 Evas_Coord pagesize_v;
5138 ELM_CHECK_WIDTYPE(obj, widtype);
5139 Widget_Data *wd = elm_widget_data_get(obj);
5142 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5143 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5147 /* for gengrid as of now */
5149 _elm_genlist_page_relative_get(const Evas_Object *obj,
5153 ELM_CHECK_WIDTYPE(obj, widtype);
5154 Widget_Data *wd = elm_widget_data_get(obj);
5157 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5160 /* for gengrid as of now */
5162 _elm_genlist_page_size_set(Evas_Object *obj,
5163 Evas_Coord h_pagesize,
5164 Evas_Coord v_pagesize)
5169 ELM_CHECK_WIDTYPE(obj, widtype);
5170 Widget_Data *wd = elm_widget_data_get(obj);
5172 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5173 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5177 /* for gengrid as of now */
5179 _elm_genlist_current_page_get(const Evas_Object *obj,
5183 ELM_CHECK_WIDTYPE(obj, widtype);
5184 Widget_Data *wd = elm_widget_data_get(obj);
5187 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5190 /* for gengrid as of now */
5192 _elm_genlist_last_page_get(const Evas_Object *obj,
5196 ELM_CHECK_WIDTYPE(obj, widtype);
5197 Widget_Data *wd = elm_widget_data_get(obj);
5200 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5203 /* for gengrid as of now */
5205 _elm_genlist_page_show(const Evas_Object *obj,
5209 ELM_CHECK_WIDTYPE(obj, widtype);
5210 Widget_Data *wd = elm_widget_data_get(obj);
5213 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5216 /* for gengrid as of now */
5218 _elm_genlist_page_bring_in(const Evas_Object *obj,
5222 ELM_CHECK_WIDTYPE(obj, widtype);
5223 Widget_Data *wd = elm_widget_data_get(obj);
5226 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5230 _elm_genlist_item_widget_get(const Elm_Gen_Item *it)
5232 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
5237 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5240 Evas_Object *content;
5242 if (!it->realized) return;
5243 if (it->wd->reorder_it == it) return;
5244 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5246 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5249 ecore_timer_del(it->long_timer);
5250 it->long_timer = NULL;
5253 elm_widget_stringlist_free(it->texts);
5255 elm_widget_stringlist_free(it->contents);
5256 it->contents = NULL;
5257 elm_widget_stringlist_free(it->states);
5260 EINA_LIST_FREE(it->content_objs, content)
5261 evas_object_del(content);
5263 it->unrealize_cb(it);
5265 it->realized = EINA_FALSE;
5266 it->want_unrealize = EINA_FALSE;
5267 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5268 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5272 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5274 elm_widget_item_pre_notify_del(it);
5275 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5276 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5278 if (it->itc->func.del)
5279 it->itc->func.del((void *)it->base.data, WIDGET(it));
5283 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5285 _elm_genlist_item_del_notserious(it);
5286 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5287 if (it->tooltip.del_cb)
5288 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5289 it->wd->walking -= it->walking;
5290 if (it->long_timer) ecore_timer_del(it->long_timer);
5292 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5294 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5295 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5298 elm_widget_item_del(it);