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_labels, *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);
139 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
141 static const char SIG_ACTIVATED[] = "activated";
142 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
143 static const char SIG_SELECTED[] = "selected";
144 static const char SIG_UNSELECTED[] = "unselected";
145 static const char SIG_EXPANDED[] = "expanded";
146 static const char SIG_CONTRACTED[] = "contracted";
147 static const char SIG_EXPAND_REQUEST[] = "expand,request";
148 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
149 static const char SIG_REALIZED[] = "realized";
150 static const char SIG_UNREALIZED[] = "unrealized";
151 static const char SIG_DRAG_START_UP[] = "drag,start,up";
152 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
153 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
154 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
155 static const char SIG_DRAG_STOP[] = "drag,stop";
156 static const char SIG_DRAG[] = "drag";
157 static const char SIG_LONGPRESSED[] = "longpressed";
158 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
159 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
160 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
161 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
162 static const char SIG_EDGE_TOP[] = "edge,top";
163 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
164 static const char SIG_EDGE_LEFT[] = "edge,left";
165 static const char SIG_EDGE_RIGHT[] = "edge,right";
166 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
167 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
168 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
169 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
170 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
171 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
172 static const char SIG_SWIPE[] = "swipe";
173 static const char SIG_MOVED[] = "moved";
175 static const Evas_Smart_Cb_Description _signals[] = {
176 {SIG_CLICKED_DOUBLE, ""},
179 {SIG_UNSELECTED, ""},
181 {SIG_CONTRACTED, ""},
182 {SIG_EXPAND_REQUEST, ""},
183 {SIG_CONTRACT_REQUEST, ""},
185 {SIG_UNREALIZED, ""},
186 {SIG_DRAG_START_UP, ""},
187 {SIG_DRAG_START_DOWN, ""},
188 {SIG_DRAG_START_LEFT, ""},
189 {SIG_DRAG_START_RIGHT, ""},
192 {SIG_LONGPRESSED, ""},
193 {SIG_SCROLL_ANIM_START, ""},
194 {SIG_SCROLL_ANIM_STOP, ""},
195 {SIG_SCROLL_DRAG_START, ""},
196 {SIG_SCROLL_DRAG_STOP, ""},
198 {SIG_EDGE_BOTTOM, ""},
200 {SIG_EDGE_RIGHT, ""},
201 {SIG_MULTI_SWIPE_LEFT, ""},
202 {SIG_MULTI_SWIPE_RIGHT, ""},
203 {SIG_MULTI_SWIPE_UP, ""},
204 {SIG_MULTI_SWIPE_DOWN, ""},
205 {SIG_MULTI_PINCH_OUT, ""},
206 {SIG_MULTI_PINCH_IN, ""},
212 static Eina_Compare_Cb _elm_genlist_item_compare_cb;
213 static Eina_Compare_Cb _elm_genlist_item_compare_data_cb;
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_label_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, "labels"));
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,
1764 const char *treesize;
1766 int depth, tsize = 20;
1767 Item_Cache *itc = NULL;
1769 if (it->generation < it->wd->generation) return;
1770 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1773 if (it->item->order_num_in != in)
1775 it->item->order_num_in = in;
1776 _elm_genlist_item_odd_even_update(it);
1777 _elm_genlist_item_state_update(it, NULL);
1779 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1780 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1783 it->item->order_num_in = in;
1785 if (it->item->nocache)
1786 it->item->nocache = EINA_FALSE;
1788 itc = _item_cache_find(it);
1791 VIEW(it) = itc->base_view;
1792 itc->base_view = NULL;
1793 it->spacer = itc->spacer;
1798 const char *stacking_even;
1799 const char *stacking;
1801 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1802 edje_object_scale_set(VIEW(it),
1803 elm_widget_scale_get(WIDGET(it)) *
1804 _elm_config->scale);
1805 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
1806 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1808 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
1809 strncpy(buf, "tree", sizeof(buf));
1810 else strncpy(buf, "item", sizeof(buf));
1811 if (it->wd->compress)
1812 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1814 strncat(buf, "/", sizeof(buf) - strlen(buf));
1815 strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1817 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
1818 elm_widget_style_get(WIDGET(it)));
1820 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1821 if (!stacking_even) stacking_even = "above";
1822 it->item->stacking_even = !!strcmp("above", stacking_even);
1824 stacking = edje_object_data_get(VIEW(it), "stacking");
1825 if (!stacking) stacking = "yes";
1826 it->item->nostacking = !!strcmp("yes", stacking);
1828 edje_object_mirrored_set(VIEW(it),
1829 elm_widget_mirrored_get(WIDGET(it)));
1831 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1832 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1833 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1836 _elm_genlist_item_odd_even_update(it);
1838 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
1840 if (!it2->parent->group) depth += 1;
1842 it->item->expanded_depth = depth;
1843 treesize = edje_object_data_get(VIEW(it), "treesize");
1844 if (treesize) tsize = atoi(treesize);
1845 evas_object_size_hint_min_set(it->spacer,
1846 (depth * tsize) * _elm_config->scale, 1);
1847 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1850 edje_object_signal_callback_add(VIEW(it),
1851 "elm,action,expand,toggle",
1852 "elm", _signal_expand_toggle, it);
1853 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
1854 "elm", _signal_expand, it);
1855 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
1856 "elm", _signal_contract, it);
1857 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
1859 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
1861 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1863 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
1865 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
1867 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
1870 _elm_genlist_item_state_update(it, itc);
1873 if ((calc) && (it->wd->homogeneous) &&
1874 ((it->wd->item_width) ||
1875 ((it->wd->item_width) && (it->wd->group_item_width))))
1877 /* homogenous genlist shortcut */
1878 if (!it->item->mincalcd)
1882 it->item->w = it->item->minw = it->wd->group_item_width;
1883 it->item->h = it->item->minh = it->wd->group_item_height;
1887 it->item->w = it->item->minw = it->wd->item_width;
1888 it->item->h = it->item->minh = it->wd->item_height;
1890 it->item->mincalcd = EINA_TRUE;
1895 /* FIXME: If you see that assert, please notify us and we
1896 will clean our mess */
1897 assert(eina_list_count(it->content_objs) == 0);
1899 _item_label_realize(it, VIEW(it), &it->labels, NULL);
1900 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
1901 _item_state_realize(it, VIEW(it), &it->states, NULL);
1903 if (!it->item->mincalcd)
1905 Evas_Coord mw = -1, mh = -1;
1907 if (!it->display_only)
1908 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1909 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
1910 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
1912 if (!it->display_only)
1913 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1914 it->item->w = it->item->minw = mw;
1915 it->item->h = it->item->minh = mh;
1916 it->item->mincalcd = EINA_TRUE;
1918 if ((!it->wd->group_item_width) && (it->group))
1920 it->wd->group_item_width = mw;
1921 it->wd->group_item_height = mh;
1923 else if ((!it->wd->item_width) && (it->item->flags == ELM_GENLIST_ITEM_NONE))
1925 it->wd->item_width = mw;
1926 it->wd->item_height = mh;
1929 if (!calc) evas_object_show(VIEW(it));
1932 if (it->tooltip.content_cb)
1934 elm_widget_item_tooltip_content_cb_set(it,
1935 it->tooltip.content_cb,
1936 it->tooltip.data, NULL);
1937 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1938 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1941 if (it->mouse_cursor)
1942 elm_widget_item_cursor_set(it, it->mouse_cursor);
1944 it->realized = EINA_TRUE;
1945 it->want_unrealize = EINA_FALSE;
1947 if (itc) _item_cache_free(itc);
1948 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1949 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1951 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1952 edje_object_message_signal_process(VIEW(it));
1956 _item_unrealize_cb(Elm_Gen_Item *it)
1958 if (it->item->nocache)
1960 evas_object_del(VIEW(it));
1962 evas_object_del(it->spacer);
1967 edje_object_mirrored_set(VIEW(it),
1968 elm_widget_mirrored_get(WIDGET(it)));
1969 edje_object_scale_set(VIEW(it),
1970 elm_widget_scale_get(WIDGET(it))
1971 * _elm_config->scale);
1972 _item_cache_add(it);
1975 _mode_item_unrealize(it);
1977 it->realized = EINA_FALSE;
1978 it->want_unrealize = EINA_FALSE;
1982 _item_block_recalc(Item_Block *itb,
1988 Evas_Coord minw = 0, minh = 0;
1989 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
1992 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
1994 EINA_LIST_FOREACH(itb->items, l, it)
1996 if (it->generation < it->wd->generation) continue;
1997 showme |= it->item->showme;
2002 if (!it->item->mincalcd) changed = EINA_TRUE;
2005 _item_realize(it, in, EINA_TRUE);
2006 _elm_genlist_item_unrealize(it, EINA_TRUE);
2011 _item_realize(it, in, EINA_TRUE);
2012 _elm_genlist_item_unrealize(it, EINA_TRUE);
2016 _item_realize(it, in, EINA_FALSE);
2017 minh += it->item->minh;
2018 if (minw < it->item->minw) minw = it->item->minw;
2026 itb->changed = EINA_FALSE;
2027 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2028 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2033 _item_block_realize(Item_Block *itb)
2035 if (itb->realized) return;
2036 itb->realized = EINA_TRUE;
2037 itb->want_unrealize = EINA_FALSE;
2041 _item_block_unrealize(Item_Block *itb)
2045 Eina_Bool dragging = EINA_FALSE;
2047 if (!itb->realized) return;
2048 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2049 EINA_LIST_FOREACH(itb->items, l, it)
2055 dragging = EINA_TRUE;
2056 it->want_unrealize = EINA_TRUE;
2059 _elm_genlist_item_unrealize(it, EINA_FALSE);
2064 itb->realized = EINA_FALSE;
2065 itb->want_unrealize = EINA_TRUE;
2068 itb->want_unrealize = EINA_FALSE;
2069 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2070 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2074 _get_space_for_reorder_item(Elm_Gen_Item *it)
2076 Evas_Coord rox, roy, row, roh, oy, oh;
2077 Eina_Bool top = EINA_FALSE;
2078 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2079 if (!reorder_it) return 0;
2081 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2082 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2084 if ((it->wd->reorder_start_y < it->item->block->y) &&
2085 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2087 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2088 if (it->item->block->count == 1)
2089 it->wd->reorder_rel = it;
2091 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2092 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2094 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2097 it->item->block->reorder_offset = 0;
2099 it->item->scrl_y += it->item->block->reorder_offset;
2101 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2102 rox, roy + (roh / 2), row, 1));
2105 it->wd->reorder_rel = it;
2106 it->item->scrl_y += it->wd->reorder_it->item->h;
2107 return it->wd->reorder_it->item->h;
2114 _reorder_move_animator_cb(void *data)
2116 Elm_Gen_Item *it = data;
2117 Eina_Bool down = EINA_FALSE;
2119 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2121 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2123 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2126 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2127 if (diff > it->item->h) y = diff / 2;
2129 if (it->item->old_scrl_y < it->item->scrl_y)
2131 it->item->old_scrl_y += y;
2134 else if (it->item->old_scrl_y > it->item->scrl_y)
2136 it->item->old_scrl_y -= y;
2139 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2140 _group_items_recalc(it->wd);
2142 if ((it->wd->reorder_pan_move) ||
2143 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2144 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2146 it->item->old_scrl_y = it->item->scrl_y;
2147 it->item->move_effect_enabled = EINA_FALSE;
2148 it->wd->reorder_move_animator = NULL;
2149 return ECORE_CALLBACK_CANCEL;
2151 return ECORE_CALLBACK_RENEW;
2155 _item_position(Elm_Gen_Item *it,
2163 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2164 evas_object_resize(view, it->item->w, it->item->h);
2165 evas_object_move(view, it_x, it_y);
2166 evas_object_show(view);
2167 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2168 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2172 _item_block_position(Item_Block *itb,
2178 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2179 Eina_Bool vis = EINA_FALSE;
2181 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2182 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2183 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2185 EINA_LIST_FOREACH(itb->items, l, it)
2187 if (it->generation < it->wd->generation) continue;
2188 else if (it->wd->reorder_it == it) continue;
2191 it->item->w = itb->w;
2192 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2193 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2195 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2196 cvx, cvy, cvw, cvh));
2199 if ((itb->realized) && (!it->realized))
2201 if (vis) _item_realize(it, in, EINA_FALSE);
2207 if (it->wd->reorder_mode)
2208 y += _get_space_for_reorder_item(it);
2209 git = it->item->group_item;
2212 if (git->item->scrl_y < oy)
2213 git->item->scrl_y = oy;
2214 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2215 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2216 git->item->want_realize = EINA_TRUE;
2218 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2220 if (!it->item->move_effect_enabled)
2222 it->item->move_effect_enabled = EINA_TRUE;
2223 it->wd->reorder_move_animator =
2225 _reorder_move_animator_cb, it);
2228 if (!it->item->move_effect_enabled)
2230 if (it->item->mode_view)
2231 _item_position(it, it->item->mode_view, it->item->scrl_x,
2234 _item_position(it, VIEW(it), it->item->scrl_x,
2236 it->item->old_scrl_y = it->item->scrl_y;
2241 if (!it->dragging) _elm_genlist_item_unrealize(it, EINA_FALSE);
2248 if (vis) it->item->want_realize = EINA_TRUE;
2252 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2253 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2257 _group_items_recalc(void *data)
2259 Widget_Data *wd = data;
2263 evas_event_freeze(evas_object_evas_get(wd->obj));
2264 EINA_LIST_FOREACH(wd->group_items, l, git)
2266 if (git->item->want_realize)
2269 _item_realize(git, 0, EINA_FALSE);
2270 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2271 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2272 evas_object_show(VIEW(git));
2273 evas_object_raise(VIEW(git));
2275 else if (!git->item->want_realize && git->realized)
2278 _elm_genlist_item_unrealize(git, EINA_FALSE);
2281 evas_event_thaw(evas_object_evas_get(wd->obj));
2282 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2286 _must_recalc_idler(void *data)
2288 Widget_Data *wd = data;
2289 if (wd->calc_job) ecore_job_del(wd->calc_job);
2290 wd->calc_job = ecore_job_add(_calc_job, wd);
2291 wd->must_recalc_idler = NULL;
2292 return ECORE_CALLBACK_CANCEL;
2296 _calc_job(void *data)
2298 Widget_Data *wd = data;
2299 Item_Block *itb, *chb = NULL;
2300 Evas_Coord minw = -1, minh = 0, y = 0, ow;
2302 Eina_Bool minw_change = EINA_FALSE;
2303 Eina_Bool did_must_recalc = EINA_FALSE;
2306 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2310 evas_event_freeze(evas_object_evas_get(wd->obj));
2311 EINA_INLIST_FOREACH(wd->blocks, itb)
2313 Eina_Bool showme = EINA_FALSE;
2316 showme = itb->showme;
2317 itb->showme = EINA_FALSE;
2320 if (itb->realized) _item_block_unrealize(itb);
2322 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2324 if (itb->must_recalc)
2328 EINA_LIST_FOREACH(itb->items, l, it)
2329 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2330 itb->changed = EINA_TRUE;
2331 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2332 itb->must_recalc = EINA_FALSE;
2334 if (itb->realized) _item_block_unrealize(itb);
2335 showme = _item_block_recalc(itb, in, EINA_FALSE);
2341 if (minw == -1) minw = itb->minw;
2342 else if ((!itb->must_recalc) && (minw < itb->minw))
2345 minw_change = EINA_TRUE;
2351 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2353 wd->show_item->item->showme = EINA_FALSE;
2355 elm_smart_scroller_region_bring_in(wd->scr,
2357 wd->show_item->item->block->x,
2359 wd->show_item->item->block->y,
2360 wd->show_item->item->block->w,
2361 wd->show_item->item->h);
2363 elm_smart_scroller_child_region_show(wd->scr,
2365 wd->show_item->item->block->x,
2367 wd->show_item->item->block->y,
2368 wd->show_item->item->block->w,
2369 wd->show_item->item->h);
2370 wd->show_item = NULL;
2375 EINA_INLIST_FOREACH(wd->blocks, itb)
2381 if ((chb) && (EINA_INLIST_GET(chb)->next))
2383 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2385 if (itb->realized) _item_block_unrealize(itb);
2388 wd->realminw = minw;
2389 if (minw < wd->w) minw = wd->w;
2390 if ((minw != wd->minw) || (minh != wd->minh))
2394 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2395 _sizing_eval(wd->obj);
2396 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2401 it = wd->anchor_item;
2402 it_y = wd->anchor_y;
2403 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2404 it->item->block->y + it->y + it_y);
2405 wd->anchor_item = it;
2406 wd->anchor_y = it_y;
2409 if (did_must_recalc)
2411 if (!wd->must_recalc_idler)
2412 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2414 wd->calc_job = NULL;
2415 evas_object_smart_changed(wd->pan_smart);
2416 evas_event_thaw(evas_object_evas_get(wd->obj));
2417 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2421 _update_job(void *data)
2423 Widget_Data *wd = data;
2427 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2429 wd->update_job = NULL;
2432 evas_event_freeze(evas_object_evas_get(wd->obj));
2433 EINA_INLIST_FOREACH(wd->blocks, itb)
2435 Evas_Coord itminw, itminh;
2442 _item_block_position(itb, num);
2446 recalc = EINA_FALSE;
2447 EINA_LIST_FOREACH(itb->items, l2, it)
2449 if (it->item->updateme)
2451 itminw = it->item->minw;
2452 itminh = it->item->minh;
2454 it->item->updateme = EINA_FALSE;
2457 _elm_genlist_item_unrealize(it, EINA_FALSE);
2458 _item_realize(it, num, EINA_FALSE);
2459 position = EINA_TRUE;
2463 _item_realize(it, num, EINA_TRUE);
2464 _elm_genlist_item_unrealize(it, EINA_TRUE);
2466 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2471 itb->updateme = EINA_FALSE;
2474 position = EINA_TRUE;
2475 itb->changed = EINA_TRUE;
2476 _item_block_recalc(itb, num0, EINA_FALSE);
2477 _item_block_position(itb, num0);
2482 if (wd->calc_job) ecore_job_del(wd->calc_job);
2483 wd->calc_job = ecore_job_add(_calc_job, wd);
2485 evas_event_thaw(evas_object_evas_get(wd->obj));
2486 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2490 _pan_set(Evas_Object *obj,
2494 Pan *sd = evas_object_smart_data_get(obj);
2498 // Evas_Coord ow, oh;
2499 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2500 // ow = sd->wd->minw - ow;
2501 // if (ow < 0) ow = 0;
2502 // oh = sd->wd->minh - oh;
2503 // if (oh < 0) oh = 0;
2504 // if (x < 0) x = 0;
2505 // if (y < 0) y = 0;
2506 // if (x > ow) x = ow;
2507 // if (y > oh) y = oh;
2508 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2512 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2514 if ((itb->y + itb->h) > y)
2519 EINA_LIST_FOREACH(itb->items, l2, it)
2521 if ((itb->y + it->y) >= y)
2523 sd->wd->anchor_item = it;
2524 sd->wd->anchor_y = -(itb->y + it->y - y);
2531 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2535 _pan_get(Evas_Object *obj,
2539 Pan *sd = evas_object_smart_data_get(obj);
2542 if (x) *x = sd->wd->pan_x;
2543 if (y) *y = sd->wd->pan_y;
2547 _pan_max_get(Evas_Object *obj,
2551 Pan *sd = evas_object_smart_data_get(obj);
2555 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2556 ow = sd->wd->minw - ow;
2558 oh = sd->wd->minh - oh;
2565 _pan_min_get(Evas_Object *obj __UNUSED__,
2574 _pan_child_size_get(Evas_Object *obj,
2578 Pan *sd = evas_object_smart_data_get(obj);
2581 if (w) *w = sd->wd->minw;
2582 if (h) *h = sd->wd->minh;
2586 _pan_add(Evas_Object *obj)
2589 Evas_Object_Smart_Clipped_Data *cd;
2592 cd = evas_object_smart_data_get(obj);
2595 sd->__clipped_data = *cd;
2597 evas_object_smart_data_set(obj, sd);
2601 _pan_del(Evas_Object *obj)
2603 Pan *sd = evas_object_smart_data_get(obj);
2608 ecore_job_del(sd->resize_job);
2609 sd->resize_job = NULL;
2615 _pan_resize_job(void *data)
2619 _sizing_eval(sd->wd->obj);
2620 sd->resize_job = NULL;
2624 _pan_resize(Evas_Object *obj,
2628 Pan *sd = evas_object_smart_data_get(obj);
2632 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2633 if ((ow == w) && (oh == h)) return;
2634 if ((sd->wd->height_for_width) && (ow != w))
2637 if (sd->resize_job) ecore_job_del(sd->resize_job);
2638 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2640 sd->wd->pan_resized = EINA_TRUE;
2641 evas_object_smart_changed(obj);
2642 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2643 sd->wd->calc_job = NULL;
2645 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2646 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2651 _pan_calculate(Evas_Object *obj)
2653 Pan *sd = evas_object_smart_data_get(obj);
2655 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2661 evas_event_freeze(evas_object_evas_get(obj));
2663 if (sd->wd->pan_resized)
2666 sd->wd->pan_resized = EINA_FALSE;
2669 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2670 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2671 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2673 git->item->want_realize = EINA_FALSE;
2675 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2677 itb->w = sd->wd->minw;
2678 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2679 itb->y - sd->wd->pan_y + oy,
2681 cvx, cvy, cvw, cvh))
2683 if ((!itb->realized) || (itb->changed))
2684 _item_block_realize(itb);
2685 _item_block_position(itb, in);
2689 if (itb->realized) _item_block_unrealize(itb);
2693 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2694 _group_items_recalc(sd->wd);
2695 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2697 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2698 sd->wd->reorder_pan_move = EINA_TRUE;
2699 else sd->wd->reorder_pan_move = EINA_FALSE;
2700 evas_object_raise(sd->wd->VIEW(reorder_it));
2701 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2702 sd->wd->start_time = ecore_loop_time_get();
2704 _item_auto_scroll(sd->wd);
2705 evas_event_thaw(evas_object_evas_get(obj));
2706 evas_event_thaw_eval(evas_object_evas_get(obj));
2710 _pan_move(Evas_Object *obj,
2711 Evas_Coord x __UNUSED__,
2712 Evas_Coord y __UNUSED__)
2714 Pan *sd = evas_object_smart_data_get(obj);
2717 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2718 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2722 _hold_on(void *data __UNUSED__,
2724 void *event_info __UNUSED__)
2726 Widget_Data *wd = elm_widget_data_get(obj);
2728 elm_smart_scroller_hold_set(wd->scr, 1);
2732 _hold_off(void *data __UNUSED__,
2734 void *event_info __UNUSED__)
2736 Widget_Data *wd = elm_widget_data_get(obj);
2738 elm_smart_scroller_hold_set(wd->scr, 0);
2742 _freeze_on(void *data __UNUSED__,
2744 void *event_info __UNUSED__)
2746 Widget_Data *wd = elm_widget_data_get(obj);
2748 elm_smart_scroller_freeze_set(wd->scr, 1);
2752 _freeze_off(void *data __UNUSED__,
2754 void *event_info __UNUSED__)
2756 Widget_Data *wd = elm_widget_data_get(obj);
2758 elm_smart_scroller_freeze_set(wd->scr, 0);
2762 _scr_anim_start(void *data,
2763 Evas_Object *obj __UNUSED__,
2764 void *event_info __UNUSED__)
2766 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
2770 _scr_anim_stop(void *data,
2771 Evas_Object *obj __UNUSED__,
2772 void *event_info __UNUSED__)
2774 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
2778 _scr_drag_start(void *data,
2779 Evas_Object *obj __UNUSED__,
2780 void *event_info __UNUSED__)
2782 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
2786 _scr_drag_stop(void *data,
2787 Evas_Object *obj __UNUSED__,
2788 void *event_info __UNUSED__)
2790 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
2794 _edge_left(void *data,
2795 Evas_Object *scr __UNUSED__,
2796 void *event_info __UNUSED__)
2798 Evas_Object *obj = data;
2799 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2803 _edge_right(void *data,
2804 Evas_Object *scr __UNUSED__,
2805 void *event_info __UNUSED__)
2807 Evas_Object *obj = data;
2808 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2812 _edge_top(void *data,
2813 Evas_Object *scr __UNUSED__,
2814 void *event_info __UNUSED__)
2816 Evas_Object *obj = data;
2817 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2821 _edge_bottom(void *data,
2822 Evas_Object *scr __UNUSED__,
2823 void *event_info __UNUSED__)
2825 Evas_Object *obj = data;
2826 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2830 _mode_item_realize(Elm_Gen_Item *it)
2834 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
2836 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2837 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
2838 edje_object_scale_set(it->item->mode_view,
2839 elm_widget_scale_get(WIDGET(it)) *
2840 _elm_config->scale);
2841 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
2842 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
2844 strncpy(buf, "item", sizeof(buf));
2845 if (it->wd->compress)
2846 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
2848 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
2849 strncat(buf, "/", sizeof(buf) - strlen(buf));
2850 strncat(buf, it->wd->mode_item_style, sizeof(buf) - strlen(buf));
2852 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
2853 elm_widget_style_get(WIDGET(it)));
2854 edje_object_mirrored_set(it->item->mode_view,
2855 elm_widget_mirrored_get(WIDGET(it)));
2857 /* signal callback add */
2858 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
2860 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
2862 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
2865 /* text_get, content_get, state_get */
2866 /* FIXME: If you see that assert, please notify us and we
2867 will clean our mess */
2868 assert(eina_list_count(it->item->mode_content_objs) == 0);
2870 _item_label_realize(it, it->item->mode_view, &it->item->mode_labels, NULL);
2871 it->item->mode_content_objs =
2872 _item_content_realize(it, it->item->mode_view,
2873 &it->item->mode_contents, NULL);
2874 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
2876 edje_object_part_swallow(it->item->mode_view,
2877 edje_object_data_get(it->item->mode_view, "mode_part"),
2880 it->want_unrealize = EINA_FALSE;
2881 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2882 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2886 _mode_item_unrealize(Elm_Gen_Item *it)
2888 Widget_Data *wd = it->wd;
2889 Evas_Object *content;
2890 if (!it->item->mode_view) return;
2892 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2893 elm_widget_stringlist_free(it->item->mode_labels);
2894 it->item->mode_labels = NULL;
2895 elm_widget_stringlist_free(it->item->mode_contents);
2896 it->item->mode_contents = NULL;
2897 elm_widget_stringlist_free(it->item->mode_states);
2899 EINA_LIST_FREE(it->item->mode_content_objs, content)
2900 evas_object_del(content);
2902 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
2903 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
2904 evas_object_del(it->item->mode_view);
2905 it->item->mode_view = NULL;
2907 if (wd->mode_item == it)
2908 wd->mode_item = NULL;
2909 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2910 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2914 _item_mode_set(Elm_Gen_Item *it)
2917 Widget_Data *wd = it->wd;
2922 it->item->nocache = EINA_TRUE;
2924 if (wd->scr_hold_timer)
2926 ecore_timer_del(wd->scr_hold_timer);
2927 wd->scr_hold_timer = NULL;
2929 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
2930 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
2932 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2933 _mode_item_realize(it);
2934 if (it->item->group_item)
2935 evas_object_raise(it->item->VIEW(group_item));
2936 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
2937 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2938 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2940 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
2941 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2945 _item_mode_unset(Widget_Data *wd)
2948 if (!wd->mode_item) return;
2949 char buf[1024], buf2[1024];
2953 it->item->nocache = EINA_TRUE;
2955 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
2956 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
2958 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2959 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
2961 wd->mode_item = NULL;
2965 _item_auto_scroll(Widget_Data *wd)
2970 Evas_Coord ox, oy, ow, oh;
2972 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
2974 evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
2975 if (wd->expanded_item->item->scrl_y > (oh + oy) / 2)
2977 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
2978 elm_genlist_item_bring_in(it);
2980 wd->auto_scroll_enabled = EINA_FALSE;
2985 elm_genlist_add(Evas_Object *parent)
2990 Evas_Coord minw, minh;
2991 static Evas_Smart *smart = NULL;
2995 static Evas_Smart_Class sc;
2997 evas_object_smart_clipped_smart_set(&_pan_sc);
2999 sc.name = "elm_genlist_pan";
3000 sc.version = EVAS_SMART_CLASS_VERSION;
3003 sc.resize = _pan_resize;
3004 sc.move = _pan_move;
3005 sc.calculate = _pan_calculate;
3006 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3009 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3011 ELM_SET_WIDTYPE(widtype, "genlist");
3013 elm_widget_type_set(obj, "genlist");
3014 elm_widget_sub_object_add(parent, obj);
3015 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3016 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3017 elm_widget_data_set(obj, wd);
3018 elm_widget_del_hook_set(obj, _del_hook);
3019 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3020 elm_widget_theme_hook_set(obj, _theme_hook);
3021 elm_widget_can_focus_set(obj, EINA_TRUE);
3022 elm_widget_event_hook_set(obj, _event_hook);
3023 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3024 elm_widget_translate_hook_set(obj, _translate_hook);
3027 wd->scr = elm_smart_scroller_add(e);
3028 elm_smart_scroller_widget_set(wd->scr, obj);
3029 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3030 elm_widget_style_get(obj));
3031 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3032 _elm_config->thumbscroll_bounce_enable);
3033 elm_widget_resize_object_set(obj, wd->scr);
3035 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3036 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3037 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3038 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3039 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3040 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3041 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3042 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3045 wd->mode = ELM_LIST_SCROLL;
3046 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3047 wd->item_cache_max = wd->max_items_per_block * 2;
3048 wd->longpress_timeout = _elm_config->longpress_timeout;
3050 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3051 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3052 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3053 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3055 wd->pan_smart = evas_object_smart_add(e, smart);
3056 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3059 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3060 _pan_set, _pan_get, _pan_max_get,
3061 _pan_min_get, _pan_child_size_get);
3063 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3065 evas_object_size_hint_min_set(obj, minw, minh);
3067 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3069 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3075 _item_select(Elm_Gen_Item *it)
3077 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3080 it->selected = EINA_TRUE;
3081 it->wd->selected = eina_list_append(it->wd->selected, it);
3083 else if (!it->wd->always_select) return;
3085 evas_object_ref(WIDGET(it));
3088 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3089 if (it->generation == it->wd->generation)
3090 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3093 evas_object_unref(WIDGET(it));
3094 if ((it->wd->clear_me) && (!it->wd->walking))
3095 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3098 if ((!it->walking) && (it->generation < it->wd->generation))
3100 if (!it->relcount) it->del_cb(it);
3103 it->wd->last_selected_item = it;
3107 static Evas_Object *
3108 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3110 return edje_object_part_swallow_get(VIEW(it), part);
3114 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3116 edje_object_part_swallow(VIEW(it), part, content);
3119 static Evas_Object *
3120 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3124 obj = edje_object_part_swallow_get(VIEW(it), part);
3125 if (!obj) return NULL;
3126 edje_object_part_unswallow(VIEW(it), obj);
3131 _item_label_hook(Elm_Gen_Item *it, const char *part)
3133 if (!it->itc->func.text_get) return NULL;
3134 return edje_object_part_text_get(VIEW(it), part);
3138 _elm_genlist_item_new(Widget_Data *wd,
3139 const Elm_Gen_Item_Class *itc,
3141 Elm_Gen_Item *parent,
3143 const void *func_data)
3147 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3148 if (!it) return NULL;
3150 it->generation = wd->generation;
3152 it->base.data = data;
3153 it->parent = parent;
3154 it->func.func = func;
3155 it->func.data = func_data;
3156 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3157 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3158 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3160 it->sel_cb = (Ecore_Cb)_item_select;
3162 elm_widget_item_text_get_hook_set(it, _item_label_hook);
3166 static Elm_Gen_Item *
3167 _item_new(Widget_Data *wd,
3168 const Elm_Genlist_Item_Class *itc,
3170 Elm_Gen_Item *parent,
3171 Elm_Genlist_Item_Flags flags,
3173 const void *func_data)
3177 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3178 if (!it) return NULL;
3179 it->item = ELM_NEW(Elm_Gen_Item_Type);
3180 it->item->flags = flags;
3181 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3182 it->item->expanded_depth = 0;
3183 elm_widget_item_del_cb_set(it, _item_del_hook);
3184 ELM_GEN_ITEM_SETUP(it);
3187 if (it->parent->group)
3188 it->item->group_item = parent;
3189 else if (it->parent->item->group_item)
3190 it->item->group_item = it->parent->item->group_item;
3196 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3200 itb = calloc(1, sizeof(Item_Block));
3201 if (!itb) return NULL;
3204 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3206 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3211 _item_block_add(Widget_Data *wd,
3214 Item_Block *itb = NULL;
3221 itb = calloc(1, sizeof(Item_Block));
3222 if (!itb) return EINA_FALSE;
3224 if (!it->item->rel->item->block)
3227 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3228 itb->items = eina_list_append(itb->items, it);
3232 if (it->item->before)
3234 wd->blocks = eina_inlist_prepend_relative
3235 (wd->blocks, EINA_INLIST_GET(itb),
3236 EINA_INLIST_GET(it->item->rel->item->block));
3238 eina_list_prepend_relative(itb->items, it, it->item->rel);
3242 wd->blocks = eina_inlist_append_relative
3243 (wd->blocks, EINA_INLIST_GET(itb),
3244 EINA_INLIST_GET(it->item->rel->item->block));
3246 eina_list_append_relative(itb->items, it, it->item->rel);
3252 if (it->item->before)
3256 itb = (Item_Block *)(wd->blocks);
3257 if (itb->count >= wd->max_items_per_block)
3259 itb = _item_block_new(wd, EINA_TRUE);
3260 if (!itb) return EINA_FALSE;
3265 itb = _item_block_new(wd, EINA_TRUE);
3266 if (!itb) return EINA_FALSE;
3268 itb->items = eina_list_prepend(itb->items, it);
3274 itb = (Item_Block *)(wd->blocks->last);
3275 if (itb->count >= wd->max_items_per_block)
3277 itb = _item_block_new(wd, EINA_FALSE);
3278 if (!itb) return EINA_FALSE;
3283 itb = _item_block_new(wd, EINA_FALSE);
3284 if (!itb) return EINA_FALSE;
3286 itb->items = eina_list_append(itb->items, it);
3292 if (it->item->rel->item->queued)
3294 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3295 on sorted insertion order, so the queue is not always ordered like the item list.
3296 This lead to issue where we depend on a item that is not yet created. As a quick
3297 work around, we reschedule the calc of the item and stop reordering the list to
3298 prevent any nasty issue to show up here.
3300 wd->queue = eina_list_append(wd->queue, it);
3301 wd->requeue = EINA_TRUE;
3302 it->item->queued = EINA_TRUE;
3305 itb = it->item->rel->item->block;
3306 if (!itb) goto newblock;
3307 if (it->item->before)
3308 itb->items = eina_list_prepend_relative(itb->items, it, it->item->rel);
3310 itb->items = eina_list_append_relative(itb->items, it, it->item->rel);
3313 itb->changed = EINA_TRUE;
3314 it->item->block = itb;
3315 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3316 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3319 it->item->rel->relcount--;
3320 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3321 _item_del(it->item->rel);
3322 it->item->rel = NULL;
3324 if (itb->count > itb->wd->max_items_per_block)
3329 Eina_Bool done = EINA_FALSE;
3331 newc = itb->count / 2;
3333 if (EINA_INLIST_GET(itb)->prev)
3335 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3337 if (itbp->count + newc < wd->max_items_per_block / 2)
3339 /* moving items to previous block */
3340 while ((itb->count > newc) && (itb->items))
3342 it2 = eina_list_data_get(itb->items);
3343 itb->items = eina_list_remove_list(itb->items, itb->items);
3346 itbp->items = eina_list_append(itbp->items, it2);
3347 it2->item->block = itbp;
3355 if (!done && EINA_INLIST_GET(itb)->next)
3357 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3359 if (itbn->count + newc < wd->max_items_per_block / 2)
3361 /* moving items to next block */
3362 while ((itb->count > newc) && (itb->items))
3366 l = eina_list_last(itb->items);
3367 it2 = eina_list_data_get(l);
3368 itb->items = eina_list_remove_list(itb->items, l);
3371 itbn->items = eina_list_prepend(itbn->items, it2);
3372 it2->item->block = itbn;
3382 /* moving items to new block */
3383 itb2 = calloc(1, sizeof(Item_Block));
3384 if (!itb2) return EINA_FALSE;
3387 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3388 EINA_INLIST_GET(itb));
3389 itb2->changed = EINA_TRUE;
3390 while ((itb->count > newc) && (itb->items))
3394 l = eina_list_last(itb->items);
3396 itb->items = eina_list_remove_list(itb->items, l);
3399 itb2->items = eina_list_prepend(itb2->items, it2);
3400 it2->item->block = itb2;
3410 _queue_process(Widget_Data *wd)
3413 Eina_Bool showme = EINA_FALSE;
3416 t0 = ecore_loop_time_get();
3417 //evas_event_freeze(evas_object_evas_get(wd->obj));
3418 for (n = 0; (wd->queue) && (n < 128); n++)
3422 it = eina_list_data_get(wd->queue);
3423 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3424 it->item->queued = EINA_FALSE;
3425 if (!_item_block_add(wd, it)) continue;
3427 _item_block_realize(it->item->block);
3428 t = ecore_time_get();
3429 if (it->item->block->changed)
3431 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3432 it->item->block->changed = 0;
3434 if (showme) it->item->block->showme = EINA_TRUE;
3435 if (eina_inlist_count(wd->blocks) > 1)
3437 if ((t - t0) > (ecore_animator_frametime_get())) break;
3440 //evas_event_thaw(evas_object_evas_get(wd->obj));
3441 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3446 _idle_process(void *data, Eina_Bool *wakeup)
3448 Widget_Data *wd = data;
3451 //static double q_start = 0.0;
3452 //if (q_start == 0.0) q_start = ecore_time_get();
3454 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
3458 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
3460 return ECORE_CALLBACK_CANCEL;
3462 return ECORE_CALLBACK_RENEW;
3466 _item_idle_enterer(void *data)
3468 Widget_Data *wd = data;
3469 Eina_Bool wakeup = EINA_FALSE;
3470 Eina_Bool ok = _idle_process(data, &wakeup);
3475 if (wd->calc_job) ecore_job_del(wd->calc_job);
3476 wd->calc_job = ecore_job_add(_calc_job, wd);
3478 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
3483 _item_queue(Widget_Data *wd,
3487 if (it->item->queued) return;
3488 it->item->queued = EINA_TRUE;
3489 if (cb && !wd->requeue)
3490 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
3492 wd->queue = eina_list_append(wd->queue, it);
3493 // FIXME: why does a freeze then thaw here cause some genlist
3494 // elm_genlist_item_append() to be much much slower?
3495 // evas_event_freeze(evas_object_evas_get(wd->obj));
3496 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
3498 if (wd->queue_idle_enterer)
3500 ecore_idle_enterer_del(wd->queue_idle_enterer);
3501 wd->queue_idle_enterer = NULL;
3505 // evas_event_thaw(evas_object_evas_get(wd->obj));
3506 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3507 if (!wd->queue_idle_enterer)
3508 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
3512 _elm_genlist_item_compare_data(const void *data, const void *data1)
3514 const Elm_Gen_Item *it = data;
3515 const Elm_Gen_Item *item1 = data1;
3517 return _elm_genlist_item_compare_data_cb(it->base.data, item1->base.data);
3521 _elm_genlist_item_compare(const void *data, const void *data1)
3523 const Elm_Gen_Item *it, *item1;
3524 it = ELM_GEN_ITEM_FROM_INLIST(data);
3525 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
3526 return _elm_genlist_item_compare_cb(it, item1);
3530 _elm_genlist_item_list_compare(const void *data, const void *data1)
3532 const Elm_Gen_Item *it = data;
3533 const Elm_Gen_Item *item1 = data1;
3534 return _elm_genlist_item_compare_cb(it, item1);
3538 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
3543 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3544 _item_block_del(it);
3546 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3547 it->item->rel = after;
3548 it->item->rel->relcount++;
3549 it->item->before = EINA_FALSE;
3550 if (after->item->group_item) it->item->group_item = after->item->group_item;
3551 _item_queue(it->wd, it, NULL);
3553 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3557 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
3560 if (!before) return;
3562 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3563 _item_block_del(it);
3564 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
3565 it->item->rel = before;
3566 it->item->rel->relcount++;
3567 it->item->before = EINA_TRUE;
3568 if (before->item->group_item) it->item->group_item = before->item->group_item;
3569 _item_queue(it->wd, it, NULL);
3571 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3575 elm_genlist_item_append(Evas_Object *obj,
3576 const Elm_Genlist_Item_Class *itc,
3578 Elm_Gen_Item *parent,
3579 Elm_Genlist_Item_Flags flags,
3581 const void *func_data)
3583 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3584 Widget_Data *wd = elm_widget_data_get(obj);
3585 if (!wd) return NULL;
3586 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3588 if (!it) return NULL;
3592 wd->group_items = eina_list_append(wd->group_items, it);
3593 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
3594 it->item->rel = NULL;
3598 Elm_Gen_Item *it2 = NULL;
3599 Eina_List *ll = eina_list_last(it->parent->item->items);
3600 if (ll) it2 = ll->data;
3601 it->parent->item->items = eina_list_append(it->parent->item->items, it);
3602 if (!it2) it2 = it->parent;
3604 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3605 EINA_INLIST_GET(it2));
3606 it->item->rel = it2;
3607 it->item->rel->relcount++;
3609 it->item->before = EINA_FALSE;
3610 _item_queue(wd, it, NULL);
3615 elm_genlist_item_prepend(Evas_Object *obj,
3616 const Elm_Genlist_Item_Class *itc,
3618 Elm_Gen_Item *parent,
3619 Elm_Genlist_Item_Flags flags,
3621 const void *func_data)
3623 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3624 Widget_Data *wd = elm_widget_data_get(obj);
3625 if (!wd) return NULL;
3626 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3628 if (!it) return NULL;
3632 wd->group_items = eina_list_prepend(wd->group_items, it);
3633 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
3634 it->item->rel = NULL;
3638 Elm_Gen_Item *it2 = NULL;
3639 Eina_List *ll = it->parent->item->items;
3640 if (ll) it2 = ll->data;
3641 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
3642 if (!it2) it2 = it->parent;
3644 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3645 EINA_INLIST_GET(it2));
3646 it->item->rel = it2;
3647 it->item->rel->relcount++;
3649 it->item->before = EINA_TRUE;
3650 _item_queue(wd, it, NULL);
3655 elm_genlist_item_insert_after(Evas_Object *obj,
3656 const Elm_Genlist_Item_Class *itc,
3658 Elm_Gen_Item *parent,
3659 Elm_Gen_Item *after,
3660 Elm_Genlist_Item_Flags flags,
3662 const void *func_data)
3664 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3665 EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3666 Widget_Data *wd = elm_widget_data_get(obj);
3667 if (!wd) return NULL;
3668 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
3669 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3671 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3673 if (!it) return NULL;
3678 wd->group_items = eina_list_append_relative(wd->group_items, it,
3683 it->parent->item->items = eina_list_append_relative(it->parent->item->items, it,
3686 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3687 EINA_INLIST_GET(after));
3688 it->item->rel = after;
3689 it->item->rel->relcount++;
3690 it->item->before = EINA_FALSE;
3691 _item_queue(wd, it, NULL);
3696 elm_genlist_item_insert_before(Evas_Object *obj,
3697 const Elm_Genlist_Item_Class *itc,
3699 Elm_Gen_Item *parent,
3700 Elm_Gen_Item *before,
3701 Elm_Genlist_Item_Flags flags,
3703 const void *func_data)
3705 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3706 EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
3707 Widget_Data *wd = elm_widget_data_get(obj);
3708 if (!wd) return NULL;
3709 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
3710 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3712 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3714 if (!it) return NULL;
3717 if (it->group && before->group)
3718 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
3723 it->parent->item->items = eina_list_prepend_relative(it->parent->item->items, it,
3726 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3727 EINA_INLIST_GET(before));
3728 it->item->rel = before;
3729 it->item->rel->relcount++;
3730 it->item->before = EINA_TRUE;
3731 _item_queue(wd, it, NULL);
3736 elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
3737 const Elm_Genlist_Item_Class *itc,
3739 Elm_Gen_Item *parent,
3740 Elm_Genlist_Item_Flags flags,
3741 Eina_Compare_Cb comp,
3743 const void *func_data)
3745 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3746 Widget_Data *wd = elm_widget_data_get(obj);
3747 if (!wd) return NULL;
3748 Elm_Gen_Item *rel = NULL;
3749 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3751 if (!it) return NULL;
3753 _elm_genlist_item_compare_cb = comp;
3760 l = eina_list_search_sorted_near_list(it->parent->item->items,
3761 _elm_genlist_item_list_compare, it,
3764 rel = eina_list_data_get(l);
3768 if (cmp_result >= 0)
3770 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
3771 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3772 it->item->before = EINA_FALSE;
3774 else if (cmp_result < 0)
3776 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
3777 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3778 it->item->before = EINA_TRUE;
3785 wd->state = eina_inlist_sorted_state_new();
3786 eina_inlist_sorted_state_init(wd->state, wd->items);
3787 wd->requeue = EINA_FALSE;
3791 wd->group_items = eina_list_append(wd->group_items, it);
3793 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
3794 _elm_genlist_item_compare, wd->state);
3796 if (EINA_INLIST_GET(it)->next)
3798 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3799 it->item->before = EINA_TRUE;
3801 else if (EINA_INLIST_GET(it)->prev)
3803 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3804 it->item->before = EINA_FALSE;
3810 it->item->rel = rel;
3811 it->item->rel->relcount++;
3814 _item_queue(wd, it, _elm_genlist_item_list_compare);
3820 elm_genlist_item_sorted_insert(Evas_Object *obj,
3821 const Elm_Genlist_Item_Class *itc,
3823 Elm_Gen_Item *parent,
3824 Elm_Genlist_Item_Flags flags,
3825 Eina_Compare_Cb comp,
3827 const void *func_data)
3829 _elm_genlist_item_compare_data_cb = comp;
3831 return elm_genlist_item_direct_sorted_insert(obj, itc, data, parent, flags,
3832 _elm_genlist_item_compare_data, func, func_data);
3836 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
3838 Eina_Inlist *next, *l;
3840 ELM_CHECK_WIDTYPE(obj, widtype);
3841 Widget_Data *wd = elm_widget_data_get(obj);
3844 if (!standby) wd->generation++;
3848 eina_inlist_sorted_state_free(wd->state);
3852 if (wd->walking > 0)
3857 evas_event_freeze(evas_object_evas_get(wd->obj));
3858 for (l = wd->items, next = l ? l->next : NULL;
3860 l = next, next = next ? next->next : NULL)
3862 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
3864 if (it->generation < wd->generation)
3866 Elm_Gen_Item *itn = NULL;
3868 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
3869 if (itn) itn->walking++; /* prevent early death of subitem */
3871 if (itn) itn->walking--;
3877 ecore_job_del(wd->calc_job);
3878 wd->calc_job = NULL;
3880 if (wd->selected) wd->selected = eina_list_free(wd->selected);
3881 if (wd->clear_cb) wd->clear_cb(wd);
3889 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
3890 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3892 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
3893 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
3894 evas_event_thaw(evas_object_evas_get(wd->obj));
3895 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3899 elm_genlist_clear(Evas_Object *obj)
3901 _elm_genlist_clear(obj, EINA_FALSE);
3905 elm_genlist_multi_select_set(Evas_Object *obj,
3908 ELM_CHECK_WIDTYPE(obj, widtype);
3909 Widget_Data *wd = elm_widget_data_get(obj);
3915 elm_genlist_multi_select_get(const Evas_Object *obj)
3917 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3918 Widget_Data *wd = elm_widget_data_get(obj);
3919 if (!wd) return EINA_FALSE;
3924 elm_genlist_selected_item_get(const Evas_Object *obj)
3926 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3927 Widget_Data *wd = elm_widget_data_get(obj);
3928 if (!wd) return NULL;
3929 if (wd->selected) return wd->selected->data;
3933 EAPI const Eina_List *
3934 elm_genlist_selected_items_get(const Evas_Object *obj)
3936 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3937 Widget_Data *wd = elm_widget_data_get(obj);
3938 if (!wd) return NULL;
3939 return wd->selected;
3943 elm_genlist_realized_items_get(const Evas_Object *obj)
3945 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3946 Widget_Data *wd = elm_widget_data_get(obj);
3947 Eina_List *list = NULL;
3949 Eina_Bool done = EINA_FALSE;
3950 if (!wd) return NULL;
3951 EINA_INLIST_FOREACH(wd->blocks, itb)
3959 EINA_LIST_FOREACH(itb->items, l, it)
3961 if (it->realized) list = eina_list_append(list, it);
3973 elm_genlist_at_xy_item_get(const Evas_Object *obj,
3978 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3979 Widget_Data *wd = elm_widget_data_get(obj);
3980 Evas_Coord ox, oy, ow, oh;
3983 if (!wd) return NULL;
3984 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
3986 EINA_INLIST_FOREACH(wd->blocks, itb)
3991 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
3992 oy + itb->y - itb->wd->pan_y,
3993 itb->w, itb->h, x, y, 1, 1))
3995 EINA_LIST_FOREACH(itb->items, l, it)
3997 Evas_Coord itx, ity;
3999 itx = ox + itb->x + it->x - itb->wd->pan_x;
4000 ity = oy + itb->y + it->y - itb->wd->pan_y;
4001 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4005 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4006 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4012 lasty = ity + it->item->h;
4017 if (y > lasty) *posret = 1;
4024 elm_genlist_first_item_get(const Evas_Object *obj)
4026 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4027 Widget_Data *wd = elm_widget_data_get(obj);
4028 if (!wd) return NULL;
4029 if (!wd->items) return NULL;
4030 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4031 while ((it) && (it->generation < wd->generation))
4032 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4037 elm_genlist_last_item_get(const Evas_Object *obj)
4039 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4040 Widget_Data *wd = elm_widget_data_get(obj);
4041 if (!wd) return NULL;
4042 if (!wd->items) return NULL;
4043 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4044 while ((it) && (it->generation < wd->generation))
4045 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4050 elm_genlist_item_next_get(const Elm_Gen_Item *it)
4052 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4055 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4056 if ((it) && (it->generation == it->wd->generation)) break;
4058 return (Elm_Gen_Item *)it;
4062 elm_genlist_item_prev_get(const Elm_Gen_Item *it)
4064 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4067 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4068 if ((it) && (it->generation == it->wd->generation)) break;
4070 return (Elm_Gen_Item *)it;
4074 elm_genlist_item_genlist_get(const Elm_Gen_Item *it)
4076 return _elm_genlist_item_widget_get(it);
4080 elm_genlist_item_parent_get(const Elm_Gen_Item *it)
4082 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4087 elm_genlist_item_subitems_clear(Elm_Gen_Item *it)
4089 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4090 Eina_List *tl = NULL, *l;
4093 EINA_LIST_FOREACH(it->item->items, l, it2)
4094 tl = eina_list_append(tl, it2);
4095 EINA_LIST_FREE(tl, it2)
4096 elm_genlist_item_del(it2);
4100 elm_genlist_item_selected_set(Elm_Gen_Item *it,
4103 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4104 Widget_Data *wd = it->wd;
4106 if ((it->generation < wd->generation) || (it->disabled)) return;
4107 selected = !!selected;
4108 if (it->selected == selected) return;
4114 while (wd->selected)
4116 if (it->unhighlight_cb) it->unhighlight_cb(wd->selected->data);
4117 it->unsel_cb(wd->selected->data);
4120 it->highlight_cb(it);
4124 if (it->unhighlight_cb) it->unhighlight_cb(it);
4129 elm_genlist_item_selected_get(const Elm_Gen_Item *it)
4131 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4132 return it->selected;
4136 elm_genlist_item_expanded_set(Elm_Gen_Item *it,
4139 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4140 if (it->item->expanded == expanded) return;
4141 it->item->expanded = expanded;
4142 it->wd->expanded_item = it;
4143 if (it->item->expanded)
4146 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
4147 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
4148 it->wd->auto_scroll_enabled = EINA_TRUE;
4153 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
4154 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
4155 it->wd->auto_scroll_enabled = EINA_FALSE;
4160 elm_genlist_item_expanded_get(const Elm_Gen_Item *it)
4162 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4163 return it->item->expanded;
4167 elm_genlist_item_expanded_depth_get(const Elm_Gen_Item *it)
4169 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, 0);
4170 return it->item->expanded_depth;
4174 elm_genlist_item_disabled_set(Elm_Gen_Item *it,
4177 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4180 if (it->disabled == disabled) return;
4181 if (it->generation < it->wd->generation) return;
4182 it->disabled = !!disabled;
4184 elm_genlist_item_selected_set(it, EINA_FALSE);
4188 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4190 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
4191 EINA_LIST_FOREACH(it->content_objs, l, obj)
4192 elm_widget_disabled_set(obj, disabled);
4197 elm_genlist_item_disabled_get(const Elm_Gen_Item *it)
4199 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4200 if (it->generation < it->wd->generation) return EINA_FALSE;
4201 return it->disabled;
4205 elm_genlist_item_display_only_set(Elm_Gen_Item *it,
4206 Eina_Bool display_only)
4208 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4209 if (it->display_only == display_only) return;
4210 if (it->generation < it->wd->generation) return;
4211 it->display_only = display_only;
4212 it->item->mincalcd = EINA_FALSE;
4213 it->item->updateme = EINA_TRUE;
4214 if (it->item->block) it->item->block->updateme = EINA_TRUE;
4215 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4216 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4220 elm_genlist_item_display_only_get(const Elm_Gen_Item *it)
4222 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4223 if (it->generation < it->wd->generation) return EINA_FALSE;
4224 return it->display_only;
4228 elm_genlist_item_show(Elm_Gen_Item *it)
4230 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4231 Evas_Coord gith = 0;
4232 if (it->generation < it->wd->generation) return;
4233 if ((it->item->queued) || (!it->item->mincalcd))
4235 it->wd->show_item = it;
4236 it->wd->bring_in = EINA_TRUE;
4237 it->item->showme = EINA_TRUE;
4240 if (it->wd->show_item)
4242 it->wd->show_item->item->showme = EINA_FALSE;
4243 it->wd->show_item = NULL;
4245 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4246 gith = it->item->group_item->item->h;
4247 elm_smart_scroller_child_region_show(it->wd->scr,
4248 it->x + it->item->block->x,
4249 it->y + it->item->block->y - gith,
4250 it->item->block->w, it->item->h);
4254 elm_genlist_item_promote(Elm_Gen_Item *it)
4256 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4257 if (it->generation < it->wd->generation) return;
4258 _item_move_before(it, elm_genlist_first_item_get(WIDGET(it)));
4262 elm_genlist_item_demote(Elm_Gen_Item *it)
4264 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4265 if (it->generation < it->wd->generation) return;
4266 _item_move_after(it, elm_genlist_last_item_get(WIDGET(it)));
4270 elm_genlist_item_bring_in(Elm_Gen_Item *it)
4272 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4273 Evas_Coord gith = 0;
4274 if (it->generation < it->wd->generation) return;
4275 if ((it->item->queued) || (!it->item->mincalcd))
4277 it->wd->show_item = it;
4278 it->wd->bring_in = EINA_TRUE;
4279 it->item->showme = EINA_TRUE;
4282 if (it->wd->show_item)
4284 it->wd->show_item->item->showme = EINA_FALSE;
4285 it->wd->show_item = NULL;
4287 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4288 gith = it->item->group_item->item->h;
4289 elm_smart_scroller_region_bring_in(it->wd->scr,
4290 it->x + it->item->block->x,
4291 it->y + it->item->block->y - gith,
4292 it->item->block->w, it->item->h);
4296 elm_genlist_item_top_show(Elm_Gen_Item *it)
4298 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4300 Evas_Coord gith = 0;
4302 if (it->generation < it->wd->generation) return;
4303 if ((it->item->queued) || (!it->item->mincalcd))
4305 it->wd->show_item = it;
4306 it->wd->bring_in = EINA_TRUE;
4307 it->item->showme = EINA_TRUE;
4310 if (it->wd->show_item)
4312 it->wd->show_item->item->showme = EINA_FALSE;
4313 it->wd->show_item = NULL;
4315 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4316 if (it->item->group_item) gith = it->item->group_item->item->h;
4317 elm_smart_scroller_child_region_show(it->wd->scr,
4318 it->x + it->item->block->x,
4319 it->y + it->item->block->y - gith,
4320 it->item->block->w, oh);
4324 elm_genlist_item_top_bring_in(Elm_Gen_Item *it)
4326 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4328 Evas_Coord gith = 0;
4330 if (it->generation < it->wd->generation) return;
4331 if ((it->item->queued) || (!it->item->mincalcd))
4333 it->wd->show_item = it;
4334 it->wd->bring_in = EINA_TRUE;
4335 it->item->showme = EINA_TRUE;
4338 if (it->wd->show_item)
4340 it->wd->show_item->item->showme = EINA_FALSE;
4341 it->wd->show_item = NULL;
4343 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4344 if (it->item->group_item) gith = it->item->group_item->item->h;
4345 elm_smart_scroller_region_bring_in(it->wd->scr,
4346 it->x + it->item->block->x,
4347 it->y + it->item->block->y - gith,
4348 it->item->block->w, oh);
4352 elm_genlist_item_middle_show(Elm_Gen_Item *it)
4354 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4357 if (it->generation < it->wd->generation) return;
4358 if ((it->item->queued) || (!it->item->mincalcd))
4360 it->wd->show_item = it;
4361 it->wd->bring_in = EINA_TRUE;
4362 it->item->showme = EINA_TRUE;
4365 if (it->wd->show_item)
4367 it->wd->show_item->item->showme = EINA_FALSE;
4368 it->wd->show_item = NULL;
4370 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4371 elm_smart_scroller_child_region_show(it->wd->scr,
4372 it->x + it->item->block->x,
4373 it->y + it->item->block->y - oh / 2 +
4374 it->item->h / 2, it->item->block->w, oh);
4378 elm_genlist_item_middle_bring_in(Elm_Gen_Item *it)
4380 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4383 if (it->generation < it->wd->generation) return;
4384 if ((it->item->queued) || (!it->item->mincalcd))
4386 it->wd->show_item = it;
4387 it->wd->bring_in = EINA_TRUE;
4388 it->item->showme = EINA_TRUE;
4391 if (it->wd->show_item)
4393 it->wd->show_item->item->showme = EINA_FALSE;
4394 it->wd->show_item = NULL;
4396 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4397 elm_smart_scroller_region_bring_in(it->wd->scr,
4398 it->x + it->item->block->x,
4399 it->y + it->item->block->y - oh / 2 + it->item->h / 2,
4400 it->item->block->w, oh);
4404 elm_genlist_item_del(Elm_Gen_Item *it)
4406 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4407 if ((it->relcount > 0) || (it->walking > 0))
4409 elm_genlist_item_subitems_clear(it);
4410 if (it->wd->show_item == it) it->wd->show_item = NULL;
4411 _elm_genlist_item_del_notserious(it);
4412 if (it->item->block)
4414 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
4415 it->item->block->changed = EINA_TRUE;
4416 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
4417 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
4421 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
4430 elm_genlist_item_data_set(Elm_Gen_Item *it,
4433 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4434 elm_widget_item_data_set(it, data);
4438 elm_genlist_item_data_get(const Elm_Gen_Item *it)
4440 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4441 return elm_widget_item_data_get(it);
4445 elm_genlist_item_icons_orphan(Elm_Gen_Item *it)
4447 elm_genlist_item_contents_orphan(it);
4451 elm_genlist_item_contents_orphan(Elm_Gen_Item *it)
4453 Evas_Object *content;
4454 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4455 EINA_LIST_FREE(it->content_objs, content)
4457 elm_widget_sub_object_del(WIDGET(it), content);
4458 evas_object_smart_member_del(content);
4459 evas_object_hide(content);
4463 EAPI const Evas_Object *
4464 elm_genlist_item_object_get(const Elm_Gen_Item *it)
4466 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4471 elm_genlist_item_update(Elm_Gen_Item *it)
4473 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4474 if (!it->item->block) return;
4475 if (it->generation < it->wd->generation) return;
4476 it->item->mincalcd = EINA_FALSE;
4477 it->item->updateme = EINA_TRUE;
4478 it->item->block->updateme = EINA_TRUE;
4479 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4480 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4484 elm_genlist_item_fields_update(Elm_Genlist_Item *it,
4486 Elm_Genlist_Item_Field_Flags itf)
4488 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4489 if (!it->item->block) return;
4490 if (it->generation < it->wd->generation) return;
4492 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_LABEL))
4493 _item_label_realize(it, it->base.view, &it->labels, parts);
4494 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
4496 it->content_objs = _item_content_unrealize(it, it->base.view,
4497 &it->contents, parts);
4498 it->content_objs = _item_content_realize(it, it->base.view,
4499 &it->contents, parts);
4501 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
4502 _item_state_realize(it, it->base.view, &it->states, parts);
4506 elm_genlist_item_item_class_update(Elm_Gen_Item *it,
4507 const Elm_Genlist_Item_Class *itc)
4509 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4510 if (!it->item->block) return;
4511 EINA_SAFETY_ON_NULL_RETURN(itc);
4512 if (it->generation < it->wd->generation) return;
4514 it->item->nocache = EINA_TRUE;
4515 elm_genlist_item_update(it);
4518 EAPI const Elm_Genlist_Item_Class *
4519 elm_genlist_item_item_class_get(const Elm_Gen_Item *it)
4521 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4522 if (it->generation < it->wd->generation) return NULL;
4526 static Evas_Object *
4527 _elm_genlist_item_label_create(void *data,
4528 Evas_Object *obj __UNUSED__,
4529 Evas_Object *tooltip,
4530 void *it __UNUSED__)
4532 Evas_Object *label = elm_label_add(tooltip);
4535 elm_object_style_set(label, "tooltip");
4536 elm_object_text_set(label, data);
4541 _elm_genlist_item_label_del_cb(void *data,
4542 Evas_Object *obj __UNUSED__,
4543 void *event_info __UNUSED__)
4545 eina_stringshare_del(data);
4549 elm_genlist_item_tooltip_text_set(Elm_Gen_Item *it,
4552 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4553 text = eina_stringshare_add(text);
4554 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
4556 _elm_genlist_item_label_del_cb);
4560 elm_genlist_item_tooltip_content_cb_set(Elm_Gen_Item *it,
4561 Elm_Tooltip_Item_Content_Cb func,
4563 Evas_Smart_Cb del_cb)
4565 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, error);
4567 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4570 if (it->tooltip.del_cb)
4571 it->tooltip.del_cb((void *)it->tooltip.data,
4574 it->tooltip.content_cb = func;
4575 it->tooltip.data = data;
4576 it->tooltip.del_cb = del_cb;
4580 elm_widget_item_tooltip_content_cb_set(it,
4581 it->tooltip.content_cb,
4582 it->tooltip.data, NULL);
4583 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4584 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
4590 if (del_cb) del_cb((void *)data, NULL, NULL);
4594 elm_genlist_item_tooltip_unset(Elm_Gen_Item *it)
4596 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4597 if ((VIEW(it)) && (it->tooltip.content_cb))
4598 elm_widget_item_tooltip_unset(it);
4600 if (it->tooltip.del_cb)
4601 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4602 it->tooltip.del_cb = NULL;
4603 it->tooltip.content_cb = NULL;
4604 it->tooltip.data = NULL;
4605 it->tooltip.free_size = EINA_FALSE;
4606 if (it->tooltip.style)
4607 elm_genlist_item_tooltip_style_set(it, NULL);
4611 elm_genlist_item_tooltip_style_set(Elm_Gen_Item *it,
4614 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4615 eina_stringshare_replace(&it->tooltip.style, style);
4616 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4620 elm_genlist_item_tooltip_style_get(const Elm_Gen_Item *it)
4622 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4623 return it->tooltip.style;
4627 elm_genlist_item_tooltip_window_mode_set(Elm_Gen_Item *it, Eina_Bool disable)
4629 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4630 it->tooltip.free_size = disable;
4631 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
4636 elm_genlist_item_tooltip_window_mode_get(const Elm_Gen_Item *it)
4638 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4639 return it->tooltip.free_size;
4643 elm_genlist_item_cursor_set(Elm_Gen_Item *it,
4646 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4647 eina_stringshare_replace(&it->mouse_cursor, cursor);
4648 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4652 elm_genlist_item_cursor_get(const Elm_Gen_Item *it)
4654 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4655 return elm_widget_item_cursor_get(it);
4659 elm_genlist_item_cursor_unset(Elm_Gen_Item *it)
4661 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4662 if (!it->mouse_cursor)
4666 elm_widget_item_cursor_unset(it);
4668 eina_stringshare_del(it->mouse_cursor);
4669 it->mouse_cursor = NULL;
4673 elm_genlist_item_cursor_style_set(Elm_Gen_Item *it,
4676 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4677 elm_widget_item_cursor_style_set(it, style);
4681 elm_genlist_item_cursor_style_get(const Elm_Gen_Item *it)
4683 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4684 return elm_widget_item_cursor_style_get(it);
4688 elm_genlist_item_cursor_engine_only_set(Elm_Gen_Item *it,
4689 Eina_Bool engine_only)
4691 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4692 elm_widget_item_cursor_engine_only_set(it, engine_only);
4696 elm_genlist_item_cursor_engine_only_get(const Elm_Gen_Item *it)
4698 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4699 return elm_widget_item_cursor_engine_only_get(it);
4703 elm_genlist_horizontal_set(Evas_Object *obj,
4706 ELM_CHECK_WIDTYPE(obj, widtype);
4707 Widget_Data *wd = elm_widget_data_get(obj);
4709 if (wd->mode == mode) return;
4715 elm_genlist_horizontal_mode_set(Evas_Object *obj,
4718 elm_genlist_horizontal_set(obj, mode);
4722 elm_genlist_horizontal_get(const Evas_Object *obj)
4724 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4725 Widget_Data *wd = elm_widget_data_get(obj);
4726 if (!wd) return ELM_LIST_LAST;
4731 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4733 return elm_genlist_horizontal_get(obj);
4737 elm_genlist_always_select_mode_set(Evas_Object *obj,
4738 Eina_Bool always_select)
4740 ELM_CHECK_WIDTYPE(obj, widtype);
4741 Widget_Data *wd = elm_widget_data_get(obj);
4743 wd->always_select = always_select;
4747 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4749 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4750 Widget_Data *wd = elm_widget_data_get(obj);
4751 if (!wd) return EINA_FALSE;
4752 return wd->always_select;
4756 elm_genlist_no_select_mode_set(Evas_Object *obj,
4757 Eina_Bool no_select)
4759 ELM_CHECK_WIDTYPE(obj, widtype);
4760 Widget_Data *wd = elm_widget_data_get(obj);
4762 wd->no_select = no_select;
4766 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4768 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4769 Widget_Data *wd = elm_widget_data_get(obj);
4770 if (!wd) return EINA_FALSE;
4771 return wd->no_select;
4775 elm_genlist_compress_mode_set(Evas_Object *obj,
4778 ELM_CHECK_WIDTYPE(obj, widtype);
4779 Widget_Data *wd = elm_widget_data_get(obj);
4781 wd->compress = compress;
4782 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
4786 elm_genlist_compress_mode_get(const Evas_Object *obj)
4788 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4789 Widget_Data *wd = elm_widget_data_get(obj);
4790 if (!wd) return EINA_FALSE;
4791 return wd->compress;
4795 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
4796 Eina_Bool height_for_width)
4798 ELM_CHECK_WIDTYPE(obj, widtype);
4799 Widget_Data *wd = elm_widget_data_get(obj);
4801 wd->height_for_width = !!height_for_width;
4802 if (wd->height_for_width)
4804 elm_genlist_homogeneous_set(obj, EINA_FALSE);
4805 elm_genlist_compress_mode_set(obj, EINA_TRUE);
4810 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
4812 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4813 Widget_Data *wd = elm_widget_data_get(obj);
4814 if (!wd) return EINA_FALSE;
4815 return wd->height_for_width;
4819 elm_genlist_bounce_set(Evas_Object *obj,
4823 ELM_CHECK_WIDTYPE(obj, widtype);
4824 Widget_Data *wd = elm_widget_data_get(obj);
4826 elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
4827 wd->h_bounce = h_bounce;
4828 wd->v_bounce = v_bounce;
4832 elm_genlist_bounce_get(const Evas_Object *obj,
4833 Eina_Bool *h_bounce,
4834 Eina_Bool *v_bounce)
4836 ELM_CHECK_WIDTYPE(obj, widtype);
4837 Widget_Data *wd = elm_widget_data_get(obj);
4839 if (h_bounce) *h_bounce = wd->h_bounce;
4840 if (v_bounce) *v_bounce = wd->v_bounce;
4844 elm_genlist_homogeneous_set(Evas_Object *obj,
4845 Eina_Bool homogeneous)
4847 ELM_CHECK_WIDTYPE(obj, widtype);
4848 Widget_Data *wd = elm_widget_data_get(obj);
4850 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
4851 wd->homogeneous = homogeneous;
4855 elm_genlist_homogeneous_get(const Evas_Object *obj)
4857 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4858 Widget_Data *wd = elm_widget_data_get(obj);
4859 if (!wd) return EINA_FALSE;
4860 return wd->homogeneous;
4864 elm_genlist_block_count_set(Evas_Object *obj,
4867 ELM_CHECK_WIDTYPE(obj, widtype);
4868 Widget_Data *wd = elm_widget_data_get(obj);
4870 wd->max_items_per_block = n;
4871 wd->item_cache_max = wd->max_items_per_block * 2;
4872 _item_cache_clean(wd);
4876 elm_genlist_block_count_get(const Evas_Object *obj)
4878 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4879 Widget_Data *wd = elm_widget_data_get(obj);
4881 return wd->max_items_per_block;
4885 elm_genlist_longpress_timeout_set(Evas_Object *obj,
4888 ELM_CHECK_WIDTYPE(obj, widtype);
4889 Widget_Data *wd = elm_widget_data_get(obj);
4891 wd->longpress_timeout = timeout;
4895 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
4897 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4898 Widget_Data *wd = elm_widget_data_get(obj);
4900 return wd->longpress_timeout;
4904 elm_genlist_scroller_policy_set(Evas_Object *obj,
4905 Elm_Scroller_Policy policy_h,
4906 Elm_Scroller_Policy policy_v)
4908 ELM_CHECK_WIDTYPE(obj, widtype);
4909 Widget_Data *wd = elm_widget_data_get(obj);
4910 if ((!wd) || (!wd->scr)) return;
4911 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4912 (policy_v >= ELM_SCROLLER_POLICY_LAST))
4914 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
4918 elm_genlist_scroller_policy_get(const Evas_Object *obj,
4919 Elm_Scroller_Policy *policy_h,
4920 Elm_Scroller_Policy *policy_v)
4922 ELM_CHECK_WIDTYPE(obj, widtype);
4923 Widget_Data *wd = elm_widget_data_get(obj);
4924 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
4925 if ((!wd) || (!wd->scr)) return;
4926 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
4927 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
4928 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
4932 elm_genlist_realized_items_update(Evas_Object *obj)
4934 ELM_CHECK_WIDTYPE(obj, widtype);
4936 Eina_List *list, *l;
4939 list = elm_genlist_realized_items_get(obj);
4940 EINA_LIST_FOREACH(list, l, it)
4941 elm_genlist_item_update(it);
4945 elm_genlist_item_mode_set(Elm_Gen_Item *it,
4946 const char *mode_type,
4949 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4950 Widget_Data *wd = it->wd;
4955 if (!mode_type) return;
4956 if ((it->generation < it->wd->generation) || (it->disabled)) return;
4958 if ((wd->mode_item == it) &&
4959 (!strcmp(mode_type, wd->mode_type)) &&
4962 if (!wd->mode_item_style) return;
4963 it->mode_set = mode_set;
4967 EINA_LIST_FOREACH(wd->selected, l, it2)
4969 elm_genlist_item_selected_set(it2, EINA_FALSE);
4973 it2 = elm_genlist_selected_item_get(wd->obj);
4974 if ((it2) && (it2->realized))
4975 elm_genlist_item_selected_set(it2, EINA_FALSE);
4978 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
4980 ((it == wd->mode_item) && (!mode_set)))
4981 _item_mode_unset(wd);
4983 eina_stringshare_replace(&wd->mode_type, mode_type);
4984 if (mode_set) _item_mode_set(it);
4989 elm_genlist_mode_item_style_get(const Evas_Object *obj)
4991 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4992 Widget_Data *wd = elm_widget_data_get(obj);
4993 if (!wd) return NULL;
4994 return wd->mode_item_style;
4998 elm_genlist_mode_item_style_set(Evas_Object *obj, const char *style)
5000 ELM_CHECK_WIDTYPE(obj, widtype);
5001 Widget_Data *wd = elm_widget_data_get(obj);
5003 if ((style == wd->mode_item_style) || (style && wd->mode_item_style &&
5004 (!strcmp(style, wd->mode_item_style))))
5006 eina_stringshare_replace(&wd->mode_item_style, style);
5007 elm_genlist_realized_items_update(obj);
5011 elm_genlist_mode_get(const Evas_Object *obj)
5013 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5014 Widget_Data *wd = elm_widget_data_get(obj);
5015 if (!wd) return NULL;
5016 return wd->mode_type;
5019 EAPI const Elm_Gen_Item *
5020 elm_genlist_mode_item_get(const Evas_Object *obj)
5022 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5023 Widget_Data *wd = elm_widget_data_get(obj);
5024 if (!wd) return NULL;
5025 return wd->mode_item;
5029 elm_genlist_reorder_mode_set(Evas_Object *obj,
5030 Eina_Bool reorder_mode)
5032 ELM_CHECK_WIDTYPE(obj, widtype);
5033 Widget_Data *wd = elm_widget_data_get(obj);
5035 wd->reorder_mode = reorder_mode;
5039 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5041 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5042 Widget_Data *wd = elm_widget_data_get(obj);
5043 if (!wd) return EINA_FALSE;
5044 return wd->reorder_mode;
5047 /* for gengrid as of now */
5049 _elm_genlist_page_relative_set(Evas_Object *obj,
5053 Evas_Coord pagesize_h;
5054 Evas_Coord pagesize_v;
5056 ELM_CHECK_WIDTYPE(obj, widtype);
5057 Widget_Data *wd = elm_widget_data_get(obj);
5060 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5061 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5065 /* for gengrid as of now */
5067 _elm_genlist_page_relative_get(const Evas_Object *obj,
5071 ELM_CHECK_WIDTYPE(obj, widtype);
5072 Widget_Data *wd = elm_widget_data_get(obj);
5075 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5078 /* for gengrid as of now */
5080 _elm_genlist_page_size_set(Evas_Object *obj,
5081 Evas_Coord h_pagesize,
5082 Evas_Coord v_pagesize)
5087 ELM_CHECK_WIDTYPE(obj, widtype);
5088 Widget_Data *wd = elm_widget_data_get(obj);
5090 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5091 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5095 /* for gengrid as of now */
5097 _elm_genlist_current_page_get(const Evas_Object *obj,
5101 ELM_CHECK_WIDTYPE(obj, widtype);
5102 Widget_Data *wd = elm_widget_data_get(obj);
5105 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5108 /* for gengrid as of now */
5110 _elm_genlist_last_page_get(const Evas_Object *obj,
5114 ELM_CHECK_WIDTYPE(obj, widtype);
5115 Widget_Data *wd = elm_widget_data_get(obj);
5118 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5121 /* for gengrid as of now */
5123 _elm_genlist_page_show(const Evas_Object *obj,
5127 ELM_CHECK_WIDTYPE(obj, widtype);
5128 Widget_Data *wd = elm_widget_data_get(obj);
5131 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5134 /* for gengrid as of now */
5136 _elm_genlist_page_bring_in(const Evas_Object *obj,
5140 ELM_CHECK_WIDTYPE(obj, widtype);
5141 Widget_Data *wd = elm_widget_data_get(obj);
5144 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5148 _elm_genlist_item_widget_get(const Elm_Gen_Item *it)
5150 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
5155 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5158 Evas_Object *content;
5160 if (!it->realized) return;
5161 if (it->wd->reorder_it == it) return;
5162 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5164 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5167 ecore_timer_del(it->long_timer);
5168 it->long_timer = NULL;
5171 elm_widget_stringlist_free(it->labels);
5173 elm_widget_stringlist_free(it->contents);
5174 it->contents = NULL;
5175 elm_widget_stringlist_free(it->states);
5178 EINA_LIST_FREE(it->content_objs, content)
5179 evas_object_del(content);
5181 it->unrealize_cb(it);
5183 it->realized = EINA_FALSE;
5184 it->want_unrealize = EINA_FALSE;
5185 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5186 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5190 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5192 elm_widget_item_pre_notify_del(it);
5193 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5194 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5196 if (it->itc->func.del)
5197 it->itc->func.del((void *)it->base.data, WIDGET(it));
5201 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5203 _elm_genlist_item_del_notserious(it);
5204 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5205 if (it->tooltip.del_cb)
5206 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5207 it->wd->walking -= it->walking;
5208 if (it->long_timer) ecore_timer_del(it->long_timer);
5210 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5212 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5213 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5216 elm_widget_item_del(it);