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, Eina_Bool standby);
138 static void _pan_child_size_get(Evas_Object *obj,
142 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
144 static const char SIG_ACTIVATED[] = "activated";
145 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
146 static const char SIG_SELECTED[] = "selected";
147 static const char SIG_UNSELECTED[] = "unselected";
148 static const char SIG_EXPANDED[] = "expanded";
149 static const char SIG_CONTRACTED[] = "contracted";
150 static const char SIG_EXPAND_REQUEST[] = "expand,request";
151 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
152 static const char SIG_REALIZED[] = "realized";
153 static const char SIG_UNREALIZED[] = "unrealized";
154 static const char SIG_DRAG_START_UP[] = "drag,start,up";
155 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
156 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
157 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
158 static const char SIG_DRAG_STOP[] = "drag,stop";
159 static const char SIG_DRAG[] = "drag";
160 static const char SIG_LONGPRESSED[] = "longpressed";
161 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
162 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
163 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
164 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
165 static const char SIG_EDGE_TOP[] = "edge,top";
166 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
167 static const char SIG_EDGE_LEFT[] = "edge,left";
168 static const char SIG_EDGE_RIGHT[] = "edge,right";
169 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
170 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
171 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
172 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
173 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
174 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
175 static const char SIG_SWIPE[] = "swipe";
176 static const char SIG_MOVED[] = "moved";
178 static const Evas_Smart_Cb_Description _signals[] = {
179 {SIG_CLICKED_DOUBLE, ""},
182 {SIG_UNSELECTED, ""},
184 {SIG_CONTRACTED, ""},
185 {SIG_EXPAND_REQUEST, ""},
186 {SIG_CONTRACT_REQUEST, ""},
188 {SIG_UNREALIZED, ""},
189 {SIG_DRAG_START_UP, ""},
190 {SIG_DRAG_START_DOWN, ""},
191 {SIG_DRAG_START_LEFT, ""},
192 {SIG_DRAG_START_RIGHT, ""},
195 {SIG_LONGPRESSED, ""},
196 {SIG_SCROLL_ANIM_START, ""},
197 {SIG_SCROLL_ANIM_STOP, ""},
198 {SIG_SCROLL_DRAG_START, ""},
199 {SIG_SCROLL_DRAG_STOP, ""},
201 {SIG_EDGE_BOTTOM, ""},
203 {SIG_EDGE_RIGHT, ""},
204 {SIG_MULTI_SWIPE_LEFT, ""},
205 {SIG_MULTI_SWIPE_RIGHT, ""},
206 {SIG_MULTI_SWIPE_UP, ""},
207 {SIG_MULTI_SWIPE_DOWN, ""},
208 {SIG_MULTI_PINCH_OUT, ""},
209 {SIG_MULTI_PINCH_IN, ""},
216 #undef ELM_CHECK_WIDTYPE
217 #define ELM_CHECK_WIDTYPE(obj, widtype) \
218 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
219 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
220 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
221 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
222 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
224 static const char *_gengrid = NULL;
225 static const char *_genlist = NULL;
227 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
229 elm_genlist_type_check(const Evas_Object *obj,
232 const char *provided, *expected = "(unknown)";
233 static int abort_on_warn = -1;
234 provided = elm_widget_type_get(obj);
235 if (!_genlist) _genlist = eina_stringshare_add("genlist");
236 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
237 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
239 if ((!provided) || (!provided[0]))
241 provided = evas_object_type_get(obj);
242 if ((!provided) || (!provided[0]))
243 provided = "(unknown)";
245 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
246 if (abort_on_warn == -1)
248 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
249 else abort_on_warn = 0;
251 if (abort_on_warn == 1) abort();
256 _event_hook(Evas_Object *obj,
257 Evas_Object *src __UNUSED__,
258 Evas_Callback_Type type,
261 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
262 Evas_Event_Key_Down *ev = event_info;
263 Widget_Data *wd = elm_widget_data_get(obj);
264 Evas_Coord pan_max_x = 0, pan_max_y = 0;
265 if (!wd) return EINA_FALSE;
266 if (!wd->items) return EINA_FALSE;
267 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
268 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
270 Elm_Gen_Item *it = NULL;
273 Evas_Coord step_x = 0;
274 Evas_Coord step_y = 0;
277 Evas_Coord page_x = 0;
278 Evas_Coord page_y = 0;
280 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
281 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
282 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
283 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
285 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
289 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
293 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
295 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
296 (_item_multi_select_up(wd)))
297 || (_item_single_select_up(wd)))
299 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
305 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
307 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
308 (_item_multi_select_down(wd)))
309 || (_item_single_select_down(wd)))
311 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
317 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
319 it = elm_genlist_first_item_get(obj);
320 elm_genlist_item_bring_in(it);
321 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
324 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
326 it = elm_genlist_last_item_get(obj);
327 elm_genlist_item_bring_in(it);
328 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
331 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
334 y -= -(page_y * v_h) / 100;
338 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
341 y += -(page_y * v_h) / 100;
345 else if (!strcmp(ev->keyname, "Escape"))
347 if (!_deselect_all_items(wd)) return EINA_FALSE;
348 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
351 else if (((!strcmp(ev->keyname, "Return")) ||
352 (!strcmp(ev->keyname, "KP_Enter")) ||
353 (!strcmp(ev->keyname, "space")))
354 && (!wd->multi) && (wd->selected))
356 it = elm_genlist_selected_item_get(obj);
357 elm_genlist_item_expanded_set(it,
358 !elm_genlist_item_expanded_get(it));
359 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
361 else return EINA_FALSE;
363 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
364 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
366 if (x > pan_max_x) x = pan_max_x;
368 if (y > pan_max_y) y = pan_max_y;
369 elm_smart_scroller_child_pos_set(wd->scr, x, y);
374 _deselect_all_items(Widget_Data *wd)
376 if (!wd->selected) return EINA_FALSE;
378 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
384 _item_multi_select_up(Widget_Data *wd)
386 if (!wd->selected) return EINA_FALSE;
387 if (!wd->multi) return EINA_FALSE;
389 Elm_Gen_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
390 if (!prev) return EINA_TRUE;
392 if (elm_genlist_item_selected_get(prev))
394 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
395 wd->last_selected_item = prev;
396 elm_genlist_item_show(wd->last_selected_item);
400 elm_genlist_item_selected_set(prev, EINA_TRUE);
401 elm_genlist_item_show(prev);
407 _item_multi_select_down(Widget_Data *wd)
409 if (!wd->selected) return EINA_FALSE;
410 if (!wd->multi) return EINA_FALSE;
412 Elm_Gen_Item *next = elm_genlist_item_next_get(wd->last_selected_item);
413 if (!next) return EINA_TRUE;
415 if (elm_genlist_item_selected_get(next))
417 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
418 wd->last_selected_item = next;
419 elm_genlist_item_show(wd->last_selected_item);
423 elm_genlist_item_selected_set(next, EINA_TRUE);
424 elm_genlist_item_show(next);
430 _item_single_select_up(Widget_Data *wd)
435 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
436 while ((prev) && (prev->generation < wd->generation))
437 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
439 else prev = elm_genlist_item_prev_get(wd->last_selected_item);
441 if (!prev) return EINA_FALSE;
443 _deselect_all_items(wd);
445 elm_genlist_item_selected_set(prev, EINA_TRUE);
446 elm_genlist_item_show(prev);
451 _item_single_select_down(Widget_Data *wd)
456 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
457 while ((next) && (next->generation < wd->generation))
458 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
460 else next = elm_genlist_item_next_get(wd->last_selected_item);
462 if (!next) return EINA_FALSE;
464 _deselect_all_items(wd);
466 elm_genlist_item_selected_set(next, EINA_TRUE);
467 elm_genlist_item_show(next);
472 _on_focus_hook(void *data __UNUSED__,
475 Widget_Data *wd = elm_widget_data_get(obj);
477 if (elm_widget_focus_get(obj))
479 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
480 evas_object_focus_set(wd->obj, EINA_TRUE);
481 if ((wd->selected) && (!wd->last_selected_item))
482 wd->last_selected_item = eina_list_data_get(wd->selected);
486 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
487 evas_object_focus_set(wd->obj, EINA_FALSE);
492 _del_hook(Evas_Object *obj)
494 Widget_Data *wd = elm_widget_data_get(obj);
496 _item_cache_zero(wd);
497 if (wd->calc_job) ecore_job_del(wd->calc_job);
498 if (wd->update_job) ecore_job_del(wd->update_job);
499 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
500 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
501 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
502 if (wd->mode_type) eina_stringshare_del(wd->mode_type);
503 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
508 _del_pre_hook(Evas_Object *obj)
510 Widget_Data *wd = elm_widget_data_get(obj);
512 elm_genlist_clear(obj);
513 evas_object_del(wd->pan_smart);
514 wd->pan_smart = NULL;
518 _mirrored_set(Evas_Object *obj,
521 Widget_Data *wd = elm_widget_data_get(obj);
523 _item_cache_zero(wd);
524 elm_smart_scroller_mirrored_set(wd->scr, rtl);
528 _theme_hook(Evas_Object *obj)
530 Widget_Data *wd = elm_widget_data_get(obj);
533 evas_event_freeze(evas_object_evas_get(wd->obj));
534 _item_cache_zero(wd);
535 _elm_widget_mirrored_reload(obj);
536 _mirrored_set(obj, elm_widget_mirrored_get(obj));
537 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
538 elm_widget_style_get(obj));
539 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
540 wd->item_width = wd->item_height = 0;
541 wd->group_item_width = wd->group_item_height = 0;
542 wd->minw = wd->minh = wd->realminw = 0;
543 EINA_INLIST_FOREACH(wd->blocks, itb)
548 if (itb->realized) _item_block_unrealize(itb);
549 EINA_LIST_FOREACH(itb->items, l, it)
550 it->item->mincalcd = EINA_FALSE;
552 itb->changed = EINA_TRUE;
554 if (wd->calc_job) ecore_job_del(wd->calc_job);
555 wd->calc_job = ecore_job_add(_calc_job, wd);
557 evas_event_thaw(evas_object_evas_get(wd->obj));
558 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
562 _show_region_hook(void *data,
565 Widget_Data *wd = elm_widget_data_get(data);
566 Evas_Coord x, y, w, h;
568 elm_widget_show_region_get(obj, &x, &y, &w, &h);
569 //x & y are screen coordinates, Add with pan coordinates
572 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
576 _translate_hook(Evas_Object *obj)
578 evas_object_smart_callback_call(obj, "language,changed", NULL);
582 _sizing_eval(Evas_Object *obj)
584 Widget_Data *wd = elm_widget_data_get(obj);
585 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
587 evas_object_size_hint_min_get(wd->scr, &minw, &minh);
588 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
590 if (wd->height_for_width)
594 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
595 if ((vw != 0) && (vw != wd->prev_viewport_w))
599 wd->prev_viewport_w = vw;
600 EINA_INLIST_FOREACH(wd->blocks, itb)
602 itb->must_recalc = EINA_TRUE;
604 if (wd->calc_job) ecore_job_del(wd->calc_job);
605 wd->calc_job = ecore_job_add(_calc_job, wd);
608 if (wd->mode == ELM_LIST_LIMIT)
614 edje_object_size_min_calc
615 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
622 edje_object_size_min_calc
623 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
627 evas_object_size_hint_min_set(obj, minw, minh);
628 evas_object_size_hint_max_set(obj, maxw, maxh);
632 _signal_emit_hook(Evas_Object *obj,
633 const char *emission,
636 Widget_Data *wd = elm_widget_data_get(obj);
637 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
642 _item_highlight(Elm_Gen_Item *it)
644 const char *selectraise;
645 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->highlighted) ||
646 (it->disabled) || (it->display_only) || (it->item->mode_view))
648 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
649 selectraise = edje_object_data_get(VIEW(it), "selectraise");
650 if ((selectraise) && (!strcmp(selectraise, "on")))
652 evas_object_raise(VIEW(it));
653 if ((it->item->group_item) && (it->item->group_item->realized))
654 evas_object_raise(it->item->VIEW(group_item));
656 it->highlighted = EINA_TRUE;
660 _item_unhighlight(Elm_Gen_Item *it)
662 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
663 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
664 if (!it->item->nostacking)
666 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even) evas_object_lower(VIEW(it));
667 else evas_object_raise(VIEW(it));
669 it->highlighted = EINA_FALSE;
673 _item_block_del(Elm_Gen_Item *it)
676 Item_Block *itb = it->item->block;
678 itb->items = eina_list_remove(itb->items, it);
680 itb->changed = EINA_TRUE;
681 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
682 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
685 il = EINA_INLIST_GET(itb);
686 Item_Block *itbn = (Item_Block *)(il->next);
688 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
690 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
692 if (itbn) itbn->changed = EINA_TRUE;
696 if (itb->count < itb->wd->max_items_per_block/2)
698 il = EINA_INLIST_GET(itb);
699 Item_Block *itbp = (Item_Block *)(il->prev);
700 Item_Block *itbn = (Item_Block *)(il->next);
701 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
705 EINA_LIST_FREE(itb->items, it2)
707 it2->item->block = itbp;
708 itbp->items = eina_list_append(itbp->items, it2);
710 itbp->changed = EINA_TRUE;
712 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
713 EINA_INLIST_GET(itb));
716 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
720 Eina_List *last = eina_list_last(itb->items);
721 Elm_Gen_Item *it2 = last->data;
723 it2->item->block = itbn;
724 itb->items = eina_list_remove_list(itb->items, last);
725 itbn->items = eina_list_prepend(itbn->items, it2);
727 itbn->changed = EINA_TRUE;
730 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
738 _item_del(Elm_Gen_Item *it)
740 Evas_Object *obj = WIDGET(it);
742 evas_event_freeze(evas_object_evas_get(obj));
743 elm_genlist_item_subitems_clear(it);
744 if (it->wd->show_item == it) it->wd->show_item = NULL;
745 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
746 if (it->item->block) _item_block_del(it);
747 if (it->item->queued)
748 it->wd->queue = eina_list_remove(it->wd->queue, it);
749 if (it->wd->anchor_item == it)
751 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
752 if (!it->wd->anchor_item)
753 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
756 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
757 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
758 _elm_genlist_item_del_serious(it);
759 evas_event_thaw(evas_object_evas_get(obj));
760 evas_event_thaw_eval(evas_object_evas_get(obj));
764 _clear_cb(Widget_Data *wd)
766 wd->anchor_item = NULL;
769 Item_Block *itb = (Item_Block *)(wd->blocks);
771 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
772 if (itb->items) eina_list_free(itb->items);
775 if (wd->queue_idle_enterer)
777 ecore_idle_enterer_del(wd->queue_idle_enterer);
778 wd->queue_idle_enterer = NULL;
780 if (wd->must_recalc_idler)
782 ecore_idler_del(wd->must_recalc_idler);
783 wd->must_recalc_idler = NULL;
785 if (wd->queue) wd->queue = eina_list_free(wd->queue);
786 if (wd->reorder_move_animator)
788 ecore_animator_del(wd->reorder_move_animator);
789 wd->reorder_move_animator = NULL;
791 wd->show_item = NULL;
792 wd->reorder_old_pan_y = 0;
796 _item_unselect(Elm_Gen_Item *it)
798 if ((it->generation < it->wd->generation) || (!it->selected)) return;
799 it->selected = EINA_FALSE;
800 it->wd->selected = eina_list_remove(it->wd->selected, it);
801 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
805 _mouse_move(void *data,
806 Evas *evas __UNUSED__,
810 Elm_Gen_Item *it = data;
811 Evas_Event_Mouse_Move *ev = event_info;
812 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
813 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
815 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
817 if (!it->wd->on_hold)
819 it->wd->on_hold = EINA_TRUE;
820 if (!it->wd->wasselected)
822 _item_unhighlight(it);
827 if (it->wd->multitouched)
829 it->wd->cur_x = ev->cur.canvas.x;
830 it->wd->cur_y = ev->cur.canvas.y;
833 if ((it->dragging) && (it->down))
835 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
838 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
839 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
840 if (abs((it->wd->history[it->wd->movements].x -
841 it->wd->history[0].x)) > 40)
842 it->wd->swipe = EINA_TRUE;
848 ecore_timer_del(it->long_timer);
849 it->long_timer = NULL;
851 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
854 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
858 ecore_timer_del(it->long_timer);
859 it->long_timer = NULL;
861 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
863 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
864 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
866 if (!it->wd->reorder_start_y)
867 it->wd->reorder_start_y = it->item->block->y + it->y;
871 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
872 y_pos = oy + oh - it->wd->reorder_it->item->h;
876 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
878 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
879 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
883 if (!it->display_only)
884 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
885 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
886 x = ev->cur.canvas.x - x;
887 y = ev->cur.canvas.y - y;
890 if (adx < 0) adx = -dx;
893 if (ady < 0) ady = -dy;
896 if ((adx > minw) || (ady > minh))
898 it->dragging = EINA_TRUE;
901 ecore_timer_del(it->long_timer);
902 it->long_timer = NULL;
904 if (!it->wd->wasselected)
906 _item_unhighlight(it);
912 evas_object_smart_callback_call(WIDGET(it),
913 SIG_DRAG_START_UP, it);
917 evas_object_smart_callback_call(WIDGET(it),
918 SIG_DRAG_START_LEFT, it);
920 evas_object_smart_callback_call(WIDGET(it),
921 SIG_DRAG_START_RIGHT, it);
927 evas_object_smart_callback_call(WIDGET(it),
928 SIG_DRAG_START_DOWN, it);
932 evas_object_smart_callback_call(WIDGET(it),
933 SIG_DRAG_START_LEFT, it);
935 evas_object_smart_callback_call(WIDGET(it),
936 SIG_DRAG_START_RIGHT, it);
943 _long_press(void *data)
945 Elm_Gen_Item *it = data, *it_tmp;
948 it->long_timer = NULL;
949 if ((it->disabled) || (it->dragging) || (it->display_only))
950 return ECORE_CALLBACK_CANCEL;
951 it->wd->longpressed = EINA_TRUE;
952 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
953 if ((it->wd->reorder_mode) && (!it->group))
955 it->wd->reorder_it = it;
956 it->wd->reorder_start_y = 0;
958 evas_object_raise(VIEW(it));
959 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
960 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
962 list = elm_genlist_realized_items_get(it->wd->obj);
963 EINA_LIST_FOREACH(list, l, it_tmp)
965 if (it != it_tmp) _item_unselect(it_tmp);
967 if (elm_genlist_item_expanded_get(it))
969 elm_genlist_item_expanded_set(it, EINA_FALSE);
970 return ECORE_CALLBACK_RENEW;
972 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
974 return ECORE_CALLBACK_CANCEL;
978 _swipe(Elm_Gen_Item *it)
983 if ((it->display_only) || (it->disabled)) return;
984 it->wd->swipe = EINA_FALSE;
985 for (i = 0; i < it->wd->movements; i++)
987 sum += it->wd->history[i].x;
988 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
991 sum /= it->wd->movements;
992 if (abs(sum - it->wd->history[0].x) <= 10) return;
993 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
997 _swipe_cancel(void *data)
999 Elm_Gen_Item *it = data;
1001 if (!it) return ECORE_CALLBACK_CANCEL;
1002 it->wd->swipe = EINA_FALSE;
1003 it->wd->movements = 0;
1004 return ECORE_CALLBACK_RENEW;
1008 _multi_cancel(void *data)
1010 Widget_Data *wd = data;
1012 if (!wd) return ECORE_CALLBACK_CANCEL;
1013 wd->multi_timeout = EINA_TRUE;
1014 return ECORE_CALLBACK_RENEW;
1018 _multi_touch_gesture_eval(void *data)
1020 Elm_Gen_Item *it = data;
1022 it->wd->multitouched = EINA_FALSE;
1023 if (it->wd->multi_timer)
1025 ecore_timer_del(it->wd->multi_timer);
1026 it->wd->multi_timer = NULL;
1028 if (it->wd->multi_timeout)
1030 it->wd->multi_timeout = EINA_FALSE;
1034 Evas_Coord minw = 0, minh = 0;
1035 Evas_Coord off_x, off_y, off_mx, off_my;
1037 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1038 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1039 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1040 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1041 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1043 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1045 if ((off_x + off_mx) > (off_y + off_my))
1047 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1048 evas_object_smart_callback_call(WIDGET(it),
1049 SIG_MULTI_SWIPE_RIGHT, it);
1050 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1051 evas_object_smart_callback_call(WIDGET(it),
1052 SIG_MULTI_SWIPE_LEFT, it);
1053 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1054 evas_object_smart_callback_call(WIDGET(it),
1055 SIG_MULTI_PINCH_OUT, it);
1057 evas_object_smart_callback_call(WIDGET(it),
1058 SIG_MULTI_PINCH_IN, it);
1062 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1063 evas_object_smart_callback_call(WIDGET(it),
1064 SIG_MULTI_SWIPE_DOWN, it);
1065 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1066 evas_object_smart_callback_call(WIDGET(it),
1067 SIG_MULTI_SWIPE_UP, it);
1068 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1069 evas_object_smart_callback_call(WIDGET(it),
1070 SIG_MULTI_PINCH_OUT, it);
1072 evas_object_smart_callback_call(WIDGET(it),
1073 SIG_MULTI_PINCH_IN, it);
1076 it->wd->multi_timeout = EINA_FALSE;
1080 _multi_down(void *data,
1081 Evas *evas __UNUSED__,
1082 Evas_Object *obj __UNUSED__,
1085 Elm_Gen_Item *it = data;
1086 Evas_Event_Multi_Down *ev = event_info;
1088 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1089 it->wd->multi_device = ev->device;
1090 it->wd->multi_down = EINA_TRUE;
1091 it->wd->multitouched = EINA_TRUE;
1092 it->wd->prev_mx = ev->canvas.x;
1093 it->wd->prev_my = ev->canvas.y;
1094 if (!it->wd->wasselected)
1096 _item_unhighlight(it);
1099 it->wd->wasselected = EINA_FALSE;
1100 it->wd->longpressed = EINA_FALSE;
1103 ecore_timer_del(it->long_timer);
1104 it->long_timer = NULL;
1108 it->dragging = EINA_FALSE;
1109 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1111 if (it->item->swipe_timer)
1113 ecore_timer_del(it->item->swipe_timer);
1114 it->item->swipe_timer = NULL;
1116 if (it->wd->on_hold)
1118 it->wd->swipe = EINA_FALSE;
1119 it->wd->movements = 0;
1120 it->wd->on_hold = EINA_FALSE;
1125 _multi_up(void *data,
1126 Evas *evas __UNUSED__,
1127 Evas_Object *obj __UNUSED__,
1130 Elm_Gen_Item *it = data;
1131 Evas_Event_Multi_Up *ev = event_info;
1133 if (it->wd->multi_device != ev->device) return;
1134 it->wd->multi_device = 0;
1135 it->wd->multi_down = EINA_FALSE;
1136 if (it->wd->mouse_down) return;
1137 _multi_touch_gesture_eval(data);
1141 _multi_move(void *data,
1142 Evas *evas __UNUSED__,
1143 Evas_Object *obj __UNUSED__,
1146 Elm_Gen_Item *it = data;
1147 Evas_Event_Multi_Move *ev = event_info;
1149 if (it->wd->multi_device != ev->device) return;
1150 it->wd->cur_mx = ev->cur.canvas.x;
1151 it->wd->cur_my = ev->cur.canvas.y;
1155 _mouse_down(void *data,
1156 Evas *evas __UNUSED__,
1160 Elm_Gen_Item *it = data;
1161 Evas_Event_Mouse_Down *ev = event_info;
1164 if (ev->button != 1) return;
1165 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1167 it->wd->on_hold = EINA_TRUE;
1170 it->down = EINA_TRUE;
1171 it->dragging = EINA_FALSE;
1172 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1173 it->dx = ev->canvas.x - x;
1174 it->dy = ev->canvas.y - y;
1175 it->wd->mouse_down = EINA_TRUE;
1176 if (!it->wd->multitouched)
1178 it->wd->prev_x = ev->canvas.x;
1179 it->wd->prev_y = ev->canvas.y;
1180 it->wd->multi_timeout = EINA_FALSE;
1181 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1182 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1184 it->wd->longpressed = EINA_FALSE;
1185 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1186 else it->wd->on_hold = EINA_FALSE;
1187 if (it->wd->on_hold) return;
1188 it->wd->wasselected = it->selected;
1189 _item_highlight(it);
1190 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1191 if ((!it->disabled) && (!it->display_only))
1193 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1194 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1196 if (it->long_timer) ecore_timer_del(it->long_timer);
1197 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1198 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1200 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1203 it->long_timer = NULL;
1204 it->wd->swipe = EINA_FALSE;
1205 it->wd->movements = 0;
1209 _mouse_up(void *data,
1210 Evas *evas __UNUSED__,
1211 Evas_Object *obj __UNUSED__,
1214 Elm_Gen_Item *it = data;
1215 Evas_Event_Mouse_Up *ev = event_info;
1216 Eina_Bool dragged = EINA_FALSE;
1218 if (ev->button != 1) return;
1219 it->down = EINA_FALSE;
1220 it->wd->mouse_down = EINA_FALSE;
1221 if (it->wd->multitouched)
1223 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1224 if (it->wd->multi_down) return;
1225 _multi_touch_gesture_eval(data);
1228 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1229 else it->wd->on_hold = EINA_FALSE;
1232 ecore_timer_del(it->long_timer);
1233 it->long_timer = NULL;
1237 it->dragging = EINA_FALSE;
1238 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1241 if (it->item->swipe_timer)
1243 ecore_timer_del(it->item->swipe_timer);
1244 it->item->swipe_timer = NULL;
1246 if (it->wd->multi_timer)
1248 ecore_timer_del(it->wd->multi_timer);
1249 it->wd->multi_timer = NULL;
1250 it->wd->multi_timeout = EINA_FALSE;
1252 if (it->wd->on_hold)
1254 if (it->wd->swipe) _swipe(data);
1255 it->wd->longpressed = EINA_FALSE;
1256 it->wd->on_hold = EINA_FALSE;
1259 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1261 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1263 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1265 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1266 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1268 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1272 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1273 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1275 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1276 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1277 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1278 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1280 if (it->wd->longpressed)
1282 it->wd->longpressed = EINA_FALSE;
1283 if (!it->wd->wasselected)
1285 _item_unhighlight(it);
1288 it->wd->wasselected = EINA_FALSE;
1293 if (it->want_unrealize)
1295 _elm_genlist_item_unrealize(it, EINA_FALSE);
1296 if (it->item->block->want_unrealize)
1297 _item_block_unrealize(it->item->block);
1300 if ((it->disabled) || (dragged) || (it->display_only)) return;
1301 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1306 _item_highlight(it);
1311 _item_unhighlight(it);
1319 Widget_Data *wd = it->wd;
1322 while (wd->selected)
1324 _item_unhighlight(wd->selected->data);
1325 _item_unselect(wd->selected->data);
1331 const Eina_List *l, *l_next;
1334 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1337 _item_unhighlight(it2);
1338 _item_unselect(it2);
1340 //_item_highlight(it);
1343 _item_highlight(it);
1349 _signal_expand_toggle(void *data,
1350 Evas_Object *obj __UNUSED__,
1351 const char *emission __UNUSED__,
1352 const char *source __UNUSED__)
1354 Elm_Gen_Item *it = data;
1356 if (it->item->expanded)
1357 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1359 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1363 _signal_expand(void *data,
1364 Evas_Object *obj __UNUSED__,
1365 const char *emission __UNUSED__,
1366 const char *source __UNUSED__)
1368 Elm_Gen_Item *it = data;
1370 if (!it->item->expanded)
1371 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1375 _signal_contract(void *data,
1376 Evas_Object *obj __UNUSED__,
1377 const char *emission __UNUSED__,
1378 const char *source __UNUSED__)
1380 Elm_Gen_Item *it = data;
1382 if (it->item->expanded)
1383 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1387 _scr_hold_timer_cb(void *data)
1389 if (!data) return ECORE_CALLBACK_CANCEL;
1390 Widget_Data *wd = data;
1391 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1392 wd->scr_hold_timer = NULL;
1393 return ECORE_CALLBACK_CANCEL;
1397 _mode_finished_signal_cb(void *data,
1399 const char *emission __UNUSED__,
1400 const char *source __UNUSED__)
1404 Elm_Gen_Item *it = data;
1405 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1407 Evas *te = evas_object_evas_get(obj);
1409 evas_event_freeze(te);
1410 it->item->nocache = EINA_FALSE;
1411 _mode_item_unrealize(it);
1412 if (it->item->group_item)
1413 evas_object_raise(it->item->VIEW(group_item));
1414 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->mode_type);
1415 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1416 evas_event_thaw(te);
1417 evas_event_thaw_eval(te);
1421 _item_cache_clean(Widget_Data *wd)
1423 evas_event_freeze(evas_object_evas_get(wd->obj));
1424 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1428 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1429 wd->item_cache = eina_inlist_remove(wd->item_cache,
1430 wd->item_cache->last);
1431 wd->item_cache_count--;
1432 if (itc->spacer) evas_object_del(itc->spacer);
1433 if (itc->base_view) evas_object_del(itc->base_view);
1434 if (itc->item_style) eina_stringshare_del(itc->item_style);
1437 evas_event_thaw(evas_object_evas_get(wd->obj));
1438 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1442 _item_cache_zero(Widget_Data *wd)
1444 int pmax = wd->item_cache_max;
1445 wd->item_cache_max = 0;
1446 _item_cache_clean(wd);
1447 wd->item_cache_max = pmax;
1451 _item_cache_add(Elm_Gen_Item *it)
1455 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1456 if (it->wd->item_cache_max <= 0)
1458 evas_object_del(VIEW(it));
1460 evas_object_del(it->spacer);
1462 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1463 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1467 it->wd->item_cache_count++;
1468 itc = calloc(1, sizeof(Item_Cache));
1469 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1470 EINA_INLIST_GET(itc));
1471 itc->spacer = it->spacer;
1473 itc->base_view = VIEW(it);
1475 evas_object_hide(itc->base_view);
1476 evas_object_move(itc->base_view, -9999, -9999);
1477 itc->item_style = eina_stringshare_add(it->itc->item_style);
1478 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) itc->tree = 1;
1479 itc->compress = (it->wd->compress);
1480 itc->selected = it->selected;
1481 itc->disabled = it->disabled;
1482 itc->expanded = it->item->expanded;
1485 ecore_timer_del(it->long_timer);
1486 it->long_timer = NULL;
1488 if (it->item->swipe_timer)
1490 ecore_timer_del(it->item->swipe_timer);
1491 it->item->swipe_timer = NULL;
1493 // FIXME: other callbacks?
1494 edje_object_signal_callback_del_full(itc->base_view,
1495 "elm,action,expand,toggle",
1496 "elm", _signal_expand_toggle, it);
1497 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1499 _signal_expand, it);
1500 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1501 "elm", _signal_contract, it);
1502 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1504 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1506 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1508 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1510 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1512 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1514 _item_cache_clean(it->wd);
1515 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1516 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1520 _item_cache_find(Elm_Gen_Item *it)
1525 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) tree = 1;
1526 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1528 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1530 if ((itc->tree == tree) &&
1531 (itc->compress == it->wd->compress) &&
1532 (!strcmp(it->itc->item_style, itc->item_style)))
1534 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1535 EINA_INLIST_GET(itc));
1536 it->wd->item_cache_count--;
1544 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1546 if (!it->item->nostacking)
1548 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1549 evas_object_lower(VIEW(it));
1551 evas_object_raise(VIEW(it));
1554 if (it->item->order_num_in & 0x1)
1555 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1557 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1561 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1565 if (it->selected != itc->selected)
1568 edje_object_signal_emit(VIEW(it),
1569 "elm,state,selected", "elm");
1571 if (it->disabled != itc->disabled)
1574 edje_object_signal_emit(VIEW(it),
1575 "elm,state,disabled", "elm");
1577 if (it->item->expanded != itc->expanded)
1579 if (it->item->expanded)
1580 edje_object_signal_emit(VIEW(it),
1581 "elm,state,expanded", "elm");
1587 edje_object_signal_emit(VIEW(it),
1588 "elm,state,selected", "elm");
1590 edje_object_signal_emit(VIEW(it),
1591 "elm,state,disabled", "elm");
1592 if (it->item->expanded)
1593 edje_object_signal_emit(VIEW(it),
1594 "elm,state,expanded", "elm");
1599 _item_cache_free(Item_Cache *itc)
1601 if (itc->spacer) evas_object_del(itc->spacer);
1602 if (itc->base_view) evas_object_del(itc->base_view);
1603 if (itc->item_style) eina_stringshare_del(itc->item_style);
1608 _item_del_hook(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1610 Elm_Gen_Item *it = event_info;
1612 if (it->wd->last_selected_item == it)
1613 it->wd->last_selected_item = NULL;
1617 _item_text_realize(Elm_Gen_Item *it,
1618 Evas_Object *target,
1622 if (it->itc->func.text_get)
1627 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1628 EINA_LIST_FOREACH(*source, l, key)
1630 if (parts && fnmatch(parts, key, FNM_PERIOD))
1633 char *s = it->itc->func.text_get
1634 ((void *)it->base.data, WIDGET(it), key);
1638 edje_object_part_text_set(target, key, s);
1643 edje_object_part_text_set(target, key, "");
1650 _item_content_unrealize(Elm_Gen_Item *it,
1651 Evas_Object *target,
1655 Eina_List *res = it->content_objs;
1657 if (it->itc->func.content_get)
1661 Evas_Object *ic = NULL;
1663 EINA_LIST_FOREACH(*source, l, key)
1665 if (parts && fnmatch(parts, key, FNM_PERIOD))
1668 ic = edje_object_part_swallow_get(target, key);
1671 res = eina_list_remove(res, ic);
1672 edje_object_part_unswallow(target, ic);
1673 evas_object_del(ic);
1682 _item_content_realize(Elm_Gen_Item *it,
1683 Evas_Object *target,
1687 Eina_List *res = NULL;
1689 if (it->itc->func.content_get)
1693 Evas_Object *ic = NULL;
1695 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1697 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
1698 res = it->content_objs;
1700 EINA_LIST_FOREACH(*source, l, key)
1702 if (parts && fnmatch(parts, key, FNM_PERIOD))
1705 if (it->itc->func.content_get)
1706 ic = it->itc->func.content_get
1707 ((void *)it->base.data, WIDGET(it), key);
1710 res = eina_list_append(res, ic);
1711 edje_object_part_swallow(target, key, ic);
1712 evas_object_show(ic);
1713 elm_widget_sub_object_add(WIDGET(it), ic);
1715 elm_widget_disabled_set(ic, EINA_TRUE);
1724 _item_state_realize(Elm_Gen_Item *it,
1725 Evas_Object *target,
1729 if (it->itc->func.state_get)
1735 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
1736 EINA_LIST_FOREACH(*source, l, key)
1738 if (parts && fnmatch(parts, key, FNM_PERIOD))
1741 Eina_Bool on = it->itc->func.state_get
1742 ((void *)it->base.data, WIDGET(it), key);
1746 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1747 edje_object_signal_emit(target, buf, "elm");
1751 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1752 edje_object_signal_emit(target, buf, "elm");
1759 _item_realize(Elm_Gen_Item *it,
1763 const char *treesize;
1766 Item_Cache *itc = NULL;
1768 if (it->generation < it->wd->generation) return;
1769 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1772 if (it->item->order_num_in != in)
1774 it->item->order_num_in = in;
1775 _elm_genlist_item_odd_even_update(it);
1776 _elm_genlist_item_state_update(it, NULL);
1778 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1779 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1782 it->item->order_num_in = in;
1784 if (it->item->nocache)
1785 it->item->nocache = EINA_FALSE;
1787 itc = _item_cache_find(it);
1790 VIEW(it) = itc->base_view;
1791 itc->base_view = NULL;
1792 it->spacer = itc->spacer;
1797 const char *stacking_even;
1798 const char *stacking;
1800 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1801 edje_object_scale_set(VIEW(it),
1802 elm_widget_scale_get(WIDGET(it)) *
1803 _elm_config->scale);
1804 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
1805 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1807 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
1808 strncpy(buf, "tree", sizeof(buf));
1809 else strncpy(buf, "item", sizeof(buf));
1810 if (it->wd->compress)
1811 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1813 strncat(buf, "/", sizeof(buf) - strlen(buf));
1814 strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1816 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
1817 elm_widget_style_get(WIDGET(it)));
1819 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1820 if (!stacking_even) stacking_even = "above";
1821 it->item->stacking_even = !!strcmp("above", stacking_even);
1823 stacking = edje_object_data_get(VIEW(it), "stacking");
1824 if (!stacking) stacking = "yes";
1825 it->item->nostacking = !!strcmp("yes", stacking);
1827 edje_object_mirrored_set(VIEW(it),
1828 elm_widget_mirrored_get(WIDGET(it)));
1830 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1831 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1832 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1835 _elm_genlist_item_odd_even_update(it);
1837 treesize = edje_object_data_get(VIEW(it), "treesize");
1838 if (treesize) tsize = atoi(treesize);
1839 evas_object_size_hint_min_set(it->spacer,
1840 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
1841 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1844 edje_object_signal_callback_add(VIEW(it),
1845 "elm,action,expand,toggle",
1846 "elm", _signal_expand_toggle, it);
1847 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
1848 "elm", _signal_expand, it);
1849 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
1850 "elm", _signal_contract, it);
1851 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
1853 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
1855 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1857 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
1859 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
1861 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
1864 _elm_genlist_item_state_update(it, itc);
1867 if ((calc) && (it->wd->homogeneous) &&
1868 ((it->wd->item_width) ||
1869 ((it->wd->item_width) && (it->wd->group_item_width))))
1871 /* homogenous genlist shortcut */
1872 if (!it->item->mincalcd)
1876 it->item->w = it->item->minw = it->wd->group_item_width;
1877 it->item->h = it->item->minh = it->wd->group_item_height;
1881 it->item->w = it->item->minw = it->wd->item_width;
1882 it->item->h = it->item->minh = it->wd->item_height;
1884 it->item->mincalcd = EINA_TRUE;
1889 /* FIXME: If you see that assert, please notify us and we
1890 will clean our mess */
1891 assert(eina_list_count(it->content_objs) == 0);
1893 _item_text_realize(it, VIEW(it), &it->texts, NULL);
1894 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
1895 _item_state_realize(it, VIEW(it), &it->states, NULL);
1897 if (!it->item->mincalcd)
1899 Evas_Coord mw = -1, mh = -1;
1901 if (!it->display_only)
1902 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1903 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
1904 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
1906 if (!it->display_only)
1907 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1908 it->item->w = it->item->minw = mw;
1909 it->item->h = it->item->minh = mh;
1910 it->item->mincalcd = EINA_TRUE;
1912 if ((!it->wd->group_item_width) && (it->group))
1914 it->wd->group_item_width = mw;
1915 it->wd->group_item_height = mh;
1917 else if ((!it->wd->item_width) && (it->item->flags == ELM_GENLIST_ITEM_NONE))
1919 it->wd->item_width = mw;
1920 it->wd->item_height = mh;
1923 if (!calc) evas_object_show(VIEW(it));
1926 if (it->tooltip.content_cb)
1928 elm_widget_item_tooltip_content_cb_set(it,
1929 it->tooltip.content_cb,
1930 it->tooltip.data, NULL);
1931 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1932 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1935 if (it->mouse_cursor)
1936 elm_widget_item_cursor_set(it, it->mouse_cursor);
1938 it->realized = EINA_TRUE;
1939 it->want_unrealize = EINA_FALSE;
1941 if (itc) _item_cache_free(itc);
1942 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1943 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1945 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1946 edje_object_message_signal_process(VIEW(it));
1950 _item_unrealize_cb(Elm_Gen_Item *it)
1952 if (it->item->nocache)
1954 evas_object_del(VIEW(it));
1956 evas_object_del(it->spacer);
1961 edje_object_mirrored_set(VIEW(it),
1962 elm_widget_mirrored_get(WIDGET(it)));
1963 edje_object_scale_set(VIEW(it),
1964 elm_widget_scale_get(WIDGET(it))
1965 * _elm_config->scale);
1966 _item_cache_add(it);
1969 _mode_item_unrealize(it);
1971 it->realized = EINA_FALSE;
1972 it->want_unrealize = EINA_FALSE;
1976 _item_block_recalc(Item_Block *itb,
1982 Evas_Coord minw = 0, minh = 0;
1983 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
1986 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
1988 EINA_LIST_FOREACH(itb->items, l, it)
1990 if (it->generation < it->wd->generation) continue;
1991 showme |= it->item->showme;
1996 if (!it->item->mincalcd) changed = EINA_TRUE;
1999 _item_realize(it, in, EINA_TRUE);
2000 _elm_genlist_item_unrealize(it, EINA_TRUE);
2005 _item_realize(it, in, EINA_TRUE);
2006 _elm_genlist_item_unrealize(it, EINA_TRUE);
2010 _item_realize(it, in, EINA_FALSE);
2011 minh += it->item->minh;
2012 if (minw < it->item->minw) minw = it->item->minw;
2020 itb->changed = EINA_FALSE;
2021 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2022 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2027 _item_block_realize(Item_Block *itb)
2029 if (itb->realized) return;
2030 itb->realized = EINA_TRUE;
2031 itb->want_unrealize = EINA_FALSE;
2035 _item_block_unrealize(Item_Block *itb)
2039 Eina_Bool dragging = EINA_FALSE;
2041 if (!itb->realized) return;
2042 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2043 EINA_LIST_FOREACH(itb->items, l, it)
2049 dragging = EINA_TRUE;
2050 it->want_unrealize = EINA_TRUE;
2053 _elm_genlist_item_unrealize(it, EINA_FALSE);
2058 itb->realized = EINA_FALSE;
2059 itb->want_unrealize = EINA_TRUE;
2062 itb->want_unrealize = EINA_FALSE;
2063 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2064 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2068 _get_space_for_reorder_item(Elm_Gen_Item *it)
2070 Evas_Coord rox, roy, row, roh, oy, oh;
2071 Eina_Bool top = EINA_FALSE;
2072 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2073 if (!reorder_it) return 0;
2075 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2076 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2078 if ((it->wd->reorder_start_y < it->item->block->y) &&
2079 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2081 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2082 if (it->item->block->count == 1)
2083 it->wd->reorder_rel = it;
2085 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2086 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2088 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2091 it->item->block->reorder_offset = 0;
2093 it->item->scrl_y += it->item->block->reorder_offset;
2095 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2096 rox, roy + (roh / 2), row, 1));
2099 it->wd->reorder_rel = it;
2100 it->item->scrl_y += it->wd->reorder_it->item->h;
2101 return it->wd->reorder_it->item->h;
2108 _reorder_move_animator_cb(void *data)
2110 Elm_Gen_Item *it = data;
2111 Eina_Bool down = EINA_FALSE;
2113 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2115 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2117 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2120 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2121 if (diff > it->item->h) y = diff / 2;
2123 if (it->item->old_scrl_y < it->item->scrl_y)
2125 it->item->old_scrl_y += y;
2128 else if (it->item->old_scrl_y > it->item->scrl_y)
2130 it->item->old_scrl_y -= y;
2133 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2134 _group_items_recalc(it->wd);
2136 if ((it->wd->reorder_pan_move) ||
2137 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2138 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2140 it->item->old_scrl_y = it->item->scrl_y;
2141 it->item->move_effect_enabled = EINA_FALSE;
2142 it->wd->reorder_move_animator = NULL;
2143 return ECORE_CALLBACK_CANCEL;
2145 return ECORE_CALLBACK_RENEW;
2149 _item_position(Elm_Gen_Item *it,
2157 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2158 evas_object_resize(view, it->item->w, it->item->h);
2159 evas_object_move(view, it_x, it_y);
2160 evas_object_show(view);
2161 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2162 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2166 _item_block_position(Item_Block *itb,
2172 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2173 Eina_Bool vis = EINA_FALSE;
2175 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2176 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2177 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2179 EINA_LIST_FOREACH(itb->items, l, it)
2181 if (it->generation < it->wd->generation) continue;
2182 else if (it->wd->reorder_it == it) continue;
2185 it->item->w = itb->w;
2186 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2187 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2189 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2190 cvx, cvy, cvw, cvh));
2193 if ((itb->realized) && (!it->realized))
2195 if (vis) _item_realize(it, in, EINA_FALSE);
2201 if (it->wd->reorder_mode)
2202 y += _get_space_for_reorder_item(it);
2203 git = it->item->group_item;
2206 if (git->item->scrl_y < oy)
2207 git->item->scrl_y = oy;
2208 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2209 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2210 git->item->want_realize = EINA_TRUE;
2212 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2214 if (!it->item->move_effect_enabled)
2216 it->item->move_effect_enabled = EINA_TRUE;
2217 it->wd->reorder_move_animator =
2219 _reorder_move_animator_cb, it);
2222 if (!it->item->move_effect_enabled)
2224 if (it->item->mode_view)
2225 _item_position(it, it->item->mode_view, it->item->scrl_x,
2228 _item_position(it, VIEW(it), it->item->scrl_x,
2230 it->item->old_scrl_y = it->item->scrl_y;
2235 if (!it->dragging) _elm_genlist_item_unrealize(it, EINA_FALSE);
2242 if (vis) it->item->want_realize = EINA_TRUE;
2246 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2247 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2251 _group_items_recalc(void *data)
2253 Widget_Data *wd = data;
2257 evas_event_freeze(evas_object_evas_get(wd->obj));
2258 EINA_LIST_FOREACH(wd->group_items, l, git)
2260 if (git->item->want_realize)
2263 _item_realize(git, 0, EINA_FALSE);
2264 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2265 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2266 evas_object_show(VIEW(git));
2267 evas_object_raise(VIEW(git));
2269 else if (!git->item->want_realize && git->realized)
2272 _elm_genlist_item_unrealize(git, EINA_FALSE);
2275 evas_event_thaw(evas_object_evas_get(wd->obj));
2276 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2280 _must_recalc_idler(void *data)
2282 Widget_Data *wd = data;
2283 if (wd->calc_job) ecore_job_del(wd->calc_job);
2284 wd->calc_job = ecore_job_add(_calc_job, wd);
2285 wd->must_recalc_idler = NULL;
2286 return ECORE_CALLBACK_CANCEL;
2290 _scroll_item(Widget_Data *wd)
2292 Elm_Genlist_Item *it = NULL;
2293 Evas_Coord gith = 0;
2294 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2296 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2298 dx = it->x + it->item->block->x;
2299 dy = it->y + it->item->block->y;
2300 dw = it->item->block->w;
2302 switch (wd->scrollto_type)
2304 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2305 if (it->item->group_item) gith = it->item->group_item->item->h;
2308 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2309 dy += (it->item->h / 2 - oh / 2);
2311 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2313 if ((wd->expanded_item) &&
2314 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2315 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2317 it = wd->expanded_item;
2318 if (it->item->group_item) gith = it->item->group_item->item->h;
2319 dx = it->x + it->item->block->x;
2320 dy = it->y + it->item->block->y - gith;
2321 dw = it->item->block->w;
2325 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2326 gith = it->item->group_item->item->h;
2333 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2335 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2337 it->item->showme = EINA_FALSE;
2338 wd->show_item = NULL;
2339 wd->auto_scroll_enabled = EINA_FALSE;
2340 wd->check_scroll = EINA_FALSE;
2344 _calc_job(void *data)
2346 Widget_Data *wd = data;
2347 Item_Block *itb, *chb = NULL;
2348 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0;
2349 Evas_Coord pan_w = 0, pan_h = 0;
2351 Eina_Bool minw_change = EINA_FALSE;
2352 Eina_Bool did_must_recalc = EINA_FALSE;
2355 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2359 evas_event_freeze(evas_object_evas_get(wd->obj));
2360 EINA_INLIST_FOREACH(wd->blocks, itb)
2362 Eina_Bool showme = EINA_FALSE;
2365 showme = itb->showme;
2366 itb->showme = EINA_FALSE;
2369 if (itb->realized) _item_block_unrealize(itb);
2371 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2373 if (itb->must_recalc)
2377 EINA_LIST_FOREACH(itb->items, l, it)
2378 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2379 itb->changed = EINA_TRUE;
2380 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2381 itb->must_recalc = EINA_FALSE;
2383 if (itb->realized) _item_block_unrealize(itb);
2384 showme = _item_block_recalc(itb, in, EINA_FALSE);
2390 if (minw == -1) minw = itb->minw;
2391 else if ((!itb->must_recalc) && (minw < itb->minw))
2394 minw_change = EINA_TRUE;
2400 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2401 wd->check_scroll = EINA_TRUE;
2405 EINA_INLIST_FOREACH(wd->blocks, itb)
2411 if ((chb) && (EINA_INLIST_GET(chb)->next))
2413 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2415 if (itb->realized) _item_block_unrealize(itb);
2418 wd->realminw = minw;
2419 if (minw < wd->w) minw = wd->w;
2420 if ((minw != wd->minw) || (minh != wd->minh))
2424 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2425 _sizing_eval(wd->obj);
2426 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2431 it = wd->anchor_item;
2432 it_y = wd->anchor_y;
2433 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2434 it->item->block->y + it->y + it_y);
2435 wd->anchor_item = it;
2436 wd->anchor_y = it_y;
2439 if (did_must_recalc)
2441 if (!wd->must_recalc_idler)
2442 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2444 if (wd->check_scroll)
2446 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2447 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2448 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2449 switch (wd->scrollto_type)
2451 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2454 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2457 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2462 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2463 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2468 wd->calc_job = NULL;
2469 evas_object_smart_changed(wd->pan_smart);
2470 evas_event_thaw(evas_object_evas_get(wd->obj));
2471 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2475 _update_job(void *data)
2477 Widget_Data *wd = data;
2481 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2483 wd->update_job = NULL;
2486 evas_event_freeze(evas_object_evas_get(wd->obj));
2487 EINA_INLIST_FOREACH(wd->blocks, itb)
2489 Evas_Coord itminw, itminh;
2496 _item_block_position(itb, num);
2500 recalc = EINA_FALSE;
2501 EINA_LIST_FOREACH(itb->items, l2, it)
2503 if (it->item->updateme)
2505 itminw = it->item->minw;
2506 itminh = it->item->minh;
2508 it->item->updateme = EINA_FALSE;
2511 _elm_genlist_item_unrealize(it, EINA_FALSE);
2512 _item_realize(it, num, EINA_FALSE);
2513 position = EINA_TRUE;
2517 _item_realize(it, num, EINA_TRUE);
2518 _elm_genlist_item_unrealize(it, EINA_TRUE);
2520 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2525 itb->updateme = EINA_FALSE;
2528 position = EINA_TRUE;
2529 itb->changed = EINA_TRUE;
2530 _item_block_recalc(itb, num0, EINA_FALSE);
2531 _item_block_position(itb, num0);
2536 if (wd->calc_job) ecore_job_del(wd->calc_job);
2537 wd->calc_job = ecore_job_add(_calc_job, wd);
2539 evas_event_thaw(evas_object_evas_get(wd->obj));
2540 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2544 _pan_set(Evas_Object *obj,
2548 Pan *sd = evas_object_smart_data_get(obj);
2552 // Evas_Coord ow, oh;
2553 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2554 // ow = sd->wd->minw - ow;
2555 // if (ow < 0) ow = 0;
2556 // oh = sd->wd->minh - oh;
2557 // if (oh < 0) oh = 0;
2558 // if (x < 0) x = 0;
2559 // if (y < 0) y = 0;
2560 // if (x > ow) x = ow;
2561 // if (y > oh) y = oh;
2562 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2566 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2568 if ((itb->y + itb->h) > y)
2573 EINA_LIST_FOREACH(itb->items, l2, it)
2575 if ((itb->y + it->y) >= y)
2577 sd->wd->anchor_item = it;
2578 sd->wd->anchor_y = -(itb->y + it->y - y);
2585 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2589 _pan_get(Evas_Object *obj,
2593 Pan *sd = evas_object_smart_data_get(obj);
2596 if (x) *x = sd->wd->pan_x;
2597 if (y) *y = sd->wd->pan_y;
2601 _pan_max_get(Evas_Object *obj,
2605 Pan *sd = evas_object_smart_data_get(obj);
2609 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2610 ow = sd->wd->minw - ow;
2612 oh = sd->wd->minh - oh;
2619 _pan_min_get(Evas_Object *obj __UNUSED__,
2628 _pan_child_size_get(Evas_Object *obj,
2632 Pan *sd = evas_object_smart_data_get(obj);
2635 if (w) *w = sd->wd->minw;
2636 if (h) *h = sd->wd->minh;
2640 _pan_add(Evas_Object *obj)
2643 Evas_Object_Smart_Clipped_Data *cd;
2646 cd = evas_object_smart_data_get(obj);
2649 sd->__clipped_data = *cd;
2651 evas_object_smart_data_set(obj, sd);
2655 _pan_del(Evas_Object *obj)
2657 Pan *sd = evas_object_smart_data_get(obj);
2662 ecore_job_del(sd->resize_job);
2663 sd->resize_job = NULL;
2669 _pan_resize_job(void *data)
2673 _sizing_eval(sd->wd->obj);
2674 sd->resize_job = NULL;
2678 _pan_resize(Evas_Object *obj,
2682 Pan *sd = evas_object_smart_data_get(obj);
2686 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2687 if ((ow == w) && (oh == h)) return;
2688 if ((sd->wd->height_for_width) && (ow != w))
2691 if (sd->resize_job) ecore_job_del(sd->resize_job);
2692 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2694 sd->wd->pan_changed = EINA_TRUE;
2695 evas_object_smart_changed(obj);
2696 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2697 sd->wd->calc_job = NULL;
2699 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2700 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2705 _pan_calculate(Evas_Object *obj)
2707 Pan *sd = evas_object_smart_data_get(obj);
2709 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2715 evas_event_freeze(evas_object_evas_get(obj));
2717 if (sd->wd->pan_changed)
2720 sd->wd->pan_changed = EINA_FALSE;
2723 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2724 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2725 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2727 git->item->want_realize = EINA_FALSE;
2729 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2731 itb->w = sd->wd->minw;
2732 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2733 itb->y - sd->wd->pan_y + oy,
2735 cvx, cvy, cvw, cvh))
2737 if ((!itb->realized) || (itb->changed))
2738 _item_block_realize(itb);
2739 _item_block_position(itb, in);
2743 if (itb->realized) _item_block_unrealize(itb);
2747 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2748 _group_items_recalc(sd->wd);
2749 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2751 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2752 sd->wd->reorder_pan_move = EINA_TRUE;
2753 else sd->wd->reorder_pan_move = EINA_FALSE;
2754 evas_object_raise(sd->wd->VIEW(reorder_it));
2755 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2756 sd->wd->start_time = ecore_loop_time_get();
2758 _item_auto_scroll(sd->wd);
2759 evas_event_thaw(evas_object_evas_get(obj));
2760 evas_event_thaw_eval(evas_object_evas_get(obj));
2764 _pan_move(Evas_Object *obj,
2765 Evas_Coord x __UNUSED__,
2766 Evas_Coord y __UNUSED__)
2768 Pan *sd = evas_object_smart_data_get(obj);
2772 sd->wd->pan_changed = EINA_TRUE;
2773 evas_object_smart_changed(obj);
2774 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2775 sd->wd->calc_job = NULL;
2779 _hold_on(void *data __UNUSED__,
2781 void *event_info __UNUSED__)
2783 Widget_Data *wd = elm_widget_data_get(obj);
2785 elm_smart_scroller_hold_set(wd->scr, 1);
2789 _hold_off(void *data __UNUSED__,
2791 void *event_info __UNUSED__)
2793 Widget_Data *wd = elm_widget_data_get(obj);
2795 elm_smart_scroller_hold_set(wd->scr, 0);
2799 _freeze_on(void *data __UNUSED__,
2801 void *event_info __UNUSED__)
2803 Widget_Data *wd = elm_widget_data_get(obj);
2805 elm_smart_scroller_freeze_set(wd->scr, 1);
2809 _freeze_off(void *data __UNUSED__,
2811 void *event_info __UNUSED__)
2813 Widget_Data *wd = elm_widget_data_get(obj);
2815 elm_smart_scroller_freeze_set(wd->scr, 0);
2819 _scr_anim_start(void *data,
2820 Evas_Object *obj __UNUSED__,
2821 void *event_info __UNUSED__)
2823 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
2827 _scr_anim_stop(void *data,
2828 Evas_Object *obj __UNUSED__,
2829 void *event_info __UNUSED__)
2831 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
2835 _scr_drag_start(void *data,
2836 Evas_Object *obj __UNUSED__,
2837 void *event_info __UNUSED__)
2839 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
2843 _scr_drag_stop(void *data,
2844 Evas_Object *obj __UNUSED__,
2845 void *event_info __UNUSED__)
2847 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
2851 _edge_left(void *data,
2852 Evas_Object *scr __UNUSED__,
2853 void *event_info __UNUSED__)
2855 Evas_Object *obj = data;
2856 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2860 _edge_right(void *data,
2861 Evas_Object *scr __UNUSED__,
2862 void *event_info __UNUSED__)
2864 Evas_Object *obj = data;
2865 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2869 _edge_top(void *data,
2870 Evas_Object *scr __UNUSED__,
2871 void *event_info __UNUSED__)
2873 Evas_Object *obj = data;
2874 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2878 _edge_bottom(void *data,
2879 Evas_Object *scr __UNUSED__,
2880 void *event_info __UNUSED__)
2882 Evas_Object *obj = data;
2883 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2887 _mode_item_realize(Elm_Gen_Item *it)
2891 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
2893 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2894 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
2895 edje_object_scale_set(it->item->mode_view,
2896 elm_widget_scale_get(WIDGET(it)) *
2897 _elm_config->scale);
2898 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
2899 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
2901 strncpy(buf, "item", sizeof(buf));
2902 if (it->wd->compress)
2903 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
2905 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
2906 strncat(buf, "/", sizeof(buf) - strlen(buf));
2907 strncat(buf, it->wd->mode_item_style, sizeof(buf) - strlen(buf));
2909 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
2910 elm_widget_style_get(WIDGET(it)));
2911 edje_object_mirrored_set(it->item->mode_view,
2912 elm_widget_mirrored_get(WIDGET(it)));
2914 /* signal callback add */
2915 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
2917 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
2919 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
2922 /* text_get, content_get, state_get */
2923 /* FIXME: If you see that assert, please notify us and we
2924 will clean our mess */
2925 assert(eina_list_count(it->item->mode_content_objs) == 0);
2927 _item_text_realize(it, it->item->mode_view, &it->item->mode_texts, NULL);
2928 it->item->mode_content_objs =
2929 _item_content_realize(it, it->item->mode_view,
2930 &it->item->mode_contents, NULL);
2931 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
2933 edje_object_part_swallow(it->item->mode_view,
2934 edje_object_data_get(it->item->mode_view, "mode_part"),
2937 it->want_unrealize = EINA_FALSE;
2938 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2939 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2943 _mode_item_unrealize(Elm_Gen_Item *it)
2945 Widget_Data *wd = it->wd;
2946 Evas_Object *content;
2947 if (!it->item->mode_view) return;
2949 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2950 elm_widget_stringlist_free(it->item->mode_texts);
2951 it->item->mode_texts = NULL;
2952 elm_widget_stringlist_free(it->item->mode_contents);
2953 it->item->mode_contents = NULL;
2954 elm_widget_stringlist_free(it->item->mode_states);
2956 EINA_LIST_FREE(it->item->mode_content_objs, content)
2957 evas_object_del(content);
2959 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
2960 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
2961 evas_object_del(it->item->mode_view);
2962 it->item->mode_view = NULL;
2964 if (wd->mode_item == it)
2965 wd->mode_item = NULL;
2966 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2967 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2971 _item_mode_set(Elm_Gen_Item *it)
2974 Widget_Data *wd = it->wd;
2979 it->item->nocache = EINA_TRUE;
2981 if (wd->scr_hold_timer)
2983 ecore_timer_del(wd->scr_hold_timer);
2984 wd->scr_hold_timer = NULL;
2986 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
2987 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
2989 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2990 _mode_item_realize(it);
2991 if (it->item->group_item)
2992 evas_object_raise(it->item->VIEW(group_item));
2993 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
2994 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2995 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2997 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
2998 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3002 _item_mode_unset(Widget_Data *wd)
3005 if (!wd->mode_item) return;
3006 char buf[1024], buf2[1024];
3010 it->item->nocache = EINA_TRUE;
3012 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
3013 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
3015 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3016 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
3018 wd->mode_item = NULL;
3022 _item_auto_scroll(Widget_Data *wd)
3025 Elm_Gen_Item *tmp_item = NULL;
3027 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3029 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3030 if (!tmp_item) return;
3031 wd->show_item = tmp_item;
3032 wd->bring_in = EINA_TRUE;
3033 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3034 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3036 wd->show_item->item->showme = EINA_TRUE;
3037 wd->auto_scroll_enabled = EINA_FALSE;
3045 elm_genlist_add(Evas_Object *parent)
3050 Evas_Coord minw, minh;
3051 static Evas_Smart *smart = NULL;
3055 static Evas_Smart_Class sc;
3057 evas_object_smart_clipped_smart_set(&_pan_sc);
3059 sc.name = "elm_genlist_pan";
3060 sc.version = EVAS_SMART_CLASS_VERSION;
3063 sc.resize = _pan_resize;
3064 sc.move = _pan_move;
3065 sc.calculate = _pan_calculate;
3066 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3069 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3071 ELM_SET_WIDTYPE(widtype, "genlist");
3073 elm_widget_type_set(obj, "genlist");
3074 elm_widget_sub_object_add(parent, obj);
3075 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3076 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3077 elm_widget_data_set(obj, wd);
3078 elm_widget_del_hook_set(obj, _del_hook);
3079 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3080 elm_widget_theme_hook_set(obj, _theme_hook);
3081 elm_widget_can_focus_set(obj, EINA_TRUE);
3082 elm_widget_event_hook_set(obj, _event_hook);
3083 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3084 elm_widget_translate_hook_set(obj, _translate_hook);
3087 wd->scr = elm_smart_scroller_add(e);
3088 elm_smart_scroller_widget_set(wd->scr, obj);
3089 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3090 elm_widget_style_get(obj));
3091 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3092 _elm_config->thumbscroll_bounce_enable);
3093 elm_widget_resize_object_set(obj, wd->scr);
3095 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3096 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3097 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3098 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3099 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3100 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3101 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3102 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3105 wd->mode = ELM_LIST_SCROLL;
3106 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3107 wd->item_cache_max = wd->max_items_per_block * 2;
3108 wd->longpress_timeout = _elm_config->longpress_timeout;
3110 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3111 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3112 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3113 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3115 wd->pan_smart = evas_object_smart_add(e, smart);
3116 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3119 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3120 _pan_set, _pan_get, _pan_max_get,
3121 _pan_min_get, _pan_child_size_get);
3123 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3125 evas_object_size_hint_min_set(obj, minw, minh);
3127 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3129 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3135 _item_select(Elm_Gen_Item *it)
3137 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3140 it->selected = EINA_TRUE;
3141 it->wd->selected = eina_list_append(it->wd->selected, it);
3143 else if (!it->wd->always_select) return;
3145 evas_object_ref(WIDGET(it));
3148 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3149 if (it->generation == it->wd->generation)
3150 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3153 evas_object_unref(WIDGET(it));
3154 if ((it->wd->clear_me) && (!it->wd->walking))
3155 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3158 if ((!it->walking) && (it->generation < it->wd->generation))
3160 if (!it->relcount) it->del_cb(it);
3163 it->wd->last_selected_item = it;
3167 static Evas_Object *
3168 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3170 return edje_object_part_swallow_get(VIEW(it), part);
3174 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3176 edje_object_part_swallow(VIEW(it), part, content);
3179 static Evas_Object *
3180 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3184 obj = edje_object_part_swallow_get(VIEW(it), part);
3185 if (!obj) return NULL;
3186 edje_object_part_unswallow(VIEW(it), obj);
3191 _item_text_hook(Elm_Gen_Item *it, const char *part)
3193 if (!it->itc->func.text_get) return NULL;
3194 return edje_object_part_text_get(VIEW(it), part);
3198 _elm_genlist_item_new(Widget_Data *wd,
3199 const Elm_Gen_Item_Class *itc,
3201 Elm_Gen_Item *parent,
3203 const void *func_data)
3207 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3208 if (!it) return NULL;
3210 it->generation = wd->generation;
3212 it->base.data = data;
3213 it->parent = parent;
3214 it->func.func = func;
3215 it->func.data = func_data;
3216 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3217 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3218 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3220 it->sel_cb = (Ecore_Cb)_item_select;
3222 elm_widget_item_text_get_hook_set(it, _item_text_hook);
3226 static Elm_Gen_Item *
3227 _item_new(Widget_Data *wd,
3228 const Elm_Genlist_Item_Class *itc,
3230 Elm_Gen_Item *parent,
3231 Elm_Genlist_Item_Flags flags,
3233 const void *func_data)
3235 Elm_Gen_Item *it, *it2;
3238 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3239 if (!it) return NULL;
3240 it->item = ELM_NEW(Elm_Gen_Item_Type);
3241 it->item->flags = flags;
3242 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3243 it->item->expanded_depth = 0;
3244 elm_widget_item_del_cb_set(it, _item_del_hook);
3245 ELM_GEN_ITEM_SETUP(it);
3248 if (it->parent->group)
3249 it->item->group_item = parent;
3250 else if (it->parent->item->group_item)
3251 it->item->group_item = it->parent->item->group_item;
3253 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3255 if (!it2->parent->group) depth += 1;
3257 it->item->expanded_depth = depth;
3262 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3266 itb = calloc(1, sizeof(Item_Block));
3267 if (!itb) return NULL;
3270 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3272 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3277 _item_block_add(Widget_Data *wd,
3280 Item_Block *itb = NULL;
3287 itb = calloc(1, sizeof(Item_Block));
3288 if (!itb) return EINA_FALSE;
3290 if (!it->item->rel->item->block)
3293 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3294 itb->items = eina_list_append(itb->items, it);
3298 if (it->item->before)
3300 wd->blocks = eina_inlist_prepend_relative
3301 (wd->blocks, EINA_INLIST_GET(itb),
3302 EINA_INLIST_GET(it->item->rel->item->block));
3304 eina_list_prepend_relative(itb->items, it, it->item->rel);
3308 wd->blocks = eina_inlist_append_relative
3309 (wd->blocks, EINA_INLIST_GET(itb),
3310 EINA_INLIST_GET(it->item->rel->item->block));
3312 eina_list_append_relative(itb->items, it, it->item->rel);
3318 if (it->item->before)
3322 itb = (Item_Block *)(wd->blocks);
3323 if (itb->count >= wd->max_items_per_block)
3325 itb = _item_block_new(wd, EINA_TRUE);
3326 if (!itb) return EINA_FALSE;
3331 itb = _item_block_new(wd, EINA_TRUE);
3332 if (!itb) return EINA_FALSE;
3334 itb->items = eina_list_prepend(itb->items, it);
3340 itb = (Item_Block *)(wd->blocks->last);
3341 if (itb->count >= wd->max_items_per_block)
3343 itb = _item_block_new(wd, EINA_FALSE);
3344 if (!itb) return EINA_FALSE;
3349 itb = _item_block_new(wd, EINA_FALSE);
3350 if (!itb) return EINA_FALSE;
3352 itb->items = eina_list_append(itb->items, it);
3358 if (it->item->rel->item->queued)
3360 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3361 on sorted insertion order, so the queue is not always ordered like the item list.
3362 This lead to issue where we depend on an item that is not yet created. As a quick
3363 work around, we reschedule the calc of the item and stop reordering the list to
3364 prevent any nasty issue to show up here.
3366 wd->queue = eina_list_append(wd->queue, it);
3367 wd->requeued = EINA_TRUE;
3368 it->item->queued = EINA_TRUE;
3371 itb = it->item->rel->item->block;
3372 if (!itb) goto newblock;
3373 if (it->item->before)
3374 itb->items = eina_list_prepend_relative(itb->items, it, it->item->rel);
3376 itb->items = eina_list_append_relative(itb->items, it, it->item->rel);
3379 itb->changed = EINA_TRUE;
3380 it->item->block = itb;
3381 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3382 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3385 it->item->rel->relcount--;
3386 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3387 _item_del(it->item->rel);
3388 it->item->rel = NULL;
3390 if (itb->count > itb->wd->max_items_per_block)
3395 Eina_Bool done = EINA_FALSE;
3397 newc = itb->count / 2;
3399 if (EINA_INLIST_GET(itb)->prev)
3401 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3403 if (itbp->count + newc < wd->max_items_per_block / 2)
3405 /* moving items to previous block */
3406 while ((itb->count > newc) && (itb->items))
3408 it2 = eina_list_data_get(itb->items);
3409 itb->items = eina_list_remove_list(itb->items, itb->items);
3412 itbp->items = eina_list_append(itbp->items, it2);
3413 it2->item->block = itbp;
3421 if (!done && EINA_INLIST_GET(itb)->next)
3423 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3425 if (itbn->count + newc < wd->max_items_per_block / 2)
3427 /* moving items to next block */
3428 while ((itb->count > newc) && (itb->items))
3432 l = eina_list_last(itb->items);
3433 it2 = eina_list_data_get(l);
3434 itb->items = eina_list_remove_list(itb->items, l);
3437 itbn->items = eina_list_prepend(itbn->items, it2);
3438 it2->item->block = itbn;
3448 /* moving items to new block */
3449 itb2 = calloc(1, sizeof(Item_Block));
3450 if (!itb2) return EINA_FALSE;
3453 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3454 EINA_INLIST_GET(itb));
3455 itb2->changed = EINA_TRUE;
3456 while ((itb->count > newc) && (itb->items))
3460 l = eina_list_last(itb->items);
3462 itb->items = eina_list_remove_list(itb->items, l);
3465 itb2->items = eina_list_prepend(itb2->items, it2);
3466 it2->item->block = itb2;
3476 _queue_process(Widget_Data *wd)
3479 Eina_Bool showme = EINA_FALSE;
3482 t0 = ecore_loop_time_get();
3483 //evas_event_freeze(evas_object_evas_get(wd->obj));
3484 for (n = 0; (wd->queue) && (n < 128); n++)
3488 it = eina_list_data_get(wd->queue);
3489 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3490 it->item->queued = EINA_FALSE;
3491 if (!_item_block_add(wd, it)) continue;
3493 _item_block_realize(it->item->block);
3494 t = ecore_time_get();
3495 if (it->item->block->changed)
3497 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3498 it->item->block->changed = 0;
3501 if (wd->calc_job) ecore_job_del(wd->calc_job);
3502 wd->calc_job = NULL;
3504 wd->pan_changed = EINA_FALSE;
3507 if (showme) it->item->block->showme = EINA_TRUE;
3508 if (eina_inlist_count(wd->blocks) > 1)
3510 if ((t - t0) > (ecore_animator_frametime_get())) break;
3513 //evas_event_thaw(evas_object_evas_get(wd->obj));
3514 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3519 _idle_process(void *data, Eina_Bool *wakeup)
3521 Widget_Data *wd = data;
3524 //static double q_start = 0.0;
3525 //if (q_start == 0.0) q_start = ecore_time_get();
3527 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
3531 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
3533 return ECORE_CALLBACK_CANCEL;
3535 return ECORE_CALLBACK_RENEW;
3539 _item_idle_enterer(void *data)
3541 Widget_Data *wd = data;
3542 Eina_Bool wakeup = EINA_FALSE;
3543 Eina_Bool ok = _idle_process(data, &wakeup);
3548 if (wd->calc_job) ecore_job_del(wd->calc_job);
3549 wd->calc_job = ecore_job_add(_calc_job, wd);
3551 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
3556 _item_queue(Widget_Data *wd,
3560 if (it->item->queued) return;
3561 it->item->queued = EINA_TRUE;
3562 if (cb && !wd->requeued)
3563 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
3565 wd->queue = eina_list_append(wd->queue, it);
3566 // FIXME: why does a freeze then thaw here cause some genlist
3567 // elm_genlist_item_append() to be much much slower?
3568 // evas_event_freeze(evas_object_evas_get(wd->obj));
3569 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
3571 if (wd->queue_idle_enterer)
3573 ecore_idle_enterer_del(wd->queue_idle_enterer);
3574 wd->queue_idle_enterer = NULL;
3578 // evas_event_thaw(evas_object_evas_get(wd->obj));
3579 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3580 if (!wd->queue_idle_enterer)
3581 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
3585 _elm_genlist_item_compare_data(const void *data, const void *data1)
3587 const Elm_Gen_Item *it = data;
3588 const Elm_Gen_Item *item1 = data1;
3590 return it->wd->item_compare_data_cb(it->base.data, item1->base.data);
3594 _elm_genlist_item_compare(const void *data, const void *data1)
3596 const Elm_Gen_Item *it, *item1;
3597 it = ELM_GEN_ITEM_FROM_INLIST(data);
3598 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
3599 return it->wd->item_compare_cb(it, item1);
3603 _elm_genlist_item_list_compare(const void *data, const void *data1)
3605 const Elm_Gen_Item *it = data;
3606 const Elm_Gen_Item *item1 = data1;
3607 return it->wd->item_compare_cb(it, item1);
3611 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
3616 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3617 _item_block_del(it);
3619 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3620 it->item->rel = after;
3621 it->item->rel->relcount++;
3622 it->item->before = EINA_FALSE;
3623 if (after->item->group_item) it->item->group_item = after->item->group_item;
3624 _item_queue(it->wd, it, NULL);
3626 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3630 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
3633 if (!before) return;
3635 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3636 _item_block_del(it);
3637 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
3638 it->item->rel = before;
3639 it->item->rel->relcount++;
3640 it->item->before = EINA_TRUE;
3641 if (before->item->group_item) it->item->group_item = before->item->group_item;
3642 _item_queue(it->wd, it, NULL);
3644 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3648 elm_genlist_item_append(Evas_Object *obj,
3649 const Elm_Genlist_Item_Class *itc,
3651 Elm_Gen_Item *parent,
3652 Elm_Genlist_Item_Flags flags,
3654 const void *func_data)
3656 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3657 Widget_Data *wd = elm_widget_data_get(obj);
3658 if (!wd) return NULL;
3659 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3661 if (!it) return NULL;
3665 wd->group_items = eina_list_append(wd->group_items, it);
3666 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
3667 it->item->rel = NULL;
3671 Elm_Gen_Item *it2 = NULL;
3672 Eina_List *ll = eina_list_last(it->parent->item->items);
3673 if (ll) it2 = ll->data;
3674 it->parent->item->items = eina_list_append(it->parent->item->items, it);
3675 if (!it2) it2 = it->parent;
3677 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3678 EINA_INLIST_GET(it2));
3679 it->item->rel = it2;
3680 it->item->rel->relcount++;
3682 it->item->before = EINA_FALSE;
3683 _item_queue(wd, it, NULL);
3688 elm_genlist_item_prepend(Evas_Object *obj,
3689 const Elm_Genlist_Item_Class *itc,
3691 Elm_Gen_Item *parent,
3692 Elm_Genlist_Item_Flags flags,
3694 const void *func_data)
3696 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3697 Widget_Data *wd = elm_widget_data_get(obj);
3698 if (!wd) return NULL;
3699 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3701 if (!it) return NULL;
3705 wd->group_items = eina_list_prepend(wd->group_items, it);
3706 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
3707 it->item->rel = NULL;
3711 Elm_Gen_Item *it2 = NULL;
3712 Eina_List *ll = it->parent->item->items;
3713 if (ll) it2 = ll->data;
3714 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
3715 if (!it2) it2 = it->parent;
3717 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3718 EINA_INLIST_GET(it2));
3719 it->item->rel = it2;
3720 it->item->rel->relcount++;
3722 it->item->before = EINA_TRUE;
3723 _item_queue(wd, it, NULL);
3728 elm_genlist_item_insert_after(Evas_Object *obj,
3729 const Elm_Genlist_Item_Class *itc,
3731 Elm_Gen_Item *parent,
3732 Elm_Gen_Item *after,
3733 Elm_Genlist_Item_Flags flags,
3735 const void *func_data)
3737 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3738 EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3739 Widget_Data *wd = elm_widget_data_get(obj);
3740 if (!wd) return NULL;
3741 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
3742 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3744 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3746 if (!it) return NULL;
3751 wd->group_items = eina_list_append_relative(wd->group_items, it,
3756 it->parent->item->items = eina_list_append_relative(it->parent->item->items, it,
3759 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3760 EINA_INLIST_GET(after));
3761 it->item->rel = after;
3762 it->item->rel->relcount++;
3763 it->item->before = EINA_FALSE;
3764 _item_queue(wd, it, NULL);
3769 elm_genlist_item_insert_before(Evas_Object *obj,
3770 const Elm_Genlist_Item_Class *itc,
3772 Elm_Gen_Item *parent,
3773 Elm_Gen_Item *before,
3774 Elm_Genlist_Item_Flags flags,
3776 const void *func_data)
3778 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3779 EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
3780 Widget_Data *wd = elm_widget_data_get(obj);
3781 if (!wd) return NULL;
3782 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
3783 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3785 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3787 if (!it) return NULL;
3790 if (it->group && before->group)
3791 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
3796 it->parent->item->items = eina_list_prepend_relative(it->parent->item->items, it,
3799 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3800 EINA_INLIST_GET(before));
3801 it->item->rel = before;
3802 it->item->rel->relcount++;
3803 it->item->before = EINA_TRUE;
3804 _item_queue(wd, it, NULL);
3809 elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
3810 const Elm_Genlist_Item_Class *itc,
3812 Elm_Gen_Item *parent,
3813 Elm_Genlist_Item_Flags flags,
3814 Eina_Compare_Cb comp,
3816 const void *func_data)
3818 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3819 Widget_Data *wd = elm_widget_data_get(obj);
3820 if (!wd) return NULL;
3821 Elm_Gen_Item *rel = NULL;
3822 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3824 if (!it) return NULL;
3826 wd->item_compare_cb = comp;
3833 l = eina_list_search_sorted_near_list(it->parent->item->items,
3834 _elm_genlist_item_list_compare, it,
3837 rel = eina_list_data_get(l);
3841 if (cmp_result >= 0)
3843 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
3844 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3845 it->item->before = EINA_FALSE;
3847 else if (cmp_result < 0)
3849 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
3850 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3851 it->item->before = EINA_TRUE;
3858 wd->state = eina_inlist_sorted_state_new();
3859 eina_inlist_sorted_state_init(wd->state, wd->items);
3860 wd->requeued = EINA_FALSE;
3864 wd->group_items = eina_list_append(wd->group_items, it);
3866 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
3867 _elm_genlist_item_compare, wd->state);
3869 if (EINA_INLIST_GET(it)->next)
3871 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3872 it->item->before = EINA_TRUE;
3874 else if (EINA_INLIST_GET(it)->prev)
3876 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3877 it->item->before = EINA_FALSE;
3883 it->item->rel = rel;
3884 it->item->rel->relcount++;
3887 _item_queue(wd, it, _elm_genlist_item_list_compare);
3893 elm_genlist_item_sorted_insert(Evas_Object *obj,
3894 const Elm_Genlist_Item_Class *itc,
3896 Elm_Gen_Item *parent,
3897 Elm_Genlist_Item_Flags flags,
3898 Eina_Compare_Cb comp,
3900 const void *func_data)
3902 Widget_Data *wd = elm_widget_data_get(obj);
3903 wd->item_compare_data_cb = comp;
3905 return elm_genlist_item_direct_sorted_insert(obj, itc, data, parent, flags,
3906 _elm_genlist_item_compare_data, func, func_data);
3910 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
3912 Eina_Inlist *next, *l;
3914 ELM_CHECK_WIDTYPE(obj, widtype);
3915 Widget_Data *wd = elm_widget_data_get(obj);
3918 if (!standby) wd->generation++;
3922 eina_inlist_sorted_state_free(wd->state);
3926 if (wd->walking > 0)
3931 evas_event_freeze(evas_object_evas_get(wd->obj));
3932 for (l = wd->items, next = l ? l->next : NULL;
3934 l = next, next = next ? next->next : NULL)
3936 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
3938 if (it->generation < wd->generation)
3940 Elm_Gen_Item *itn = NULL;
3942 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
3943 if (itn) itn->walking++; /* prevent early death of subitem */
3945 if (itn) itn->walking--;
3949 wd->pan_changed = EINA_TRUE;
3952 ecore_job_del(wd->calc_job);
3953 wd->calc_job = NULL;
3955 if (wd->selected) wd->selected = eina_list_free(wd->selected);
3956 if (wd->clear_cb) wd->clear_cb(wd);
3964 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
3965 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3967 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
3968 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
3969 evas_event_thaw(evas_object_evas_get(wd->obj));
3970 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3974 elm_genlist_clear(Evas_Object *obj)
3976 _elm_genlist_clear(obj, EINA_FALSE);
3980 elm_genlist_multi_select_set(Evas_Object *obj,
3983 ELM_CHECK_WIDTYPE(obj, widtype);
3984 Widget_Data *wd = elm_widget_data_get(obj);
3990 elm_genlist_multi_select_get(const Evas_Object *obj)
3992 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3993 Widget_Data *wd = elm_widget_data_get(obj);
3994 if (!wd) return EINA_FALSE;
3999 elm_genlist_selected_item_get(const Evas_Object *obj)
4001 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4002 Widget_Data *wd = elm_widget_data_get(obj);
4003 if (!wd) return NULL;
4004 if (wd->selected) return wd->selected->data;
4008 EAPI const Eina_List *
4009 elm_genlist_selected_items_get(const Evas_Object *obj)
4011 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4012 Widget_Data *wd = elm_widget_data_get(obj);
4013 if (!wd) return NULL;
4014 return wd->selected;
4018 elm_genlist_realized_items_get(const Evas_Object *obj)
4020 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4021 Widget_Data *wd = elm_widget_data_get(obj);
4022 Eina_List *list = NULL;
4024 Eina_Bool done = EINA_FALSE;
4025 if (!wd) return NULL;
4026 EINA_INLIST_FOREACH(wd->blocks, itb)
4034 EINA_LIST_FOREACH(itb->items, l, it)
4036 if (it->realized) list = eina_list_append(list, it);
4048 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4053 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4054 Widget_Data *wd = elm_widget_data_get(obj);
4055 Evas_Coord ox, oy, ow, oh;
4058 if (!wd) return NULL;
4059 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4061 EINA_INLIST_FOREACH(wd->blocks, itb)
4066 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4067 oy + itb->y - itb->wd->pan_y,
4068 itb->w, itb->h, x, y, 1, 1))
4070 EINA_LIST_FOREACH(itb->items, l, it)
4072 Evas_Coord itx, ity;
4074 itx = ox + itb->x + it->x - itb->wd->pan_x;
4075 ity = oy + itb->y + it->y - itb->wd->pan_y;
4076 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4080 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4081 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4087 lasty = ity + it->item->h;
4092 if (y > lasty) *posret = 1;
4099 elm_genlist_first_item_get(const Evas_Object *obj)
4101 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4102 Widget_Data *wd = elm_widget_data_get(obj);
4103 if (!wd) return NULL;
4104 if (!wd->items) return NULL;
4105 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4106 while ((it) && (it->generation < wd->generation))
4107 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4112 elm_genlist_last_item_get(const Evas_Object *obj)
4114 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4115 Widget_Data *wd = elm_widget_data_get(obj);
4116 if (!wd) return NULL;
4117 if (!wd->items) return NULL;
4118 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4119 while ((it) && (it->generation < wd->generation))
4120 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4125 elm_genlist_item_next_get(const Elm_Gen_Item *it)
4127 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4130 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4131 if ((it) && (it->generation == it->wd->generation)) break;
4133 return (Elm_Gen_Item *)it;
4137 elm_genlist_item_prev_get(const Elm_Gen_Item *it)
4139 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4142 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4143 if ((it) && (it->generation == it->wd->generation)) break;
4145 return (Elm_Gen_Item *)it;
4149 elm_genlist_item_genlist_get(const Elm_Gen_Item *it)
4151 return _elm_genlist_item_widget_get(it);
4155 elm_genlist_item_parent_get(const Elm_Gen_Item *it)
4157 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4162 elm_genlist_item_subitems_clear(Elm_Gen_Item *it)
4164 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4165 Eina_List *tl = NULL, *l;
4168 EINA_LIST_FOREACH(it->item->items, l, it2)
4169 tl = eina_list_append(tl, it2);
4170 EINA_LIST_FREE(tl, it2)
4171 elm_genlist_item_del(it2);
4175 elm_genlist_item_selected_set(Elm_Gen_Item *it,
4178 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4179 Widget_Data *wd = it->wd;
4181 if ((it->generation < wd->generation) || (it->disabled)) return;
4182 selected = !!selected;
4183 if (it->selected == selected) return;
4189 while (wd->selected)
4191 if (it->unhighlight_cb) it->unhighlight_cb(wd->selected->data);
4192 it->unsel_cb(wd->selected->data);
4195 it->highlight_cb(it);
4199 if (it->unhighlight_cb) it->unhighlight_cb(it);
4204 elm_genlist_item_selected_get(const Elm_Gen_Item *it)
4206 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4207 return it->selected;
4211 elm_genlist_item_expanded_set(Elm_Gen_Item *it,
4214 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4215 if (it->item->expanded == expanded) return;
4216 it->item->expanded = expanded;
4217 it->wd->expanded_item = it;
4218 if (it->item->expanded)
4221 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
4222 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
4223 it->wd->auto_scroll_enabled = EINA_TRUE;
4228 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
4229 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
4230 it->wd->auto_scroll_enabled = EINA_FALSE;
4235 elm_genlist_item_expanded_get(const Elm_Gen_Item *it)
4237 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4238 return it->item->expanded;
4242 elm_genlist_item_expanded_depth_get(const Elm_Gen_Item *it)
4244 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, 0);
4245 return it->item->expanded_depth;
4249 elm_genlist_item_disabled_set(Elm_Gen_Item *it,
4252 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4255 if (it->disabled == disabled) return;
4256 if (it->generation < it->wd->generation) return;
4257 it->disabled = !!disabled;
4259 elm_genlist_item_selected_set(it, EINA_FALSE);
4263 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4265 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
4266 EINA_LIST_FOREACH(it->content_objs, l, obj)
4267 elm_widget_disabled_set(obj, disabled);
4272 elm_genlist_item_disabled_get(const Elm_Gen_Item *it)
4274 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4275 if (it->generation < it->wd->generation) return EINA_FALSE;
4276 return it->disabled;
4280 elm_genlist_item_display_only_set(Elm_Gen_Item *it,
4281 Eina_Bool display_only)
4283 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4284 if (it->display_only == display_only) return;
4285 if (it->generation < it->wd->generation) return;
4286 it->display_only = display_only;
4287 it->item->mincalcd = EINA_FALSE;
4288 it->item->updateme = EINA_TRUE;
4289 if (it->item->block) it->item->block->updateme = EINA_TRUE;
4290 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4291 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4295 elm_genlist_item_display_only_get(const Elm_Gen_Item *it)
4297 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4298 if (it->generation < it->wd->generation) return EINA_FALSE;
4299 return it->display_only;
4303 elm_genlist_item_show(Elm_Gen_Item *it)
4305 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4306 Evas_Coord gith = 0;
4307 if (it->generation < it->wd->generation) return;
4308 if ((it->item->queued) || (!it->item->mincalcd))
4310 it->wd->show_item = it;
4311 it->wd->bring_in = EINA_FALSE;
4312 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
4313 it->item->showme = EINA_TRUE;
4316 if (it->wd->show_item)
4318 it->wd->show_item->item->showme = EINA_FALSE;
4319 it->wd->show_item = NULL;
4321 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4322 gith = it->item->group_item->item->h;
4323 elm_smart_scroller_child_region_show(it->wd->scr,
4324 it->x + it->item->block->x,
4325 it->y + it->item->block->y - gith,
4326 it->item->block->w, it->item->h);
4330 elm_genlist_item_promote(Elm_Gen_Item *it)
4332 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4333 if (it->generation < it->wd->generation) return;
4334 _item_move_before(it, elm_genlist_first_item_get(WIDGET(it)));
4338 elm_genlist_item_demote(Elm_Gen_Item *it)
4340 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4341 if (it->generation < it->wd->generation) return;
4342 _item_move_after(it, elm_genlist_last_item_get(WIDGET(it)));
4346 elm_genlist_item_bring_in(Elm_Gen_Item *it)
4348 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4349 Evas_Coord gith = 0;
4350 if (it->generation < it->wd->generation) return;
4351 if ((it->item->queued) || (!it->item->mincalcd))
4353 it->wd->show_item = it;
4354 it->wd->bring_in = EINA_TRUE;
4355 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
4356 it->item->showme = EINA_TRUE;
4359 if (it->wd->show_item)
4361 it->wd->show_item->item->showme = EINA_FALSE;
4362 it->wd->show_item = NULL;
4364 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4365 gith = it->item->group_item->item->h;
4366 elm_smart_scroller_region_bring_in(it->wd->scr,
4367 it->x + it->item->block->x,
4368 it->y + it->item->block->y - gith,
4369 it->item->block->w, it->item->h);
4373 elm_genlist_item_top_show(Elm_Gen_Item *it)
4375 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4377 Evas_Coord gith = 0;
4379 if (it->generation < it->wd->generation) return;
4380 if ((it->item->queued) || (!it->item->mincalcd))
4382 it->wd->show_item = it;
4383 it->wd->bring_in = EINA_FALSE;
4384 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
4385 it->item->showme = EINA_TRUE;
4388 if (it->wd->show_item)
4390 it->wd->show_item->item->showme = EINA_FALSE;
4391 it->wd->show_item = NULL;
4393 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4394 if (it->item->group_item) gith = it->item->group_item->item->h;
4395 elm_smart_scroller_child_region_show(it->wd->scr,
4396 it->x + it->item->block->x,
4397 it->y + it->item->block->y - gith,
4398 it->item->block->w, oh);
4402 elm_genlist_item_top_bring_in(Elm_Gen_Item *it)
4404 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4406 Evas_Coord gith = 0;
4408 if (it->generation < it->wd->generation) return;
4409 if ((it->item->queued) || (!it->item->mincalcd))
4411 it->wd->show_item = it;
4412 it->wd->bring_in = EINA_TRUE;
4413 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
4414 it->item->showme = EINA_TRUE;
4417 if (it->wd->show_item)
4419 it->wd->show_item->item->showme = EINA_FALSE;
4420 it->wd->show_item = NULL;
4422 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4423 if (it->item->group_item) gith = it->item->group_item->item->h;
4424 elm_smart_scroller_region_bring_in(it->wd->scr,
4425 it->x + it->item->block->x,
4426 it->y + it->item->block->y - gith,
4427 it->item->block->w, oh);
4431 elm_genlist_item_middle_show(Elm_Gen_Item *it)
4433 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4436 if (it->generation < it->wd->generation) return;
4437 if ((it->item->queued) || (!it->item->mincalcd))
4439 it->wd->show_item = it;
4440 it->wd->bring_in = EINA_FALSE;
4441 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE;
4442 it->item->showme = EINA_TRUE;
4445 if (it->wd->show_item)
4447 it->wd->show_item->item->showme = EINA_FALSE;
4448 it->wd->show_item = NULL;
4450 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4451 elm_smart_scroller_child_region_show(it->wd->scr,
4452 it->x + it->item->block->x,
4453 it->y + it->item->block->y - oh / 2 +
4454 it->item->h / 2, it->item->block->w, oh);
4458 elm_genlist_item_middle_bring_in(Elm_Gen_Item *it)
4460 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4463 if (it->generation < it->wd->generation) return;
4464 if ((it->item->queued) || (!it->item->mincalcd))
4466 it->wd->show_item = it;
4467 it->wd->bring_in = EINA_TRUE;
4468 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE;
4469 it->item->showme = EINA_TRUE;
4472 if (it->wd->show_item)
4474 it->wd->show_item->item->showme = EINA_FALSE;
4475 it->wd->show_item = NULL;
4477 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4478 elm_smart_scroller_region_bring_in(it->wd->scr,
4479 it->x + it->item->block->x,
4480 it->y + it->item->block->y - oh / 2 + it->item->h / 2,
4481 it->item->block->w, oh);
4485 elm_genlist_item_del(Elm_Gen_Item *it)
4487 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4488 if ((it->relcount > 0) || (it->walking > 0))
4490 elm_genlist_item_subitems_clear(it);
4491 if (it->wd->show_item == it) it->wd->show_item = NULL;
4492 _elm_genlist_item_del_notserious(it);
4493 if (it->item->block)
4495 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
4496 it->item->block->changed = EINA_TRUE;
4497 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
4498 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
4502 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
4511 elm_genlist_item_data_set(Elm_Gen_Item *it,
4514 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4515 elm_widget_item_data_set(it, data);
4519 elm_genlist_item_data_get(const Elm_Gen_Item *it)
4521 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4522 return elm_widget_item_data_get(it);
4526 elm_genlist_item_icons_orphan(Elm_Gen_Item *it)
4528 elm_genlist_item_contents_orphan(it);
4532 elm_genlist_item_contents_orphan(Elm_Gen_Item *it)
4534 Evas_Object *content;
4535 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4536 EINA_LIST_FREE(it->content_objs, content)
4538 elm_widget_sub_object_del(WIDGET(it), content);
4539 evas_object_smart_member_del(content);
4540 evas_object_hide(content);
4544 EAPI const Evas_Object *
4545 elm_genlist_item_object_get(const Elm_Gen_Item *it)
4547 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4552 elm_genlist_item_update(Elm_Gen_Item *it)
4554 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4555 if (!it->item->block) return;
4556 if (it->generation < it->wd->generation) return;
4557 it->item->mincalcd = EINA_FALSE;
4558 it->item->updateme = EINA_TRUE;
4559 it->item->block->updateme = EINA_TRUE;
4560 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4561 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4565 elm_genlist_item_fields_update(Elm_Genlist_Item *it,
4567 Elm_Genlist_Item_Field_Flags itf)
4569 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4570 if (!it->item->block) return;
4571 if (it->generation < it->wd->generation) return;
4573 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_LABEL))
4574 _item_text_realize(it, it->base.view, &it->texts, parts);
4575 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
4577 it->content_objs = _item_content_unrealize(it, it->base.view,
4578 &it->contents, parts);
4579 it->content_objs = _item_content_realize(it, it->base.view,
4580 &it->contents, parts);
4582 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
4583 _item_state_realize(it, it->base.view, &it->states, parts);
4587 elm_genlist_item_item_class_update(Elm_Gen_Item *it,
4588 const Elm_Genlist_Item_Class *itc)
4590 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4591 if (!it->item->block) return;
4592 EINA_SAFETY_ON_NULL_RETURN(itc);
4593 if (it->generation < it->wd->generation) return;
4595 it->item->nocache = EINA_TRUE;
4596 elm_genlist_item_update(it);
4599 EAPI const Elm_Genlist_Item_Class *
4600 elm_genlist_item_item_class_get(const Elm_Gen_Item *it)
4602 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4603 if (it->generation < it->wd->generation) return NULL;
4607 static Evas_Object *
4608 _elm_genlist_item_label_create(void *data,
4609 Evas_Object *obj __UNUSED__,
4610 Evas_Object *tooltip,
4611 void *it __UNUSED__)
4613 Evas_Object *label = elm_label_add(tooltip);
4616 elm_object_style_set(label, "tooltip");
4617 elm_object_text_set(label, data);
4622 _elm_genlist_item_label_del_cb(void *data,
4623 Evas_Object *obj __UNUSED__,
4624 void *event_info __UNUSED__)
4626 eina_stringshare_del(data);
4630 elm_genlist_item_tooltip_text_set(Elm_Gen_Item *it,
4633 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4634 text = eina_stringshare_add(text);
4635 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
4637 _elm_genlist_item_label_del_cb);
4641 elm_genlist_item_tooltip_content_cb_set(Elm_Gen_Item *it,
4642 Elm_Tooltip_Item_Content_Cb func,
4644 Evas_Smart_Cb del_cb)
4646 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, error);
4648 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4651 if (it->tooltip.del_cb)
4652 it->tooltip.del_cb((void *)it->tooltip.data,
4655 it->tooltip.content_cb = func;
4656 it->tooltip.data = data;
4657 it->tooltip.del_cb = del_cb;
4661 elm_widget_item_tooltip_content_cb_set(it,
4662 it->tooltip.content_cb,
4663 it->tooltip.data, NULL);
4664 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4665 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
4671 if (del_cb) del_cb((void *)data, NULL, NULL);
4675 elm_genlist_item_tooltip_unset(Elm_Gen_Item *it)
4677 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4678 if ((VIEW(it)) && (it->tooltip.content_cb))
4679 elm_widget_item_tooltip_unset(it);
4681 if (it->tooltip.del_cb)
4682 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4683 it->tooltip.del_cb = NULL;
4684 it->tooltip.content_cb = NULL;
4685 it->tooltip.data = NULL;
4686 it->tooltip.free_size = EINA_FALSE;
4687 if (it->tooltip.style)
4688 elm_genlist_item_tooltip_style_set(it, NULL);
4692 elm_genlist_item_tooltip_style_set(Elm_Gen_Item *it,
4695 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4696 eina_stringshare_replace(&it->tooltip.style, style);
4697 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4701 elm_genlist_item_tooltip_style_get(const Elm_Gen_Item *it)
4703 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4704 return it->tooltip.style;
4708 elm_genlist_item_tooltip_window_mode_set(Elm_Gen_Item *it, Eina_Bool disable)
4710 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4711 it->tooltip.free_size = disable;
4712 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
4717 elm_genlist_item_tooltip_window_mode_get(const Elm_Gen_Item *it)
4719 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4720 return it->tooltip.free_size;
4724 elm_genlist_item_cursor_set(Elm_Gen_Item *it,
4727 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4728 eina_stringshare_replace(&it->mouse_cursor, cursor);
4729 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4733 elm_genlist_item_cursor_get(const Elm_Gen_Item *it)
4735 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4736 return elm_widget_item_cursor_get(it);
4740 elm_genlist_item_cursor_unset(Elm_Gen_Item *it)
4742 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4743 if (!it->mouse_cursor)
4747 elm_widget_item_cursor_unset(it);
4749 eina_stringshare_del(it->mouse_cursor);
4750 it->mouse_cursor = NULL;
4754 elm_genlist_item_cursor_style_set(Elm_Gen_Item *it,
4757 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4758 elm_widget_item_cursor_style_set(it, style);
4762 elm_genlist_item_cursor_style_get(const Elm_Gen_Item *it)
4764 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4765 return elm_widget_item_cursor_style_get(it);
4769 elm_genlist_item_cursor_engine_only_set(Elm_Gen_Item *it,
4770 Eina_Bool engine_only)
4772 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4773 elm_widget_item_cursor_engine_only_set(it, engine_only);
4777 elm_genlist_item_cursor_engine_only_get(const Elm_Gen_Item *it)
4779 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4780 return elm_widget_item_cursor_engine_only_get(it);
4784 elm_genlist_horizontal_set(Evas_Object *obj,
4787 ELM_CHECK_WIDTYPE(obj, widtype);
4788 Widget_Data *wd = elm_widget_data_get(obj);
4790 if (wd->mode == mode) return;
4796 elm_genlist_horizontal_mode_set(Evas_Object *obj,
4799 elm_genlist_horizontal_set(obj, mode);
4803 elm_genlist_horizontal_get(const Evas_Object *obj)
4805 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4806 Widget_Data *wd = elm_widget_data_get(obj);
4807 if (!wd) return ELM_LIST_LAST;
4812 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4814 return elm_genlist_horizontal_get(obj);
4818 elm_genlist_always_select_mode_set(Evas_Object *obj,
4819 Eina_Bool always_select)
4821 ELM_CHECK_WIDTYPE(obj, widtype);
4822 Widget_Data *wd = elm_widget_data_get(obj);
4824 wd->always_select = always_select;
4828 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4830 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4831 Widget_Data *wd = elm_widget_data_get(obj);
4832 if (!wd) return EINA_FALSE;
4833 return wd->always_select;
4837 elm_genlist_no_select_mode_set(Evas_Object *obj,
4838 Eina_Bool no_select)
4840 ELM_CHECK_WIDTYPE(obj, widtype);
4841 Widget_Data *wd = elm_widget_data_get(obj);
4843 wd->no_select = no_select;
4847 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4849 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4850 Widget_Data *wd = elm_widget_data_get(obj);
4851 if (!wd) return EINA_FALSE;
4852 return wd->no_select;
4856 elm_genlist_compress_mode_set(Evas_Object *obj,
4859 ELM_CHECK_WIDTYPE(obj, widtype);
4860 Widget_Data *wd = elm_widget_data_get(obj);
4862 wd->compress = compress;
4863 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
4867 elm_genlist_compress_mode_get(const Evas_Object *obj)
4869 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4870 Widget_Data *wd = elm_widget_data_get(obj);
4871 if (!wd) return EINA_FALSE;
4872 return wd->compress;
4876 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
4877 Eina_Bool height_for_width)
4879 ELM_CHECK_WIDTYPE(obj, widtype);
4880 Widget_Data *wd = elm_widget_data_get(obj);
4882 wd->height_for_width = !!height_for_width;
4883 if (wd->height_for_width)
4885 elm_genlist_homogeneous_set(obj, EINA_FALSE);
4886 elm_genlist_compress_mode_set(obj, EINA_TRUE);
4891 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
4893 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4894 Widget_Data *wd = elm_widget_data_get(obj);
4895 if (!wd) return EINA_FALSE;
4896 return wd->height_for_width;
4900 elm_genlist_bounce_set(Evas_Object *obj,
4904 ELM_CHECK_WIDTYPE(obj, widtype);
4905 Widget_Data *wd = elm_widget_data_get(obj);
4907 elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
4908 wd->h_bounce = h_bounce;
4909 wd->v_bounce = v_bounce;
4913 elm_genlist_bounce_get(const Evas_Object *obj,
4914 Eina_Bool *h_bounce,
4915 Eina_Bool *v_bounce)
4917 ELM_CHECK_WIDTYPE(obj, widtype);
4918 Widget_Data *wd = elm_widget_data_get(obj);
4920 if (h_bounce) *h_bounce = wd->h_bounce;
4921 if (v_bounce) *v_bounce = wd->v_bounce;
4925 elm_genlist_homogeneous_set(Evas_Object *obj,
4926 Eina_Bool homogeneous)
4928 ELM_CHECK_WIDTYPE(obj, widtype);
4929 Widget_Data *wd = elm_widget_data_get(obj);
4931 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
4932 wd->homogeneous = homogeneous;
4936 elm_genlist_homogeneous_get(const Evas_Object *obj)
4938 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4939 Widget_Data *wd = elm_widget_data_get(obj);
4940 if (!wd) return EINA_FALSE;
4941 return wd->homogeneous;
4945 elm_genlist_block_count_set(Evas_Object *obj,
4948 ELM_CHECK_WIDTYPE(obj, widtype);
4949 Widget_Data *wd = elm_widget_data_get(obj);
4951 wd->max_items_per_block = n;
4952 wd->item_cache_max = wd->max_items_per_block * 2;
4953 _item_cache_clean(wd);
4957 elm_genlist_block_count_get(const Evas_Object *obj)
4959 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4960 Widget_Data *wd = elm_widget_data_get(obj);
4962 return wd->max_items_per_block;
4966 elm_genlist_longpress_timeout_set(Evas_Object *obj,
4969 ELM_CHECK_WIDTYPE(obj, widtype);
4970 Widget_Data *wd = elm_widget_data_get(obj);
4972 wd->longpress_timeout = timeout;
4976 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
4978 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4979 Widget_Data *wd = elm_widget_data_get(obj);
4981 return wd->longpress_timeout;
4985 elm_genlist_scroller_policy_set(Evas_Object *obj,
4986 Elm_Scroller_Policy policy_h,
4987 Elm_Scroller_Policy policy_v)
4989 ELM_CHECK_WIDTYPE(obj, widtype);
4990 Widget_Data *wd = elm_widget_data_get(obj);
4991 if ((!wd) || (!wd->scr)) return;
4992 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4993 (policy_v >= ELM_SCROLLER_POLICY_LAST))
4995 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
4999 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5000 Elm_Scroller_Policy *policy_h,
5001 Elm_Scroller_Policy *policy_v)
5003 ELM_CHECK_WIDTYPE(obj, widtype);
5004 Widget_Data *wd = elm_widget_data_get(obj);
5005 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5006 if ((!wd) || (!wd->scr)) return;
5007 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5008 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5009 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5013 elm_genlist_realized_items_update(Evas_Object *obj)
5015 ELM_CHECK_WIDTYPE(obj, widtype);
5017 Eina_List *list, *l;
5020 list = elm_genlist_realized_items_get(obj);
5021 EINA_LIST_FOREACH(list, l, it)
5022 elm_genlist_item_update(it);
5026 elm_genlist_item_mode_set(Elm_Gen_Item *it,
5027 const char *mode_type,
5030 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
5031 Widget_Data *wd = it->wd;
5036 if (!mode_type) return;
5037 if ((it->generation < it->wd->generation) || (it->disabled)) return;
5039 if ((wd->mode_item == it) &&
5040 (!strcmp(mode_type, wd->mode_type)) &&
5043 if (!wd->mode_item_style) return;
5044 it->mode_set = mode_set;
5048 EINA_LIST_FOREACH(wd->selected, l, it2)
5050 elm_genlist_item_selected_set(it2, EINA_FALSE);
5054 it2 = elm_genlist_selected_item_get(wd->obj);
5055 if ((it2) && (it2->realized))
5056 elm_genlist_item_selected_set(it2, EINA_FALSE);
5059 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
5061 ((it == wd->mode_item) && (!mode_set)))
5062 _item_mode_unset(wd);
5064 eina_stringshare_replace(&wd->mode_type, mode_type);
5065 if (mode_set) _item_mode_set(it);
5070 elm_genlist_mode_item_style_get(const Evas_Object *obj)
5072 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5073 Widget_Data *wd = elm_widget_data_get(obj);
5074 if (!wd) return NULL;
5075 return wd->mode_item_style;
5079 elm_genlist_mode_item_style_set(Evas_Object *obj, const char *style)
5081 ELM_CHECK_WIDTYPE(obj, widtype);
5082 Widget_Data *wd = elm_widget_data_get(obj);
5084 if ((style == wd->mode_item_style) || (style && wd->mode_item_style &&
5085 (!strcmp(style, wd->mode_item_style))))
5087 eina_stringshare_replace(&wd->mode_item_style, style);
5088 elm_genlist_realized_items_update(obj);
5092 elm_genlist_mode_get(const Evas_Object *obj)
5094 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5095 Widget_Data *wd = elm_widget_data_get(obj);
5096 if (!wd) return NULL;
5097 return wd->mode_type;
5100 EAPI const Elm_Gen_Item *
5101 elm_genlist_mode_item_get(const Evas_Object *obj)
5103 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5104 Widget_Data *wd = elm_widget_data_get(obj);
5105 if (!wd) return NULL;
5106 return wd->mode_item;
5110 elm_genlist_reorder_mode_set(Evas_Object *obj,
5111 Eina_Bool reorder_mode)
5113 ELM_CHECK_WIDTYPE(obj, widtype);
5114 Widget_Data *wd = elm_widget_data_get(obj);
5116 wd->reorder_mode = reorder_mode;
5120 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5122 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5123 Widget_Data *wd = elm_widget_data_get(obj);
5124 if (!wd) return EINA_FALSE;
5125 return wd->reorder_mode;
5128 /* for gengrid as of now */
5130 _elm_genlist_page_relative_set(Evas_Object *obj,
5134 Evas_Coord pagesize_h;
5135 Evas_Coord pagesize_v;
5137 ELM_CHECK_WIDTYPE(obj, widtype);
5138 Widget_Data *wd = elm_widget_data_get(obj);
5141 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5142 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5146 /* for gengrid as of now */
5148 _elm_genlist_page_relative_get(const Evas_Object *obj,
5152 ELM_CHECK_WIDTYPE(obj, widtype);
5153 Widget_Data *wd = elm_widget_data_get(obj);
5156 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5159 /* for gengrid as of now */
5161 _elm_genlist_page_size_set(Evas_Object *obj,
5162 Evas_Coord h_pagesize,
5163 Evas_Coord v_pagesize)
5168 ELM_CHECK_WIDTYPE(obj, widtype);
5169 Widget_Data *wd = elm_widget_data_get(obj);
5171 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5172 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5176 /* for gengrid as of now */
5178 _elm_genlist_current_page_get(const Evas_Object *obj,
5182 ELM_CHECK_WIDTYPE(obj, widtype);
5183 Widget_Data *wd = elm_widget_data_get(obj);
5186 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5189 /* for gengrid as of now */
5191 _elm_genlist_last_page_get(const Evas_Object *obj,
5195 ELM_CHECK_WIDTYPE(obj, widtype);
5196 Widget_Data *wd = elm_widget_data_get(obj);
5199 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5202 /* for gengrid as of now */
5204 _elm_genlist_page_show(const Evas_Object *obj,
5208 ELM_CHECK_WIDTYPE(obj, widtype);
5209 Widget_Data *wd = elm_widget_data_get(obj);
5212 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5215 /* for gengrid as of now */
5217 _elm_genlist_page_bring_in(const Evas_Object *obj,
5221 ELM_CHECK_WIDTYPE(obj, widtype);
5222 Widget_Data *wd = elm_widget_data_get(obj);
5225 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5229 _elm_genlist_item_widget_get(const Elm_Gen_Item *it)
5231 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
5236 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5239 Evas_Object *content;
5241 if (!it->realized) return;
5242 if (it->wd->reorder_it == it) return;
5243 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5245 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5248 ecore_timer_del(it->long_timer);
5249 it->long_timer = NULL;
5252 elm_widget_stringlist_free(it->texts);
5254 elm_widget_stringlist_free(it->contents);
5255 it->contents = NULL;
5256 elm_widget_stringlist_free(it->states);
5259 EINA_LIST_FREE(it->content_objs, content)
5260 evas_object_del(content);
5262 it->unrealize_cb(it);
5264 it->realized = EINA_FALSE;
5265 it->want_unrealize = EINA_FALSE;
5266 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5267 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5271 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5273 elm_widget_item_pre_notify_del(it);
5274 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5275 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5277 if (it->itc->func.del)
5278 it->itc->func.del((void *)it->base.data, WIDGET(it));
5282 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5284 _elm_genlist_item_del_notserious(it);
5285 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5286 if (it->tooltip.del_cb)
5287 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5288 it->wd->walking -= it->walking;
5289 if (it->long_timer) ecore_timer_del(it->long_timer);
5291 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5293 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5294 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5297 elm_widget_item_del(it);