3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_genlist.h"
10 #define MAX_ITEMS_PER_BLOCK 32
11 #define REORDER_EFFECT_TIME 0.5
13 #define ELM_GEN_SETUP(wd) \
14 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
15 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
16 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
18 #define ELM_GEN_ITEM_SETUP(it) \
19 (it)->del_cb = (Ecore_Cb)_item_del; \
20 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
21 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
22 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
23 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
25 typedef struct _Item_Block Item_Block;
26 typedef struct _Item_Cache Item_Cache;
28 struct Elm_Gen_Item_Type
33 Evas_Coord w, h, minw, minh;
34 Elm_Gen_Item *group_item;
35 Elm_Genlist_Item_Flags flags;
36 Eina_List *mode_labels, *mode_contents, *mode_states, *mode_content_objs;
37 Ecore_Timer *swipe_timer;
38 Evas_Coord scrl_x, scrl_y, old_scrl_y;
41 Evas_Object *mode_view;
47 Eina_Bool want_realize : 1;
48 Eina_Bool expanded : 1;
49 Eina_Bool mincalcd : 1;
52 Eina_Bool updateme : 1;
53 Eina_Bool nocache : 1;
54 Eina_Bool stacking_even : 1;
55 Eina_Bool nostacking : 1;
56 Eina_Bool move_effect_enabled : 1;
67 Evas_Coord x, y, w, h, minw, minh;
68 Eina_Bool want_unrealize : 1;
69 Eina_Bool realized : 1;
70 Eina_Bool changed : 1;
71 Eina_Bool updateme : 1;
73 Eina_Bool must_recalc : 1;
80 Evas_Object *base_view, *spacer;
82 const char *item_style; // it->itc->item_style
83 Eina_Bool tree : 1; // it->group
84 Eina_Bool compress : 1; // it->wd->compress
86 Eina_Bool selected : 1; // it->selected
87 Eina_Bool disabled : 1; // it->disabled
88 Eina_Bool expanded : 1; // it->item->expanded
91 static const char *widtype = NULL;
92 static void _item_cache_zero(Widget_Data *wd);
93 static void _del_hook(Evas_Object *obj);
94 static void _mirrored_set(Evas_Object *obj,
96 static void _theme_hook(Evas_Object *obj);
97 static void _show_region_hook(void *data,
99 static void _sizing_eval(Evas_Object *obj);
100 static void _item_realize(Elm_Gen_Item *it,
103 static void _item_unrealize_cb(Elm_Gen_Item *it);
104 static void _item_block_unrealize(Item_Block *itb);
105 static void _calc_job(void *data);
106 static void _on_focus_hook(void *data,
108 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
109 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
110 static Eina_Bool _item_single_select_up(Widget_Data *wd);
111 static Eina_Bool _item_single_select_down(Widget_Data *wd);
112 static Eina_Bool _event_hook(Evas_Object *obj,
114 Evas_Callback_Type type,
116 static void _signal_emit_hook(Evas_Object *obj,
117 const char *emission,
119 static Eina_Bool _deselect_all_items(Widget_Data *wd);
120 static void _pan_calculate(Evas_Object *obj);
121 static void _pan_max_get(Evas_Object *obj,
124 static void _item_position(Elm_Gen_Item *it,
128 static void _mode_item_realize(Elm_Gen_Item *it);
129 static void _mode_item_unrealize(Elm_Gen_Item *it);
130 static void _item_mode_set(Elm_Gen_Item *it);
131 static void _item_mode_unset(Widget_Data *wd);
132 static void _group_items_recalc(void *data);
133 static void _item_move_after(Elm_Gen_Item *it,
134 Elm_Gen_Item *after);
135 static void _item_move_before(Elm_Gen_Item *it,
136 Elm_Gen_Item *before);
137 static void _item_auto_scroll(Widget_Data *wd);
138 static void _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby);
140 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
141 static void _pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
143 static const char SIG_ACTIVATED[] = "activated";
144 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
145 static const char SIG_SELECTED[] = "selected";
146 static const char SIG_UNSELECTED[] = "unselected";
147 static const char SIG_EXPANDED[] = "expanded";
148 static const char SIG_CONTRACTED[] = "contracted";
149 static const char SIG_EXPAND_REQUEST[] = "expand,request";
150 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
151 static const char SIG_REALIZED[] = "realized";
152 static const char SIG_UNREALIZED[] = "unrealized";
153 static const char SIG_DRAG_START_UP[] = "drag,start,up";
154 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
155 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
156 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
157 static const char SIG_DRAG_STOP[] = "drag,stop";
158 static const char SIG_DRAG[] = "drag";
159 static const char SIG_LONGPRESSED[] = "longpressed";
160 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
161 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
162 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
163 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
164 static const char SIG_EDGE_TOP[] = "edge,top";
165 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
166 static const char SIG_EDGE_LEFT[] = "edge,left";
167 static const char SIG_EDGE_RIGHT[] = "edge,right";
168 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
169 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
170 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
171 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
172 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
173 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
174 static const char SIG_SWIPE[] = "swipe";
175 static const char SIG_MOVED[] = "moved";
177 static const Evas_Smart_Cb_Description _signals[] = {
178 {SIG_CLICKED_DOUBLE, ""},
181 {SIG_UNSELECTED, ""},
183 {SIG_CONTRACTED, ""},
184 {SIG_EXPAND_REQUEST, ""},
185 {SIG_CONTRACT_REQUEST, ""},
187 {SIG_UNREALIZED, ""},
188 {SIG_DRAG_START_UP, ""},
189 {SIG_DRAG_START_DOWN, ""},
190 {SIG_DRAG_START_LEFT, ""},
191 {SIG_DRAG_START_RIGHT, ""},
194 {SIG_LONGPRESSED, ""},
195 {SIG_SCROLL_ANIM_START, ""},
196 {SIG_SCROLL_ANIM_STOP, ""},
197 {SIG_SCROLL_DRAG_START, ""},
198 {SIG_SCROLL_DRAG_STOP, ""},
200 {SIG_EDGE_BOTTOM, ""},
202 {SIG_EDGE_RIGHT, ""},
203 {SIG_MULTI_SWIPE_LEFT, ""},
204 {SIG_MULTI_SWIPE_RIGHT, ""},
205 {SIG_MULTI_SWIPE_UP, ""},
206 {SIG_MULTI_SWIPE_DOWN, ""},
207 {SIG_MULTI_PINCH_OUT, ""},
208 {SIG_MULTI_PINCH_IN, ""},
215 #undef ELM_CHECK_WIDTYPE
216 #define ELM_CHECK_WIDTYPE(obj, widtype) \
217 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
218 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
219 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
220 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
221 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
223 static const char *_gengrid = NULL;
224 static const char *_genlist = NULL;
226 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
228 elm_genlist_type_check(const Evas_Object *obj,
231 const char *provided, *expected = "(unknown)";
232 static int abort_on_warn = -1;
233 provided = elm_widget_type_get(obj);
234 if (!_genlist) _genlist = eina_stringshare_add("genlist");
235 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
236 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
238 if ((!provided) || (!provided[0]))
240 provided = evas_object_type_get(obj);
241 if ((!provided) || (!provided[0]))
242 provided = "(unknown)";
244 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
245 if (abort_on_warn == -1)
247 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
248 else abort_on_warn = 0;
250 if (abort_on_warn == 1) abort();
255 _event_hook(Evas_Object *obj,
256 Evas_Object *src __UNUSED__,
257 Evas_Callback_Type type,
260 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
261 Evas_Event_Key_Down *ev = event_info;
262 Widget_Data *wd = elm_widget_data_get(obj);
263 Evas_Coord pan_max_x = 0, pan_max_y = 0;
264 if (!wd) return EINA_FALSE;
265 if (!wd->items) return EINA_FALSE;
266 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
267 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
269 Elm_Gen_Item *it = NULL;
272 Evas_Coord step_x = 0;
273 Evas_Coord step_y = 0;
276 Evas_Coord page_x = 0;
277 Evas_Coord page_y = 0;
279 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
280 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
281 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
282 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
284 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
288 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
292 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
294 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
295 (_item_multi_select_up(wd)))
296 || (_item_single_select_up(wd)))
298 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
304 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
306 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
307 (_item_multi_select_down(wd)))
308 || (_item_single_select_down(wd)))
310 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
316 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
318 it = elm_genlist_first_item_get(obj);
319 elm_genlist_item_bring_in(it);
320 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
323 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
325 it = elm_genlist_last_item_get(obj);
326 elm_genlist_item_bring_in(it);
327 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
330 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
333 y -= -(page_y * v_h) / 100;
337 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
340 y += -(page_y * v_h) / 100;
344 else if (!strcmp(ev->keyname, "Escape"))
346 if (!_deselect_all_items(wd)) return EINA_FALSE;
347 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
350 else if (((!strcmp(ev->keyname, "Return")) ||
351 (!strcmp(ev->keyname, "KP_Enter")) ||
352 (!strcmp(ev->keyname, "space")))
353 && (!wd->multi) && (wd->selected))
355 it = elm_genlist_selected_item_get(obj);
356 elm_genlist_item_expanded_set(it,
357 !elm_genlist_item_expanded_get(it));
358 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
360 else return EINA_FALSE;
362 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
363 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
365 if (x > pan_max_x) x = pan_max_x;
367 if (y > pan_max_y) y = pan_max_y;
368 elm_smart_scroller_child_pos_set(wd->scr, x, y);
373 _deselect_all_items(Widget_Data *wd)
375 if (!wd->selected) return EINA_FALSE;
377 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
383 _item_multi_select_up(Widget_Data *wd)
385 if (!wd->selected) return EINA_FALSE;
386 if (!wd->multi) return EINA_FALSE;
388 Elm_Gen_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
389 if (!prev) return EINA_TRUE;
391 if (elm_genlist_item_selected_get(prev))
393 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
394 wd->last_selected_item = prev;
395 elm_genlist_item_show(wd->last_selected_item);
399 elm_genlist_item_selected_set(prev, EINA_TRUE);
400 elm_genlist_item_show(prev);
406 _item_multi_select_down(Widget_Data *wd)
408 if (!wd->selected) return EINA_FALSE;
409 if (!wd->multi) return EINA_FALSE;
411 Elm_Gen_Item *next = elm_genlist_item_next_get(wd->last_selected_item);
412 if (!next) return EINA_TRUE;
414 if (elm_genlist_item_selected_get(next))
416 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
417 wd->last_selected_item = next;
418 elm_genlist_item_show(wd->last_selected_item);
422 elm_genlist_item_selected_set(next, EINA_TRUE);
423 elm_genlist_item_show(next);
429 _item_single_select_up(Widget_Data *wd)
434 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
435 while ((prev) && (prev->generation < wd->generation))
436 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
438 else prev = elm_genlist_item_prev_get(wd->last_selected_item);
440 if (!prev) return EINA_FALSE;
442 _deselect_all_items(wd);
444 elm_genlist_item_selected_set(prev, EINA_TRUE);
445 elm_genlist_item_show(prev);
450 _item_single_select_down(Widget_Data *wd)
455 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
456 while ((next) && (next->generation < wd->generation))
457 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
459 else next = elm_genlist_item_next_get(wd->last_selected_item);
461 if (!next) return EINA_FALSE;
463 _deselect_all_items(wd);
465 elm_genlist_item_selected_set(next, EINA_TRUE);
466 elm_genlist_item_show(next);
471 _on_focus_hook(void *data __UNUSED__,
474 Widget_Data *wd = elm_widget_data_get(obj);
476 if (elm_widget_focus_get(obj))
478 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
479 evas_object_focus_set(wd->obj, EINA_TRUE);
480 if ((wd->selected) && (!wd->last_selected_item))
481 wd->last_selected_item = eina_list_data_get(wd->selected);
485 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
486 evas_object_focus_set(wd->obj, EINA_FALSE);
491 _del_hook(Evas_Object *obj)
493 Widget_Data *wd = elm_widget_data_get(obj);
495 _item_cache_zero(wd);
496 if (wd->calc_job) ecore_job_del(wd->calc_job);
497 if (wd->update_job) ecore_job_del(wd->update_job);
498 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
499 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
500 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
501 if (wd->mode_type) eina_stringshare_del(wd->mode_type);
502 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
507 _del_pre_hook(Evas_Object *obj)
509 Widget_Data *wd = elm_widget_data_get(obj);
511 elm_genlist_clear(obj);
512 evas_object_del(wd->pan_smart);
513 wd->pan_smart = NULL;
517 _mirrored_set(Evas_Object *obj,
520 Widget_Data *wd = elm_widget_data_get(obj);
522 _item_cache_zero(wd);
523 elm_smart_scroller_mirrored_set(wd->scr, rtl);
527 _theme_hook(Evas_Object *obj)
529 Widget_Data *wd = elm_widget_data_get(obj);
532 evas_event_freeze(evas_object_evas_get(wd->obj));
533 _item_cache_zero(wd);
534 _elm_widget_mirrored_reload(obj);
535 _mirrored_set(obj, elm_widget_mirrored_get(obj));
536 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
537 elm_widget_style_get(obj));
538 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
539 wd->item_width = wd->item_height = 0;
540 wd->group_item_width = wd->group_item_height = 0;
541 wd->minw = wd->minh = wd->realminw = 0;
542 EINA_INLIST_FOREACH(wd->blocks, itb)
547 if (itb->realized) _item_block_unrealize(itb);
548 EINA_LIST_FOREACH(itb->items, l, it)
549 it->item->mincalcd = EINA_FALSE;
551 itb->changed = EINA_TRUE;
553 if (wd->calc_job) ecore_job_del(wd->calc_job);
554 wd->calc_job = ecore_job_add(_calc_job, wd);
556 evas_event_thaw(evas_object_evas_get(wd->obj));
557 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
561 _show_region_hook(void *data,
564 Widget_Data *wd = elm_widget_data_get(data);
565 Evas_Coord x, y, w, h;
567 elm_widget_show_region_get(obj, &x, &y, &w, &h);
568 //x & y are screen coordinates, Add with pan coordinates
571 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
575 _translate_hook(Evas_Object *obj)
577 evas_object_smart_callback_call(obj, "language,changed", NULL);
581 _sizing_eval(Evas_Object *obj)
583 Widget_Data *wd = elm_widget_data_get(obj);
584 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
586 evas_object_size_hint_min_get(wd->scr, &minw, &minh);
587 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
589 if (wd->height_for_width)
593 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
594 if ((vw != 0) && (vw != wd->prev_viewport_w))
598 wd->prev_viewport_w = vw;
599 EINA_INLIST_FOREACH(wd->blocks, itb)
601 itb->must_recalc = EINA_TRUE;
603 if (wd->calc_job) ecore_job_del(wd->calc_job);
604 wd->calc_job = ecore_job_add(_calc_job, wd);
607 if (wd->mode == ELM_LIST_LIMIT)
613 edje_object_size_min_calc
614 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
621 edje_object_size_min_calc
622 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
626 evas_object_size_hint_min_set(obj, minw, minh);
627 evas_object_size_hint_max_set(obj, maxw, maxh);
631 _signal_emit_hook(Evas_Object *obj,
632 const char *emission,
635 Widget_Data *wd = elm_widget_data_get(obj);
636 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
641 _item_highlight(Elm_Gen_Item *it)
643 const char *selectraise;
644 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->highlighted) ||
645 (it->disabled) || (it->display_only) || (it->item->mode_view))
647 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
648 selectraise = edje_object_data_get(VIEW(it), "selectraise");
649 if ((selectraise) && (!strcmp(selectraise, "on")))
651 evas_object_raise(VIEW(it));
652 if ((it->item->group_item) && (it->item->group_item->realized))
653 evas_object_raise(it->item->VIEW(group_item));
655 it->highlighted = EINA_TRUE;
659 _item_unhighlight(Elm_Gen_Item *it)
661 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
662 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
663 if (!it->item->nostacking)
665 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even) evas_object_lower(VIEW(it));
666 else evas_object_raise(VIEW(it));
668 it->highlighted = EINA_FALSE;
672 _item_block_del(Elm_Gen_Item *it)
675 Item_Block *itb = it->item->block;
677 itb->items = eina_list_remove(itb->items, it);
679 itb->changed = EINA_TRUE;
680 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
681 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
684 il = EINA_INLIST_GET(itb);
685 Item_Block *itbn = (Item_Block *)(il->next);
687 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
689 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
691 if (itbn) itbn->changed = EINA_TRUE;
695 if (itb->count < itb->wd->max_items_per_block/2)
697 il = EINA_INLIST_GET(itb);
698 Item_Block *itbp = (Item_Block *)(il->prev);
699 Item_Block *itbn = (Item_Block *)(il->next);
700 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
704 EINA_LIST_FREE(itb->items, it2)
706 it2->item->block = itbp;
707 itbp->items = eina_list_append(itbp->items, it2);
709 itbp->changed = EINA_TRUE;
711 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
712 EINA_INLIST_GET(itb));
715 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
719 Eina_List *last = eina_list_last(itb->items);
720 Elm_Gen_Item *it2 = last->data;
722 it2->item->block = itbn;
723 itb->items = eina_list_remove_list(itb->items, last);
724 itbn->items = eina_list_prepend(itbn->items, it2);
726 itbn->changed = EINA_TRUE;
729 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
737 _item_del(Elm_Gen_Item *it)
739 Evas_Object *obj = WIDGET(it);
741 evas_event_freeze(evas_object_evas_get(obj));
742 elm_genlist_item_subitems_clear(it);
743 if (it->wd->show_item == it) it->wd->show_item = NULL;
744 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
745 if (it->item->block) _item_block_del(it);
746 if (it->item->queued)
747 it->wd->queue = eina_list_remove(it->wd->queue, it);
748 if (it->wd->anchor_item == it)
750 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
751 if (!it->wd->anchor_item)
752 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
755 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
756 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
757 _elm_genlist_item_del_serious(it);
758 evas_event_thaw(evas_object_evas_get(obj));
759 evas_event_thaw_eval(evas_object_evas_get(obj));
763 _clear_cb(Widget_Data *wd)
765 wd->anchor_item = NULL;
768 Item_Block *itb = (Item_Block *)(wd->blocks);
770 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
771 if (itb->items) eina_list_free(itb->items);
774 if (wd->queue_idle_enterer)
776 ecore_idle_enterer_del(wd->queue_idle_enterer);
777 wd->queue_idle_enterer = NULL;
779 if (wd->must_recalc_idler)
781 ecore_idler_del(wd->must_recalc_idler);
782 wd->must_recalc_idler = NULL;
784 if (wd->queue) wd->queue = eina_list_free(wd->queue);
785 if (wd->reorder_move_animator)
787 ecore_animator_del(wd->reorder_move_animator);
788 wd->reorder_move_animator = NULL;
790 wd->show_item = NULL;
791 wd->reorder_old_pan_y = 0;
795 _item_unselect(Elm_Gen_Item *it)
797 if ((it->generation < it->wd->generation) || (!it->selected)) return;
798 it->selected = EINA_FALSE;
799 it->wd->selected = eina_list_remove(it->wd->selected, it);
800 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
804 _mouse_move(void *data,
805 Evas *evas __UNUSED__,
809 Elm_Gen_Item *it = data;
810 Evas_Event_Mouse_Move *ev = event_info;
811 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
812 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
814 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
816 if (!it->wd->on_hold)
818 it->wd->on_hold = EINA_TRUE;
819 if (!it->wd->wasselected)
821 _item_unhighlight(it);
826 if (it->wd->multitouched)
828 it->wd->cur_x = ev->cur.canvas.x;
829 it->wd->cur_y = ev->cur.canvas.y;
832 if ((it->dragging) && (it->down))
834 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
837 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
838 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
839 if (abs((it->wd->history[it->wd->movements].x -
840 it->wd->history[0].x)) > 40)
841 it->wd->swipe = EINA_TRUE;
847 ecore_timer_del(it->long_timer);
848 it->long_timer = NULL;
850 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
853 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
857 ecore_timer_del(it->long_timer);
858 it->long_timer = NULL;
860 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
862 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
863 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
865 if (!it->wd->reorder_start_y)
866 it->wd->reorder_start_y = it->item->block->y + it->y;
870 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
871 y_pos = oy + oh - it->wd->reorder_it->item->h;
875 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
877 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
878 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
882 if (!it->display_only)
883 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
884 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
885 x = ev->cur.canvas.x - x;
886 y = ev->cur.canvas.y - y;
889 if (adx < 0) adx = -dx;
892 if (ady < 0) ady = -dy;
895 if ((adx > minw) || (ady > minh))
897 it->dragging = EINA_TRUE;
900 ecore_timer_del(it->long_timer);
901 it->long_timer = NULL;
903 if (!it->wd->wasselected)
905 _item_unhighlight(it);
911 evas_object_smart_callback_call(WIDGET(it),
912 SIG_DRAG_START_UP, it);
916 evas_object_smart_callback_call(WIDGET(it),
917 SIG_DRAG_START_LEFT, it);
919 evas_object_smart_callback_call(WIDGET(it),
920 SIG_DRAG_START_RIGHT, it);
926 evas_object_smart_callback_call(WIDGET(it),
927 SIG_DRAG_START_DOWN, it);
931 evas_object_smart_callback_call(WIDGET(it),
932 SIG_DRAG_START_LEFT, it);
934 evas_object_smart_callback_call(WIDGET(it),
935 SIG_DRAG_START_RIGHT, it);
942 _long_press(void *data)
944 Elm_Gen_Item *it = data, *it_tmp;
947 it->long_timer = NULL;
948 if ((it->disabled) || (it->dragging) || (it->display_only))
949 return ECORE_CALLBACK_CANCEL;
950 it->wd->longpressed = EINA_TRUE;
951 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
952 if ((it->wd->reorder_mode) && (!it->group))
954 it->wd->reorder_it = it;
955 it->wd->reorder_start_y = 0;
957 evas_object_raise(VIEW(it));
958 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
959 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
961 list = elm_genlist_realized_items_get(it->wd->obj);
962 EINA_LIST_FOREACH(list, l, it_tmp)
964 if (it != it_tmp) _item_unselect(it_tmp);
966 if (elm_genlist_item_expanded_get(it))
968 elm_genlist_item_expanded_set(it, EINA_FALSE);
969 return ECORE_CALLBACK_RENEW;
971 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
973 return ECORE_CALLBACK_CANCEL;
977 _swipe(Elm_Gen_Item *it)
982 if ((it->display_only) || (it->disabled)) return;
983 it->wd->swipe = EINA_FALSE;
984 for (i = 0; i < it->wd->movements; i++)
986 sum += it->wd->history[i].x;
987 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
990 sum /= it->wd->movements;
991 if (abs(sum - it->wd->history[0].x) <= 10) return;
992 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
996 _swipe_cancel(void *data)
998 Elm_Gen_Item *it = data;
1000 if (!it) return ECORE_CALLBACK_CANCEL;
1001 it->wd->swipe = EINA_FALSE;
1002 it->wd->movements = 0;
1003 return ECORE_CALLBACK_RENEW;
1007 _multi_cancel(void *data)
1009 Widget_Data *wd = data;
1011 if (!wd) return ECORE_CALLBACK_CANCEL;
1012 wd->multi_timeout = EINA_TRUE;
1013 return ECORE_CALLBACK_RENEW;
1017 _multi_touch_gesture_eval(void *data)
1019 Elm_Gen_Item *it = data;
1021 it->wd->multitouched = EINA_FALSE;
1022 if (it->wd->multi_timer)
1024 ecore_timer_del(it->wd->multi_timer);
1025 it->wd->multi_timer = NULL;
1027 if (it->wd->multi_timeout)
1029 it->wd->multi_timeout = EINA_FALSE;
1033 Evas_Coord minw = 0, minh = 0;
1034 Evas_Coord off_x, off_y, off_mx, off_my;
1036 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1037 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1038 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1039 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1040 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1042 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1044 if ((off_x + off_mx) > (off_y + off_my))
1046 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1047 evas_object_smart_callback_call(WIDGET(it),
1048 SIG_MULTI_SWIPE_RIGHT, it);
1049 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1050 evas_object_smart_callback_call(WIDGET(it),
1051 SIG_MULTI_SWIPE_LEFT, it);
1052 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1053 evas_object_smart_callback_call(WIDGET(it),
1054 SIG_MULTI_PINCH_OUT, it);
1056 evas_object_smart_callback_call(WIDGET(it),
1057 SIG_MULTI_PINCH_IN, it);
1061 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1062 evas_object_smart_callback_call(WIDGET(it),
1063 SIG_MULTI_SWIPE_DOWN, it);
1064 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1065 evas_object_smart_callback_call(WIDGET(it),
1066 SIG_MULTI_SWIPE_UP, it);
1067 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1068 evas_object_smart_callback_call(WIDGET(it),
1069 SIG_MULTI_PINCH_OUT, it);
1071 evas_object_smart_callback_call(WIDGET(it),
1072 SIG_MULTI_PINCH_IN, it);
1075 it->wd->multi_timeout = EINA_FALSE;
1079 _multi_down(void *data,
1080 Evas *evas __UNUSED__,
1081 Evas_Object *obj __UNUSED__,
1084 Elm_Gen_Item *it = data;
1085 Evas_Event_Multi_Down *ev = event_info;
1087 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1088 it->wd->multi_device = ev->device;
1089 it->wd->multi_down = EINA_TRUE;
1090 it->wd->multitouched = EINA_TRUE;
1091 it->wd->prev_mx = ev->canvas.x;
1092 it->wd->prev_my = ev->canvas.y;
1093 if (!it->wd->wasselected)
1095 _item_unhighlight(it);
1098 it->wd->wasselected = EINA_FALSE;
1099 it->wd->longpressed = EINA_FALSE;
1102 ecore_timer_del(it->long_timer);
1103 it->long_timer = NULL;
1107 it->dragging = EINA_FALSE;
1108 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1110 if (it->item->swipe_timer)
1112 ecore_timer_del(it->item->swipe_timer);
1113 it->item->swipe_timer = NULL;
1115 if (it->wd->on_hold)
1117 it->wd->swipe = EINA_FALSE;
1118 it->wd->movements = 0;
1119 it->wd->on_hold = EINA_FALSE;
1124 _multi_up(void *data,
1125 Evas *evas __UNUSED__,
1126 Evas_Object *obj __UNUSED__,
1129 Elm_Gen_Item *it = data;
1130 Evas_Event_Multi_Up *ev = event_info;
1132 if (it->wd->multi_device != ev->device) return;
1133 it->wd->multi_device = 0;
1134 it->wd->multi_down = EINA_FALSE;
1135 if (it->wd->mouse_down) return;
1136 _multi_touch_gesture_eval(data);
1140 _multi_move(void *data,
1141 Evas *evas __UNUSED__,
1142 Evas_Object *obj __UNUSED__,
1145 Elm_Gen_Item *it = data;
1146 Evas_Event_Multi_Move *ev = event_info;
1148 if (it->wd->multi_device != ev->device) return;
1149 it->wd->cur_mx = ev->cur.canvas.x;
1150 it->wd->cur_my = ev->cur.canvas.y;
1154 _mouse_down(void *data,
1155 Evas *evas __UNUSED__,
1159 Elm_Gen_Item *it = data;
1160 Evas_Event_Mouse_Down *ev = event_info;
1163 if (ev->button != 1) return;
1164 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1166 it->wd->on_hold = EINA_TRUE;
1169 it->down = EINA_TRUE;
1170 it->dragging = EINA_FALSE;
1171 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1172 it->dx = ev->canvas.x - x;
1173 it->dy = ev->canvas.y - y;
1174 it->wd->mouse_down = EINA_TRUE;
1175 if (!it->wd->multitouched)
1177 it->wd->prev_x = ev->canvas.x;
1178 it->wd->prev_y = ev->canvas.y;
1179 it->wd->multi_timeout = EINA_FALSE;
1180 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1181 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1183 it->wd->longpressed = EINA_FALSE;
1184 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1185 else it->wd->on_hold = EINA_FALSE;
1186 if (it->wd->on_hold) return;
1187 it->wd->wasselected = it->selected;
1188 _item_highlight(it);
1189 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1190 if ((!it->disabled) && (!it->display_only))
1192 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1193 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1195 if (it->long_timer) ecore_timer_del(it->long_timer);
1196 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1197 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1199 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1202 it->long_timer = NULL;
1203 it->wd->swipe = EINA_FALSE;
1204 it->wd->movements = 0;
1208 _mouse_up(void *data,
1209 Evas *evas __UNUSED__,
1210 Evas_Object *obj __UNUSED__,
1213 Elm_Gen_Item *it = data;
1214 Evas_Event_Mouse_Up *ev = event_info;
1215 Eina_Bool dragged = EINA_FALSE;
1217 if (ev->button != 1) return;
1218 it->down = EINA_FALSE;
1219 it->wd->mouse_down = EINA_FALSE;
1220 if (it->wd->multitouched)
1222 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1223 if (it->wd->multi_down) return;
1224 _multi_touch_gesture_eval(data);
1227 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1228 else it->wd->on_hold = EINA_FALSE;
1231 ecore_timer_del(it->long_timer);
1232 it->long_timer = NULL;
1236 it->dragging = EINA_FALSE;
1237 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1240 if (it->item->swipe_timer)
1242 ecore_timer_del(it->item->swipe_timer);
1243 it->item->swipe_timer = NULL;
1245 if (it->wd->multi_timer)
1247 ecore_timer_del(it->wd->multi_timer);
1248 it->wd->multi_timer = NULL;
1249 it->wd->multi_timeout = EINA_FALSE;
1251 if (it->wd->on_hold)
1253 if (it->wd->swipe) _swipe(data);
1254 it->wd->longpressed = EINA_FALSE;
1255 it->wd->on_hold = EINA_FALSE;
1258 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1260 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1262 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1264 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1265 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1267 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1271 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1272 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1274 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1275 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1276 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1277 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1279 if (it->wd->longpressed)
1281 it->wd->longpressed = EINA_FALSE;
1282 if (!it->wd->wasselected)
1284 _item_unhighlight(it);
1287 it->wd->wasselected = EINA_FALSE;
1292 if (it->want_unrealize)
1294 _elm_genlist_item_unrealize(it, EINA_FALSE);
1295 if (it->item->block->want_unrealize)
1296 _item_block_unrealize(it->item->block);
1299 if ((it->disabled) || (dragged) || (it->display_only)) return;
1300 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1305 _item_highlight(it);
1310 _item_unhighlight(it);
1318 Widget_Data *wd = it->wd;
1321 while (wd->selected)
1323 _item_unhighlight(wd->selected->data);
1324 _item_unselect(wd->selected->data);
1330 const Eina_List *l, *l_next;
1333 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1336 _item_unhighlight(it2);
1337 _item_unselect(it2);
1339 //_item_highlight(it);
1342 _item_highlight(it);
1348 _signal_expand_toggle(void *data,
1349 Evas_Object *obj __UNUSED__,
1350 const char *emission __UNUSED__,
1351 const char *source __UNUSED__)
1353 Elm_Gen_Item *it = data;
1355 if (it->item->expanded)
1356 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1358 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1362 _signal_expand(void *data,
1363 Evas_Object *obj __UNUSED__,
1364 const char *emission __UNUSED__,
1365 const char *source __UNUSED__)
1367 Elm_Gen_Item *it = data;
1369 if (!it->item->expanded)
1370 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1374 _signal_contract(void *data,
1375 Evas_Object *obj __UNUSED__,
1376 const char *emission __UNUSED__,
1377 const char *source __UNUSED__)
1379 Elm_Gen_Item *it = data;
1381 if (it->item->expanded)
1382 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1386 _scr_hold_timer_cb(void *data)
1388 if (!data) return ECORE_CALLBACK_CANCEL;
1389 Widget_Data *wd = data;
1390 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1391 wd->scr_hold_timer = NULL;
1392 return ECORE_CALLBACK_CANCEL;
1396 _mode_finished_signal_cb(void *data,
1398 const char *emission __UNUSED__,
1399 const char *source __UNUSED__)
1403 Elm_Gen_Item *it = data;
1404 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1406 Evas *te = evas_object_evas_get(obj);
1408 evas_event_freeze(te);
1409 it->item->nocache = EINA_FALSE;
1410 _mode_item_unrealize(it);
1411 if (it->item->group_item)
1412 evas_object_raise(it->item->VIEW(group_item));
1413 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->mode_type);
1414 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1415 evas_event_thaw(te);
1416 evas_event_thaw_eval(te);
1420 _item_cache_clean(Widget_Data *wd)
1422 evas_event_freeze(evas_object_evas_get(wd->obj));
1423 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1427 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1428 wd->item_cache = eina_inlist_remove(wd->item_cache,
1429 wd->item_cache->last);
1430 wd->item_cache_count--;
1431 if (itc->spacer) evas_object_del(itc->spacer);
1432 if (itc->base_view) evas_object_del(itc->base_view);
1433 if (itc->item_style) eina_stringshare_del(itc->item_style);
1436 evas_event_thaw(evas_object_evas_get(wd->obj));
1437 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1441 _item_cache_zero(Widget_Data *wd)
1443 int pmax = wd->item_cache_max;
1444 wd->item_cache_max = 0;
1445 _item_cache_clean(wd);
1446 wd->item_cache_max = pmax;
1450 _item_cache_add(Elm_Gen_Item *it)
1454 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1455 if (it->wd->item_cache_max <= 0)
1457 evas_object_del(VIEW(it));
1459 evas_object_del(it->spacer);
1461 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1462 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1466 it->wd->item_cache_count++;
1467 itc = calloc(1, sizeof(Item_Cache));
1468 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1469 EINA_INLIST_GET(itc));
1470 itc->spacer = it->spacer;
1472 itc->base_view = VIEW(it);
1474 evas_object_hide(itc->base_view);
1475 evas_object_move(itc->base_view, -9999, -9999);
1476 itc->item_style = eina_stringshare_add(it->itc->item_style);
1477 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) itc->tree = 1;
1478 itc->compress = (it->wd->compress);
1479 itc->selected = it->selected;
1480 itc->disabled = it->disabled;
1481 itc->expanded = it->item->expanded;
1484 ecore_timer_del(it->long_timer);
1485 it->long_timer = NULL;
1487 if (it->item->swipe_timer)
1489 ecore_timer_del(it->item->swipe_timer);
1490 it->item->swipe_timer = NULL;
1492 // FIXME: other callbacks?
1493 edje_object_signal_callback_del_full(itc->base_view,
1494 "elm,action,expand,toggle",
1495 "elm", _signal_expand_toggle, it);
1496 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1498 _signal_expand, it);
1499 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1500 "elm", _signal_contract, it);
1501 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1503 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1505 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1507 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1509 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1511 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1513 _item_cache_clean(it->wd);
1514 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1515 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1519 _item_cache_find(Elm_Gen_Item *it)
1524 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) tree = 1;
1525 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1527 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1529 if ((itc->tree == tree) &&
1530 (itc->compress == it->wd->compress) &&
1531 (!strcmp(it->itc->item_style, itc->item_style)))
1533 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1534 EINA_INLIST_GET(itc));
1535 it->wd->item_cache_count--;
1543 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1545 if (!it->item->nostacking)
1547 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1548 evas_object_lower(VIEW(it));
1550 evas_object_raise(VIEW(it));
1553 if (it->item->order_num_in & 0x1)
1554 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1556 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1560 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1564 if (it->selected != itc->selected)
1567 edje_object_signal_emit(VIEW(it),
1568 "elm,state,selected", "elm");
1570 if (it->disabled != itc->disabled)
1573 edje_object_signal_emit(VIEW(it),
1574 "elm,state,disabled", "elm");
1576 if (it->item->expanded != itc->expanded)
1578 if (it->item->expanded)
1579 edje_object_signal_emit(VIEW(it),
1580 "elm,state,expanded", "elm");
1586 edje_object_signal_emit(VIEW(it),
1587 "elm,state,selected", "elm");
1589 edje_object_signal_emit(VIEW(it),
1590 "elm,state,disabled", "elm");
1591 if (it->item->expanded)
1592 edje_object_signal_emit(VIEW(it),
1593 "elm,state,expanded", "elm");
1598 _item_cache_free(Item_Cache *itc)
1600 if (itc->spacer) evas_object_del(itc->spacer);
1601 if (itc->base_view) evas_object_del(itc->base_view);
1602 if (itc->item_style) eina_stringshare_del(itc->item_style);
1607 _item_del_hook(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1609 Elm_Gen_Item *it = event_info;
1611 if (it->wd->last_selected_item == it)
1612 it->wd->last_selected_item = NULL;
1616 _item_label_realize(Elm_Gen_Item *it,
1617 Evas_Object *target,
1621 if (it->itc->func.text_get)
1626 *source = elm_widget_stringlist_get(edje_object_data_get(target, "labels"));
1627 EINA_LIST_FOREACH(*source, l, key)
1629 if (parts && fnmatch(parts, key, FNM_PERIOD))
1632 char *s = it->itc->func.text_get
1633 ((void *)it->base.data, WIDGET(it), key);
1637 edje_object_part_text_set(target, key, s);
1642 edje_object_part_text_set(target, key, "");
1649 _item_content_unrealize(Elm_Gen_Item *it,
1650 Evas_Object *target,
1654 Eina_List *res = it->content_objs;
1656 if (it->itc->func.content_get)
1660 Evas_Object *ic = NULL;
1662 EINA_LIST_FOREACH(*source, l, key)
1664 if (parts && fnmatch(parts, key, FNM_PERIOD))
1667 ic = edje_object_part_swallow_get(target, key);
1670 res = eina_list_remove(res, ic);
1671 edje_object_part_unswallow(target, ic);
1672 evas_object_del(ic);
1681 _item_content_realize(Elm_Gen_Item *it,
1682 Evas_Object *target,
1686 Eina_List *res = NULL;
1688 if (it->itc->func.content_get)
1692 Evas_Object *ic = NULL;
1694 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1696 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
1697 res = it->content_objs;
1699 EINA_LIST_FOREACH(*source, l, key)
1701 if (parts && fnmatch(parts, key, FNM_PERIOD))
1704 if (it->itc->func.content_get)
1705 ic = it->itc->func.content_get
1706 ((void *)it->base.data, WIDGET(it), key);
1709 res = eina_list_append(res, ic);
1710 edje_object_part_swallow(target, key, ic);
1711 evas_object_show(ic);
1712 elm_widget_sub_object_add(WIDGET(it), ic);
1714 elm_widget_disabled_set(ic, EINA_TRUE);
1723 _item_state_realize(Elm_Gen_Item *it,
1724 Evas_Object *target,
1728 if (it->itc->func.state_get)
1734 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
1735 EINA_LIST_FOREACH(*source, l, key)
1737 if (parts && fnmatch(parts, key, FNM_PERIOD))
1740 Eina_Bool on = it->itc->func.state_get
1741 ((void *)it->base.data, WIDGET(it), key);
1745 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1746 edje_object_signal_emit(target, buf, "elm");
1750 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1751 edje_object_signal_emit(target, buf, "elm");
1758 _item_realize(Elm_Gen_Item *it,
1762 const char *treesize;
1765 Item_Cache *itc = NULL;
1767 if (it->generation < it->wd->generation) return;
1768 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1771 if (it->item->order_num_in != in)
1773 it->item->order_num_in = in;
1774 _elm_genlist_item_odd_even_update(it);
1775 _elm_genlist_item_state_update(it, NULL);
1777 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1778 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1781 it->item->order_num_in = in;
1783 if (it->item->nocache)
1784 it->item->nocache = EINA_FALSE;
1786 itc = _item_cache_find(it);
1789 VIEW(it) = itc->base_view;
1790 itc->base_view = NULL;
1791 it->spacer = itc->spacer;
1796 const char *stacking_even;
1797 const char *stacking;
1799 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1800 edje_object_scale_set(VIEW(it),
1801 elm_widget_scale_get(WIDGET(it)) *
1802 _elm_config->scale);
1803 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
1804 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1806 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
1807 strncpy(buf, "tree", sizeof(buf));
1808 else strncpy(buf, "item", sizeof(buf));
1809 if (it->wd->compress)
1810 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1812 strncat(buf, "/", sizeof(buf) - strlen(buf));
1813 strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1815 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
1816 elm_widget_style_get(WIDGET(it)));
1818 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1819 if (!stacking_even) stacking_even = "above";
1820 it->item->stacking_even = !!strcmp("above", stacking_even);
1822 stacking = edje_object_data_get(VIEW(it), "stacking");
1823 if (!stacking) stacking = "yes";
1824 it->item->nostacking = !!strcmp("yes", stacking);
1826 edje_object_mirrored_set(VIEW(it),
1827 elm_widget_mirrored_get(WIDGET(it)));
1829 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1830 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1831 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1834 _elm_genlist_item_odd_even_update(it);
1836 treesize = edje_object_data_get(VIEW(it), "treesize");
1837 if (treesize) tsize = atoi(treesize);
1838 evas_object_size_hint_min_set(it->spacer,
1839 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
1840 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1843 edje_object_signal_callback_add(VIEW(it),
1844 "elm,action,expand,toggle",
1845 "elm", _signal_expand_toggle, it);
1846 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
1847 "elm", _signal_expand, it);
1848 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
1849 "elm", _signal_contract, it);
1850 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
1852 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
1854 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1856 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
1858 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
1860 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
1863 _elm_genlist_item_state_update(it, itc);
1866 if ((calc) && (it->wd->homogeneous) &&
1867 ((it->wd->item_width) ||
1868 ((it->wd->item_width) && (it->wd->group_item_width))))
1870 /* homogenous genlist shortcut */
1871 if (!it->item->mincalcd)
1875 it->item->w = it->item->minw = it->wd->group_item_width;
1876 it->item->h = it->item->minh = it->wd->group_item_height;
1880 it->item->w = it->item->minw = it->wd->item_width;
1881 it->item->h = it->item->minh = it->wd->item_height;
1883 it->item->mincalcd = EINA_TRUE;
1888 /* FIXME: If you see that assert, please notify us and we
1889 will clean our mess */
1890 assert(eina_list_count(it->content_objs) == 0);
1892 _item_label_realize(it, VIEW(it), &it->labels, NULL);
1893 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
1894 _item_state_realize(it, VIEW(it), &it->states, NULL);
1896 if (!it->item->mincalcd)
1898 Evas_Coord mw = -1, mh = -1;
1900 if (!it->display_only)
1901 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1902 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
1903 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
1905 if (!it->display_only)
1906 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1907 it->item->w = it->item->minw = mw;
1908 it->item->h = it->item->minh = mh;
1909 it->item->mincalcd = EINA_TRUE;
1911 if ((!it->wd->group_item_width) && (it->group))
1913 it->wd->group_item_width = mw;
1914 it->wd->group_item_height = mh;
1916 else if ((!it->wd->item_width) && (it->item->flags == ELM_GENLIST_ITEM_NONE))
1918 it->wd->item_width = mw;
1919 it->wd->item_height = mh;
1922 if (!calc) evas_object_show(VIEW(it));
1925 if (it->tooltip.content_cb)
1927 elm_widget_item_tooltip_content_cb_set(it,
1928 it->tooltip.content_cb,
1929 it->tooltip.data, NULL);
1930 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1931 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1934 if (it->mouse_cursor)
1935 elm_widget_item_cursor_set(it, it->mouse_cursor);
1937 it->realized = EINA_TRUE;
1938 it->want_unrealize = EINA_FALSE;
1940 if (itc) _item_cache_free(itc);
1941 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1942 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1944 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1945 edje_object_message_signal_process(VIEW(it));
1949 _item_unrealize_cb(Elm_Gen_Item *it)
1951 if (it->item->nocache)
1953 evas_object_del(VIEW(it));
1955 evas_object_del(it->spacer);
1960 edje_object_mirrored_set(VIEW(it),
1961 elm_widget_mirrored_get(WIDGET(it)));
1962 edje_object_scale_set(VIEW(it),
1963 elm_widget_scale_get(WIDGET(it))
1964 * _elm_config->scale);
1965 _item_cache_add(it);
1968 _mode_item_unrealize(it);
1970 it->realized = EINA_FALSE;
1971 it->want_unrealize = EINA_FALSE;
1975 _item_block_recalc(Item_Block *itb,
1981 Evas_Coord minw = 0, minh = 0;
1982 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
1985 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
1987 EINA_LIST_FOREACH(itb->items, l, it)
1989 if (it->generation < it->wd->generation) continue;
1990 showme |= it->item->showme;
1995 if (!it->item->mincalcd) changed = EINA_TRUE;
1998 _item_realize(it, in, EINA_TRUE);
1999 _elm_genlist_item_unrealize(it, EINA_TRUE);
2004 _item_realize(it, in, EINA_TRUE);
2005 _elm_genlist_item_unrealize(it, EINA_TRUE);
2009 _item_realize(it, in, EINA_FALSE);
2010 minh += it->item->minh;
2011 if (minw < it->item->minw) minw = it->item->minw;
2019 itb->changed = EINA_FALSE;
2020 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2021 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2026 _item_block_realize(Item_Block *itb)
2028 if (itb->realized) return;
2029 itb->realized = EINA_TRUE;
2030 itb->want_unrealize = EINA_FALSE;
2034 _item_block_unrealize(Item_Block *itb)
2038 Eina_Bool dragging = EINA_FALSE;
2040 if (!itb->realized) return;
2041 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2042 EINA_LIST_FOREACH(itb->items, l, it)
2048 dragging = EINA_TRUE;
2049 it->want_unrealize = EINA_TRUE;
2052 _elm_genlist_item_unrealize(it, EINA_FALSE);
2057 itb->realized = EINA_FALSE;
2058 itb->want_unrealize = EINA_TRUE;
2061 itb->want_unrealize = EINA_FALSE;
2062 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2063 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2067 _get_space_for_reorder_item(Elm_Gen_Item *it)
2069 Evas_Coord rox, roy, row, roh, oy, oh;
2070 Eina_Bool top = EINA_FALSE;
2071 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2072 if (!reorder_it) return 0;
2074 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2075 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2077 if ((it->wd->reorder_start_y < it->item->block->y) &&
2078 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2080 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2081 if (it->item->block->count == 1)
2082 it->wd->reorder_rel = it;
2084 else 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;
2090 it->item->block->reorder_offset = 0;
2092 it->item->scrl_y += it->item->block->reorder_offset;
2094 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2095 rox, roy + (roh / 2), row, 1));
2098 it->wd->reorder_rel = it;
2099 it->item->scrl_y += it->wd->reorder_it->item->h;
2100 return it->wd->reorder_it->item->h;
2107 _reorder_move_animator_cb(void *data)
2109 Elm_Gen_Item *it = data;
2110 Eina_Bool down = EINA_FALSE;
2112 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2114 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2116 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2119 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2120 if (diff > it->item->h) y = diff / 2;
2122 if (it->item->old_scrl_y < it->item->scrl_y)
2124 it->item->old_scrl_y += y;
2127 else if (it->item->old_scrl_y > it->item->scrl_y)
2129 it->item->old_scrl_y -= y;
2132 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2133 _group_items_recalc(it->wd);
2135 if ((it->wd->reorder_pan_move) ||
2136 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2137 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2139 it->item->old_scrl_y = it->item->scrl_y;
2140 it->item->move_effect_enabled = EINA_FALSE;
2141 it->wd->reorder_move_animator = NULL;
2142 return ECORE_CALLBACK_CANCEL;
2144 return ECORE_CALLBACK_RENEW;
2148 _item_position(Elm_Gen_Item *it,
2156 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2157 evas_object_resize(view, it->item->w, it->item->h);
2158 evas_object_move(view, it_x, it_y);
2159 //fprintf(stderr, "it: %p, x %d y %d\n", view, it_x, it_y);
2160 evas_object_show(view);
2161 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2162 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2166 _item_block_position(Item_Block *itb,
2172 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2173 Eina_Bool vis = EINA_FALSE;
2175 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2176 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2177 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2179 EINA_LIST_FOREACH(itb->items, l, it)
2181 if (it->generation < it->wd->generation) continue;
2182 else if (it->wd->reorder_it == it) continue;
2185 it->item->w = itb->w;
2186 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2187 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2189 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2190 cvx, cvy, cvw, cvh));
2193 if ((itb->realized) && (!it->realized))
2195 if (vis) _item_realize(it, in, EINA_FALSE);
2201 if (it->wd->reorder_mode)
2202 y += _get_space_for_reorder_item(it);
2203 git = it->item->group_item;
2206 if (git->item->scrl_y < oy)
2207 git->item->scrl_y = oy;
2208 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2209 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2210 git->item->want_realize = EINA_TRUE;
2212 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2214 if (!it->item->move_effect_enabled)
2216 it->item->move_effect_enabled = EINA_TRUE;
2217 it->wd->reorder_move_animator =
2219 _reorder_move_animator_cb, it);
2222 if (!it->item->move_effect_enabled)
2224 //fprintf(stderr, "it %p itb->y %d it->y %d pan_y %d oy %d\n", it, itb->y, it->y, it->wd->pan_y, oy);
2225 if (it->item->mode_view)
2226 _item_position(it, it->item->mode_view, it->item->scrl_x,
2229 _item_position(it, VIEW(it), it->item->scrl_x,
2231 it->item->old_scrl_y = it->item->scrl_y;
2236 if (!it->dragging) _elm_genlist_item_unrealize(it, EINA_FALSE);
2243 if (vis) it->item->want_realize = EINA_TRUE;
2247 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2248 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2252 _group_items_recalc(void *data)
2254 Widget_Data *wd = data;
2258 evas_event_freeze(evas_object_evas_get(wd->obj));
2259 EINA_LIST_FOREACH(wd->group_items, l, git)
2261 if (git->item->want_realize)
2264 _item_realize(git, 0, EINA_FALSE);
2265 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2266 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2267 evas_object_show(VIEW(git));
2268 evas_object_raise(VIEW(git));
2270 else if (!git->item->want_realize && git->realized)
2273 _elm_genlist_item_unrealize(git, EINA_FALSE);
2276 evas_event_thaw(evas_object_evas_get(wd->obj));
2277 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2281 _must_recalc_idler(void *data)
2283 Widget_Data *wd = data;
2284 if (wd->calc_job) ecore_job_del(wd->calc_job);
2285 wd->calc_job = ecore_job_add(_calc_job, wd);
2286 wd->must_recalc_idler = NULL;
2287 return ECORE_CALLBACK_CANCEL;
2291 _scroll_item(Widget_Data *wd)
2293 wd->show_item->item->showme = EINA_FALSE;
2295 elm_smart_scroller_region_bring_in(wd->scr,
2297 wd->show_item->item->block->x,
2299 wd->show_item->item->block->y,
2300 wd->show_item->item->block->w,
2301 wd->show_item->item->h);
2303 elm_smart_scroller_child_region_show(wd->scr,
2305 wd->show_item->item->block->x,
2307 wd->show_item->item->block->y,
2308 wd->show_item->item->block->w,
2309 wd->show_item->item->h);
2310 wd->show_item = NULL;
2314 _calc_job(void *data)
2316 Widget_Data *wd = data;
2317 Item_Block *itb, *chb = NULL;
2318 Evas_Coord minw = -1, minh = 0, y = 0, ow;
2320 Eina_Bool minw_change = EINA_FALSE;
2321 Eina_Bool did_must_recalc = EINA_FALSE;
2322 Evas_Coord pan_w = 0, pan_h = 0;
2323 static Eina_Bool check_scroll = EINA_FALSE;
2326 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2330 evas_event_freeze(evas_object_evas_get(wd->obj));
2331 EINA_INLIST_FOREACH(wd->blocks, itb)
2333 Eina_Bool showme = EINA_FALSE;
2336 showme = itb->showme;
2337 itb->showme = EINA_FALSE;
2340 if (itb->realized) _item_block_unrealize(itb);
2342 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2344 if (itb->must_recalc)
2348 EINA_LIST_FOREACH(itb->items, l, it)
2349 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2350 itb->changed = EINA_TRUE;
2351 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2352 itb->must_recalc = EINA_FALSE;
2354 if (itb->realized) _item_block_unrealize(itb);
2355 showme = _item_block_recalc(itb, in, EINA_FALSE);
2361 if (minw == -1) minw = itb->minw;
2362 else if ((!itb->must_recalc) && (minw < itb->minw))
2365 minw_change = EINA_TRUE;
2372 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2373 check_scroll = EINA_TRUE;
2376 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2377 if (ELM_RECTS_INTERSECT(
2379 wd->show_item->x + wd->show_item->item->block->x,
2380 wd->show_item->y + wd->show_item->item->block->y,
2381 wd->show_item->item->block->w,
2382 wd->show_item->item->h
2386 check_scroll = EINA_FALSE;
2389 //fprintf(stderr, "bring in %d %d %d %d : pan child %d %d\n", wd->show_item->x + wd->show_item->item->block->x, wd->show_item->y + wd->show_item->item->block->y, wd->show_item->item->block->w, wd->show_item->item->h, pan_w, pan_h);
2393 EINA_INLIST_FOREACH(wd->blocks, itb)
2399 if ((chb) && (EINA_INLIST_GET(chb)->next))
2401 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2403 if (itb->realized) _item_block_unrealize(itb);
2406 wd->realminw = minw;
2407 if (minw < wd->w) minw = wd->w;
2408 if ((minw != wd->minw) || (minh != wd->minh))
2412 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2413 _sizing_eval(wd->obj);
2414 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2419 it = wd->anchor_item;
2420 it_y = wd->anchor_y;
2421 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2422 it->item->block->y + it->y + it_y);
2423 wd->anchor_item = it;
2424 wd->anchor_y = it_y;
2427 if (did_must_recalc)
2429 if (!wd->must_recalc_idler)
2430 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2432 wd->calc_job = NULL;
2433 evas_object_smart_changed(wd->pan_smart);
2434 evas_event_thaw(evas_object_evas_get(wd->obj));
2435 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2439 _update_job(void *data)
2441 Widget_Data *wd = data;
2445 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2447 wd->update_job = NULL;
2450 evas_event_freeze(evas_object_evas_get(wd->obj));
2451 EINA_INLIST_FOREACH(wd->blocks, itb)
2453 Evas_Coord itminw, itminh;
2460 _item_block_position(itb, num);
2464 recalc = EINA_FALSE;
2465 EINA_LIST_FOREACH(itb->items, l2, it)
2467 if (it->item->updateme)
2469 itminw = it->item->minw;
2470 itminh = it->item->minh;
2472 it->item->updateme = EINA_FALSE;
2475 _elm_genlist_item_unrealize(it, EINA_FALSE);
2476 _item_realize(it, num, EINA_FALSE);
2477 position = EINA_TRUE;
2481 _item_realize(it, num, EINA_TRUE);
2482 _elm_genlist_item_unrealize(it, EINA_TRUE);
2484 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2489 itb->updateme = EINA_FALSE;
2492 position = EINA_TRUE;
2493 itb->changed = EINA_TRUE;
2494 _item_block_recalc(itb, num0, EINA_FALSE);
2495 _item_block_position(itb, num0);
2500 if (wd->calc_job) ecore_job_del(wd->calc_job);
2501 wd->calc_job = ecore_job_add(_calc_job, wd);
2503 evas_event_thaw(evas_object_evas_get(wd->obj));
2504 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2508 _pan_set(Evas_Object *obj,
2512 Pan *sd = evas_object_smart_data_get(obj);
2516 // Evas_Coord ow, oh;
2517 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2518 // ow = sd->wd->minw - ow;
2519 // if (ow < 0) ow = 0;
2520 // oh = sd->wd->minh - oh;
2521 // if (oh < 0) oh = 0;
2522 // if (x < 0) x = 0;
2523 // if (y < 0) y = 0;
2524 // if (x > ow) x = ow;
2525 // if (y > oh) y = oh;
2526 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2527 //fprintf(stderr, "pan_y %d\n", y);
2531 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2533 if ((itb->y + itb->h) > y)
2538 EINA_LIST_FOREACH(itb->items, l2, it)
2540 if ((itb->y + it->y) >= y)
2542 sd->wd->anchor_item = it;
2543 sd->wd->anchor_y = -(itb->y + it->y - y);
2550 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2554 _pan_get(Evas_Object *obj,
2558 Pan *sd = evas_object_smart_data_get(obj);
2561 if (x) *x = sd->wd->pan_x;
2562 if (y) *y = sd->wd->pan_y;
2566 _pan_max_get(Evas_Object *obj,
2570 Pan *sd = evas_object_smart_data_get(obj);
2574 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2575 ow = sd->wd->minw - ow;
2577 oh = sd->wd->minh - oh;
2584 _pan_min_get(Evas_Object *obj __UNUSED__,
2593 _pan_child_size_get(Evas_Object *obj,
2597 Pan *sd = evas_object_smart_data_get(obj);
2600 if (w) *w = sd->wd->minw;
2601 if (h) *h = sd->wd->minh;
2605 _pan_add(Evas_Object *obj)
2608 Evas_Object_Smart_Clipped_Data *cd;
2611 cd = evas_object_smart_data_get(obj);
2614 sd->__clipped_data = *cd;
2616 evas_object_smart_data_set(obj, sd);
2620 _pan_del(Evas_Object *obj)
2622 Pan *sd = evas_object_smart_data_get(obj);
2627 ecore_job_del(sd->resize_job);
2628 sd->resize_job = NULL;
2634 _pan_resize_job(void *data)
2638 _sizing_eval(sd->wd->obj);
2639 sd->resize_job = NULL;
2643 _pan_resize(Evas_Object *obj,
2647 Pan *sd = evas_object_smart_data_get(obj);
2651 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2652 if ((ow == w) && (oh == h)) return;
2653 if ((sd->wd->height_for_width) && (ow != w))
2656 if (sd->resize_job) ecore_job_del(sd->resize_job);
2657 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2659 sd->wd->pan_resized = EINA_TRUE;
2660 evas_object_smart_changed(obj);
2661 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2662 sd->wd->calc_job = NULL;
2664 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2665 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2670 _pan_calculate(Evas_Object *obj)
2672 Pan *sd = evas_object_smart_data_get(obj);
2674 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2680 evas_event_freeze(evas_object_evas_get(obj));
2682 if (sd->wd->pan_resized)
2685 sd->wd->pan_resized = EINA_FALSE;
2688 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2689 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2690 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2692 git->item->want_realize = EINA_FALSE;
2694 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2696 itb->w = sd->wd->minw;
2697 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2698 itb->y - sd->wd->pan_y + oy,
2700 cvx, cvy, cvw, cvh))
2702 if ((!itb->realized) || (itb->changed))
2703 _item_block_realize(itb);
2704 _item_block_position(itb, in);
2708 if (itb->realized) _item_block_unrealize(itb);
2712 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2713 _group_items_recalc(sd->wd);
2714 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2716 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2717 sd->wd->reorder_pan_move = EINA_TRUE;
2718 else sd->wd->reorder_pan_move = EINA_FALSE;
2719 evas_object_raise(sd->wd->VIEW(reorder_it));
2720 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2721 sd->wd->start_time = ecore_loop_time_get();
2723 _item_auto_scroll(sd->wd);
2724 evas_event_thaw(evas_object_evas_get(obj));
2725 evas_event_thaw_eval(evas_object_evas_get(obj));
2729 _pan_move(Evas_Object *obj,
2730 Evas_Coord x __UNUSED__,
2731 Evas_Coord y __UNUSED__)
2733 Pan *sd = evas_object_smart_data_get(obj);
2736 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2737 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2741 _hold_on(void *data __UNUSED__,
2743 void *event_info __UNUSED__)
2745 Widget_Data *wd = elm_widget_data_get(obj);
2747 elm_smart_scroller_hold_set(wd->scr, 1);
2751 _hold_off(void *data __UNUSED__,
2753 void *event_info __UNUSED__)
2755 Widget_Data *wd = elm_widget_data_get(obj);
2757 elm_smart_scroller_hold_set(wd->scr, 0);
2761 _freeze_on(void *data __UNUSED__,
2763 void *event_info __UNUSED__)
2765 Widget_Data *wd = elm_widget_data_get(obj);
2767 elm_smart_scroller_freeze_set(wd->scr, 1);
2771 _freeze_off(void *data __UNUSED__,
2773 void *event_info __UNUSED__)
2775 Widget_Data *wd = elm_widget_data_get(obj);
2777 elm_smart_scroller_freeze_set(wd->scr, 0);
2781 _scr_anim_start(void *data,
2782 Evas_Object *obj __UNUSED__,
2783 void *event_info __UNUSED__)
2785 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
2789 _scr_anim_stop(void *data,
2790 Evas_Object *obj __UNUSED__,
2791 void *event_info __UNUSED__)
2793 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
2797 _scr_drag_start(void *data,
2798 Evas_Object *obj __UNUSED__,
2799 void *event_info __UNUSED__)
2801 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
2805 _scr_drag_stop(void *data,
2806 Evas_Object *obj __UNUSED__,
2807 void *event_info __UNUSED__)
2809 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
2813 _edge_left(void *data,
2814 Evas_Object *scr __UNUSED__,
2815 void *event_info __UNUSED__)
2817 Evas_Object *obj = data;
2818 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2822 _edge_right(void *data,
2823 Evas_Object *scr __UNUSED__,
2824 void *event_info __UNUSED__)
2826 Evas_Object *obj = data;
2827 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2831 _edge_top(void *data,
2832 Evas_Object *scr __UNUSED__,
2833 void *event_info __UNUSED__)
2835 Evas_Object *obj = data;
2836 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2840 _edge_bottom(void *data,
2841 Evas_Object *scr __UNUSED__,
2842 void *event_info __UNUSED__)
2844 Evas_Object *obj = data;
2845 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2849 _mode_item_realize(Elm_Gen_Item *it)
2853 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
2855 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2856 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
2857 edje_object_scale_set(it->item->mode_view,
2858 elm_widget_scale_get(WIDGET(it)) *
2859 _elm_config->scale);
2860 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
2861 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
2863 strncpy(buf, "item", sizeof(buf));
2864 if (it->wd->compress)
2865 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
2867 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
2868 strncat(buf, "/", sizeof(buf) - strlen(buf));
2869 strncat(buf, it->wd->mode_item_style, sizeof(buf) - strlen(buf));
2871 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
2872 elm_widget_style_get(WIDGET(it)));
2873 edje_object_mirrored_set(it->item->mode_view,
2874 elm_widget_mirrored_get(WIDGET(it)));
2876 /* signal callback add */
2877 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
2879 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
2881 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
2884 /* text_get, content_get, state_get */
2885 /* FIXME: If you see that assert, please notify us and we
2886 will clean our mess */
2887 assert(eina_list_count(it->item->mode_content_objs) == 0);
2889 _item_label_realize(it, it->item->mode_view, &it->item->mode_labels, NULL);
2890 it->item->mode_content_objs =
2891 _item_content_realize(it, it->item->mode_view,
2892 &it->item->mode_contents, NULL);
2893 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
2895 edje_object_part_swallow(it->item->mode_view,
2896 edje_object_data_get(it->item->mode_view, "mode_part"),
2899 it->want_unrealize = EINA_FALSE;
2900 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2901 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2905 _mode_item_unrealize(Elm_Gen_Item *it)
2907 Widget_Data *wd = it->wd;
2908 Evas_Object *content;
2909 if (!it->item->mode_view) return;
2911 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2912 elm_widget_stringlist_free(it->item->mode_labels);
2913 it->item->mode_labels = NULL;
2914 elm_widget_stringlist_free(it->item->mode_contents);
2915 it->item->mode_contents = NULL;
2916 elm_widget_stringlist_free(it->item->mode_states);
2918 EINA_LIST_FREE(it->item->mode_content_objs, content)
2919 evas_object_del(content);
2921 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
2922 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
2923 evas_object_del(it->item->mode_view);
2924 it->item->mode_view = NULL;
2926 if (wd->mode_item == it)
2927 wd->mode_item = NULL;
2928 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2929 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2933 _item_mode_set(Elm_Gen_Item *it)
2936 Widget_Data *wd = it->wd;
2941 it->item->nocache = EINA_TRUE;
2943 if (wd->scr_hold_timer)
2945 ecore_timer_del(wd->scr_hold_timer);
2946 wd->scr_hold_timer = NULL;
2948 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
2949 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
2951 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2952 _mode_item_realize(it);
2953 if (it->item->group_item)
2954 evas_object_raise(it->item->VIEW(group_item));
2955 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
2956 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2957 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2959 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
2960 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2964 _item_mode_unset(Widget_Data *wd)
2967 if (!wd->mode_item) return;
2968 char buf[1024], buf2[1024];
2972 it->item->nocache = EINA_TRUE;
2974 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
2975 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
2977 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2978 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
2980 wd->mode_item = NULL;
2984 _item_auto_scroll(Widget_Data *wd)
2989 Evas_Coord ox, oy, ow, oh;
2991 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
2993 evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
2994 if (wd->expanded_item->item->scrl_y > (oh + oy) / 2)
2996 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
2997 elm_genlist_item_bring_in(it);
2999 wd->auto_scroll_enabled = EINA_FALSE;
3004 elm_genlist_add(Evas_Object *parent)
3009 Evas_Coord minw, minh;
3010 static Evas_Smart *smart = NULL;
3014 static Evas_Smart_Class sc;
3016 evas_object_smart_clipped_smart_set(&_pan_sc);
3018 sc.name = "elm_genlist_pan";
3019 sc.version = EVAS_SMART_CLASS_VERSION;
3022 sc.resize = _pan_resize;
3023 sc.move = _pan_move;
3024 sc.calculate = _pan_calculate;
3025 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3028 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3030 ELM_SET_WIDTYPE(widtype, "genlist");
3032 elm_widget_type_set(obj, "genlist");
3033 elm_widget_sub_object_add(parent, obj);
3034 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3035 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3036 elm_widget_data_set(obj, wd);
3037 elm_widget_del_hook_set(obj, _del_hook);
3038 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3039 elm_widget_theme_hook_set(obj, _theme_hook);
3040 elm_widget_can_focus_set(obj, EINA_TRUE);
3041 elm_widget_event_hook_set(obj, _event_hook);
3042 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3043 elm_widget_translate_hook_set(obj, _translate_hook);
3046 wd->scr = elm_smart_scroller_add(e);
3047 elm_smart_scroller_widget_set(wd->scr, obj);
3048 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3049 elm_widget_style_get(obj));
3050 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3051 _elm_config->thumbscroll_bounce_enable);
3052 elm_widget_resize_object_set(obj, wd->scr);
3054 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3055 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3056 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3057 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3058 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3059 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3060 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3061 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3064 wd->mode = ELM_LIST_SCROLL;
3065 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3066 wd->item_cache_max = wd->max_items_per_block * 2;
3067 wd->longpress_timeout = _elm_config->longpress_timeout;
3069 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3070 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3071 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3072 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3074 wd->pan_smart = evas_object_smart_add(e, smart);
3075 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3078 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3079 _pan_set, _pan_get, _pan_max_get,
3080 _pan_min_get, _pan_child_size_get);
3082 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3084 evas_object_size_hint_min_set(obj, minw, minh);
3086 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3088 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3094 _item_select(Elm_Gen_Item *it)
3096 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3099 it->selected = EINA_TRUE;
3100 it->wd->selected = eina_list_append(it->wd->selected, it);
3102 else if (!it->wd->always_select) return;
3104 evas_object_ref(WIDGET(it));
3107 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3108 if (it->generation == it->wd->generation)
3109 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3112 evas_object_unref(WIDGET(it));
3113 if ((it->wd->clear_me) && (!it->wd->walking))
3114 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3117 if ((!it->walking) && (it->generation < it->wd->generation))
3119 if (!it->relcount) it->del_cb(it);
3122 it->wd->last_selected_item = it;
3126 static Evas_Object *
3127 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3129 return edje_object_part_swallow_get(VIEW(it), part);
3133 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3135 edje_object_part_swallow(VIEW(it), part, content);
3138 static Evas_Object *
3139 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3143 obj = edje_object_part_swallow_get(VIEW(it), part);
3144 if (!obj) return NULL;
3145 edje_object_part_unswallow(VIEW(it), obj);
3150 _item_label_hook(Elm_Gen_Item *it, const char *part)
3152 if (!it->itc->func.text_get) return NULL;
3153 return edje_object_part_text_get(VIEW(it), part);
3157 _elm_genlist_item_new(Widget_Data *wd,
3158 const Elm_Gen_Item_Class *itc,
3160 Elm_Gen_Item *parent,
3162 const void *func_data)
3166 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3167 if (!it) return NULL;
3169 it->generation = wd->generation;
3171 it->base.data = data;
3172 it->parent = parent;
3173 it->func.func = func;
3174 it->func.data = func_data;
3175 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3176 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3177 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3179 it->sel_cb = (Ecore_Cb)_item_select;
3181 elm_widget_item_text_get_hook_set(it, _item_label_hook);
3185 static Elm_Gen_Item *
3186 _item_new(Widget_Data *wd,
3187 const Elm_Genlist_Item_Class *itc,
3189 Elm_Gen_Item *parent,
3190 Elm_Genlist_Item_Flags flags,
3192 const void *func_data)
3194 Elm_Gen_Item *it, *it2;
3197 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3198 if (!it) return NULL;
3199 it->item = ELM_NEW(Elm_Gen_Item_Type);
3200 it->item->flags = flags;
3201 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3202 it->item->expanded_depth = 0;
3203 elm_widget_item_del_cb_set(it, _item_del_hook);
3204 ELM_GEN_ITEM_SETUP(it);
3207 if (it->parent->group)
3208 it->item->group_item = parent;
3209 else if (it->parent->item->group_item)
3210 it->item->group_item = it->parent->item->group_item;
3212 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3214 if (!it2->parent->group) depth += 1;
3216 it->item->expanded_depth = depth;
3221 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3225 itb = calloc(1, sizeof(Item_Block));
3226 if (!itb) return NULL;
3229 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3231 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3236 _item_block_add(Widget_Data *wd,
3239 Item_Block *itb = NULL;
3246 itb = calloc(1, sizeof(Item_Block));
3247 if (!itb) return EINA_FALSE;
3249 if (!it->item->rel->item->block)
3252 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3253 itb->items = eina_list_append(itb->items, it);
3257 if (it->item->before)
3259 wd->blocks = eina_inlist_prepend_relative
3260 (wd->blocks, EINA_INLIST_GET(itb),
3261 EINA_INLIST_GET(it->item->rel->item->block));
3263 eina_list_prepend_relative(itb->items, it, it->item->rel);
3267 wd->blocks = eina_inlist_append_relative
3268 (wd->blocks, EINA_INLIST_GET(itb),
3269 EINA_INLIST_GET(it->item->rel->item->block));
3271 eina_list_append_relative(itb->items, it, it->item->rel);
3277 if (it->item->before)
3281 itb = (Item_Block *)(wd->blocks);
3282 if (itb->count >= wd->max_items_per_block)
3284 itb = _item_block_new(wd, EINA_TRUE);
3285 if (!itb) return EINA_FALSE;
3290 itb = _item_block_new(wd, EINA_TRUE);
3291 if (!itb) return EINA_FALSE;
3293 itb->items = eina_list_prepend(itb->items, it);
3299 itb = (Item_Block *)(wd->blocks->last);
3300 if (itb->count >= wd->max_items_per_block)
3302 itb = _item_block_new(wd, EINA_FALSE);
3303 if (!itb) return EINA_FALSE;
3308 itb = _item_block_new(wd, EINA_FALSE);
3309 if (!itb) return EINA_FALSE;
3311 itb->items = eina_list_append(itb->items, it);
3317 if (it->item->rel->item->queued)
3319 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3320 on sorted insertion order, so the queue is not always ordered like the item list.
3321 This lead to issue where we depend on an item that is not yet created. As a quick
3322 work around, we reschedule the calc of the item and stop reordering the list to
3323 prevent any nasty issue to show up here.
3325 wd->queue = eina_list_append(wd->queue, it);
3326 wd->requeued = EINA_TRUE;
3327 it->item->queued = EINA_TRUE;
3330 itb = it->item->rel->item->block;
3331 if (!itb) goto newblock;
3332 if (it->item->before)
3333 itb->items = eina_list_prepend_relative(itb->items, it, it->item->rel);
3335 itb->items = eina_list_append_relative(itb->items, it, it->item->rel);
3338 itb->changed = EINA_TRUE;
3339 it->item->block = itb;
3340 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3341 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3344 it->item->rel->relcount--;
3345 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3346 _item_del(it->item->rel);
3347 it->item->rel = NULL;
3349 if (itb->count > itb->wd->max_items_per_block)
3354 Eina_Bool done = EINA_FALSE;
3356 newc = itb->count / 2;
3358 if (EINA_INLIST_GET(itb)->prev)
3360 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3362 if (itbp->count + newc < wd->max_items_per_block / 2)
3364 /* moving items to previous block */
3365 while ((itb->count > newc) && (itb->items))
3367 it2 = eina_list_data_get(itb->items);
3368 itb->items = eina_list_remove_list(itb->items, itb->items);
3371 itbp->items = eina_list_append(itbp->items, it2);
3372 it2->item->block = itbp;
3380 if (!done && EINA_INLIST_GET(itb)->next)
3382 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3384 if (itbn->count + newc < wd->max_items_per_block / 2)
3386 /* moving items to next block */
3387 while ((itb->count > newc) && (itb->items))
3391 l = eina_list_last(itb->items);
3392 it2 = eina_list_data_get(l);
3393 itb->items = eina_list_remove_list(itb->items, l);
3396 itbn->items = eina_list_prepend(itbn->items, it2);
3397 it2->item->block = itbn;
3407 /* moving items to new block */
3408 itb2 = calloc(1, sizeof(Item_Block));
3409 if (!itb2) return EINA_FALSE;
3412 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3413 EINA_INLIST_GET(itb));
3414 itb2->changed = EINA_TRUE;
3415 while ((itb->count > newc) && (itb->items))
3419 l = eina_list_last(itb->items);
3421 itb->items = eina_list_remove_list(itb->items, l);
3424 itb2->items = eina_list_prepend(itb2->items, it2);
3425 it2->item->block = itb2;
3435 _queue_process(Widget_Data *wd)
3438 Eina_Bool showme = EINA_FALSE;
3441 t0 = ecore_loop_time_get();
3442 //evas_event_freeze(evas_object_evas_get(wd->obj));
3443 for (n = 0; (wd->queue) && (n < 128); n++)
3447 it = eina_list_data_get(wd->queue);
3448 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3449 it->item->queued = EINA_FALSE;
3450 if (!_item_block_add(wd, it)) continue;
3452 _item_block_realize(it->item->block);
3453 t = ecore_time_get();
3454 if (it->item->block->changed)
3456 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3457 it->item->block->changed = 0;
3459 if (showme) it->item->block->showme = EINA_TRUE;
3460 if (eina_inlist_count(wd->blocks) > 1)
3462 if ((t - t0) > (ecore_animator_frametime_get())) break;
3465 //evas_event_thaw(evas_object_evas_get(wd->obj));
3466 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3471 _idle_process(void *data, Eina_Bool *wakeup)
3473 Widget_Data *wd = data;
3476 //static double q_start = 0.0;
3477 //if (q_start == 0.0) q_start = ecore_time_get();
3479 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
3483 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
3485 return ECORE_CALLBACK_CANCEL;
3487 return ECORE_CALLBACK_RENEW;
3491 _item_idle_enterer(void *data)
3493 Widget_Data *wd = data;
3494 Eina_Bool wakeup = EINA_FALSE;
3495 Eina_Bool ok = _idle_process(data, &wakeup);
3500 if (wd->calc_job) ecore_job_del(wd->calc_job);
3501 wd->calc_job = ecore_job_add(_calc_job, wd);
3503 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
3508 _item_queue(Widget_Data *wd,
3512 if (it->item->queued) return;
3513 it->item->queued = EINA_TRUE;
3514 if (cb && !wd->requeued)
3515 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
3517 wd->queue = eina_list_append(wd->queue, it);
3518 // FIXME: why does a freeze then thaw here cause some genlist
3519 // elm_genlist_item_append() to be much much slower?
3520 // evas_event_freeze(evas_object_evas_get(wd->obj));
3521 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
3523 if (wd->queue_idle_enterer)
3525 ecore_idle_enterer_del(wd->queue_idle_enterer);
3526 wd->queue_idle_enterer = NULL;
3530 // evas_event_thaw(evas_object_evas_get(wd->obj));
3531 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3532 if (!wd->queue_idle_enterer)
3533 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
3537 _elm_genlist_item_compare_data(const void *data, const void *data1)
3539 const Elm_Gen_Item *it = data;
3540 const Elm_Gen_Item *item1 = data1;
3542 return it->wd->item_compare_data_cb(it->base.data, item1->base.data);
3546 _elm_genlist_item_compare(const void *data, const void *data1)
3548 const Elm_Gen_Item *it, *item1;
3549 it = ELM_GEN_ITEM_FROM_INLIST(data);
3550 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
3551 return it->wd->item_compare_cb(it, item1);
3555 _elm_genlist_item_list_compare(const void *data, const void *data1)
3557 const Elm_Gen_Item *it = data;
3558 const Elm_Gen_Item *item1 = data1;
3559 return it->wd->item_compare_cb(it, item1);
3563 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
3568 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3569 _item_block_del(it);
3571 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3572 it->item->rel = after;
3573 it->item->rel->relcount++;
3574 it->item->before = EINA_FALSE;
3575 if (after->item->group_item) it->item->group_item = after->item->group_item;
3576 _item_queue(it->wd, it, NULL);
3578 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3582 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
3585 if (!before) return;
3587 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3588 _item_block_del(it);
3589 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
3590 it->item->rel = before;
3591 it->item->rel->relcount++;
3592 it->item->before = EINA_TRUE;
3593 if (before->item->group_item) it->item->group_item = before->item->group_item;
3594 _item_queue(it->wd, it, NULL);
3596 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3600 elm_genlist_item_append(Evas_Object *obj,
3601 const Elm_Genlist_Item_Class *itc,
3603 Elm_Gen_Item *parent,
3604 Elm_Genlist_Item_Flags flags,
3606 const void *func_data)
3608 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3609 Widget_Data *wd = elm_widget_data_get(obj);
3610 if (!wd) return NULL;
3611 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3613 if (!it) return NULL;
3617 wd->group_items = eina_list_append(wd->group_items, it);
3618 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
3619 it->item->rel = NULL;
3623 Elm_Gen_Item *it2 = NULL;
3624 Eina_List *ll = eina_list_last(it->parent->item->items);
3625 if (ll) it2 = ll->data;
3626 it->parent->item->items = eina_list_append(it->parent->item->items, it);
3627 if (!it2) it2 = it->parent;
3629 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3630 EINA_INLIST_GET(it2));
3631 it->item->rel = it2;
3632 it->item->rel->relcount++;
3634 it->item->before = EINA_FALSE;
3635 _item_queue(wd, it, NULL);
3640 elm_genlist_item_prepend(Evas_Object *obj,
3641 const Elm_Genlist_Item_Class *itc,
3643 Elm_Gen_Item *parent,
3644 Elm_Genlist_Item_Flags flags,
3646 const void *func_data)
3648 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3649 Widget_Data *wd = elm_widget_data_get(obj);
3650 if (!wd) return NULL;
3651 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3653 if (!it) return NULL;
3657 wd->group_items = eina_list_prepend(wd->group_items, it);
3658 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
3659 it->item->rel = NULL;
3663 Elm_Gen_Item *it2 = NULL;
3664 Eina_List *ll = it->parent->item->items;
3665 if (ll) it2 = ll->data;
3666 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
3667 if (!it2) it2 = it->parent;
3669 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3670 EINA_INLIST_GET(it2));
3671 it->item->rel = it2;
3672 it->item->rel->relcount++;
3674 it->item->before = EINA_TRUE;
3675 _item_queue(wd, it, NULL);
3680 elm_genlist_item_insert_after(Evas_Object *obj,
3681 const Elm_Genlist_Item_Class *itc,
3683 Elm_Gen_Item *parent,
3684 Elm_Gen_Item *after,
3685 Elm_Genlist_Item_Flags flags,
3687 const void *func_data)
3689 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3690 EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3691 Widget_Data *wd = elm_widget_data_get(obj);
3692 if (!wd) return NULL;
3693 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
3694 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3696 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3698 if (!it) return NULL;
3703 wd->group_items = eina_list_append_relative(wd->group_items, it,
3708 it->parent->item->items = eina_list_append_relative(it->parent->item->items, it,
3711 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3712 EINA_INLIST_GET(after));
3713 it->item->rel = after;
3714 it->item->rel->relcount++;
3715 it->item->before = EINA_FALSE;
3716 _item_queue(wd, it, NULL);
3721 elm_genlist_item_insert_before(Evas_Object *obj,
3722 const Elm_Genlist_Item_Class *itc,
3724 Elm_Gen_Item *parent,
3725 Elm_Gen_Item *before,
3726 Elm_Genlist_Item_Flags flags,
3728 const void *func_data)
3730 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3731 EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
3732 Widget_Data *wd = elm_widget_data_get(obj);
3733 if (!wd) return NULL;
3734 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
3735 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3737 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3739 if (!it) return NULL;
3742 if (it->group && before->group)
3743 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
3748 it->parent->item->items = eina_list_prepend_relative(it->parent->item->items, it,
3751 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3752 EINA_INLIST_GET(before));
3753 it->item->rel = before;
3754 it->item->rel->relcount++;
3755 it->item->before = EINA_TRUE;
3756 _item_queue(wd, it, NULL);
3761 elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
3762 const Elm_Genlist_Item_Class *itc,
3764 Elm_Gen_Item *parent,
3765 Elm_Genlist_Item_Flags flags,
3766 Eina_Compare_Cb comp,
3768 const void *func_data)
3770 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3771 Widget_Data *wd = elm_widget_data_get(obj);
3772 if (!wd) return NULL;
3773 Elm_Gen_Item *rel = NULL;
3774 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3776 if (!it) return NULL;
3778 wd->item_compare_cb = comp;
3785 l = eina_list_search_sorted_near_list(it->parent->item->items,
3786 _elm_genlist_item_list_compare, it,
3789 rel = eina_list_data_get(l);
3793 if (cmp_result >= 0)
3795 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
3796 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3797 it->item->before = EINA_FALSE;
3799 else if (cmp_result < 0)
3801 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
3802 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3803 it->item->before = EINA_TRUE;
3810 wd->state = eina_inlist_sorted_state_new();
3811 eina_inlist_sorted_state_init(wd->state, wd->items);
3812 wd->requeued = EINA_FALSE;
3816 wd->group_items = eina_list_append(wd->group_items, it);
3818 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
3819 _elm_genlist_item_compare, wd->state);
3821 if (EINA_INLIST_GET(it)->next)
3823 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3824 it->item->before = EINA_TRUE;
3826 else if (EINA_INLIST_GET(it)->prev)
3828 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3829 it->item->before = EINA_FALSE;
3835 it->item->rel = rel;
3836 it->item->rel->relcount++;
3839 _item_queue(wd, it, _elm_genlist_item_list_compare);
3845 elm_genlist_item_sorted_insert(Evas_Object *obj,
3846 const Elm_Genlist_Item_Class *itc,
3848 Elm_Gen_Item *parent,
3849 Elm_Genlist_Item_Flags flags,
3850 Eina_Compare_Cb comp,
3852 const void *func_data)
3854 Widget_Data *wd = elm_widget_data_get(obj);
3855 wd->item_compare_data_cb = comp;
3857 return elm_genlist_item_direct_sorted_insert(obj, itc, data, parent, flags,
3858 _elm_genlist_item_compare_data, func, func_data);
3862 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
3864 Eina_Inlist *next, *l;
3866 ELM_CHECK_WIDTYPE(obj, widtype);
3867 Widget_Data *wd = elm_widget_data_get(obj);
3870 if (!standby) wd->generation++;
3874 eina_inlist_sorted_state_free(wd->state);
3878 if (wd->walking > 0)
3883 evas_event_freeze(evas_object_evas_get(wd->obj));
3884 for (l = wd->items, next = l ? l->next : NULL;
3886 l = next, next = next ? next->next : NULL)
3888 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
3890 if (it->generation < wd->generation)
3892 Elm_Gen_Item *itn = NULL;
3894 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
3895 if (itn) itn->walking++; /* prevent early death of subitem */
3897 if (itn) itn->walking--;
3903 ecore_job_del(wd->calc_job);
3904 wd->calc_job = NULL;
3906 if (wd->selected) wd->selected = eina_list_free(wd->selected);
3907 if (wd->clear_cb) wd->clear_cb(wd);
3915 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
3916 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3918 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
3919 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
3920 evas_event_thaw(evas_object_evas_get(wd->obj));
3921 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3925 elm_genlist_clear(Evas_Object *obj)
3927 _elm_genlist_clear(obj, EINA_FALSE);
3931 elm_genlist_multi_select_set(Evas_Object *obj,
3934 ELM_CHECK_WIDTYPE(obj, widtype);
3935 Widget_Data *wd = elm_widget_data_get(obj);
3941 elm_genlist_multi_select_get(const Evas_Object *obj)
3943 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3944 Widget_Data *wd = elm_widget_data_get(obj);
3945 if (!wd) return EINA_FALSE;
3950 elm_genlist_selected_item_get(const Evas_Object *obj)
3952 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3953 Widget_Data *wd = elm_widget_data_get(obj);
3954 if (!wd) return NULL;
3955 if (wd->selected) return wd->selected->data;
3959 EAPI const Eina_List *
3960 elm_genlist_selected_items_get(const Evas_Object *obj)
3962 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3963 Widget_Data *wd = elm_widget_data_get(obj);
3964 if (!wd) return NULL;
3965 return wd->selected;
3969 elm_genlist_realized_items_get(const Evas_Object *obj)
3971 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3972 Widget_Data *wd = elm_widget_data_get(obj);
3973 Eina_List *list = NULL;
3975 Eina_Bool done = EINA_FALSE;
3976 if (!wd) return NULL;
3977 EINA_INLIST_FOREACH(wd->blocks, itb)
3985 EINA_LIST_FOREACH(itb->items, l, it)
3987 if (it->realized) list = eina_list_append(list, it);
3999 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4004 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4005 Widget_Data *wd = elm_widget_data_get(obj);
4006 Evas_Coord ox, oy, ow, oh;
4009 if (!wd) return NULL;
4010 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4012 EINA_INLIST_FOREACH(wd->blocks, itb)
4017 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4018 oy + itb->y - itb->wd->pan_y,
4019 itb->w, itb->h, x, y, 1, 1))
4021 EINA_LIST_FOREACH(itb->items, l, it)
4023 Evas_Coord itx, ity;
4025 itx = ox + itb->x + it->x - itb->wd->pan_x;
4026 ity = oy + itb->y + it->y - itb->wd->pan_y;
4027 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4031 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4032 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4038 lasty = ity + it->item->h;
4043 if (y > lasty) *posret = 1;
4050 elm_genlist_first_item_get(const Evas_Object *obj)
4052 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4053 Widget_Data *wd = elm_widget_data_get(obj);
4054 if (!wd) return NULL;
4055 if (!wd->items) return NULL;
4056 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4057 while ((it) && (it->generation < wd->generation))
4058 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4063 elm_genlist_last_item_get(const Evas_Object *obj)
4065 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4066 Widget_Data *wd = elm_widget_data_get(obj);
4067 if (!wd) return NULL;
4068 if (!wd->items) return NULL;
4069 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4070 while ((it) && (it->generation < wd->generation))
4071 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4076 elm_genlist_item_next_get(const Elm_Gen_Item *it)
4078 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4081 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4082 if ((it) && (it->generation == it->wd->generation)) break;
4084 return (Elm_Gen_Item *)it;
4088 elm_genlist_item_prev_get(const Elm_Gen_Item *it)
4090 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4093 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4094 if ((it) && (it->generation == it->wd->generation)) break;
4096 return (Elm_Gen_Item *)it;
4100 elm_genlist_item_genlist_get(const Elm_Gen_Item *it)
4102 return _elm_genlist_item_widget_get(it);
4106 elm_genlist_item_parent_get(const Elm_Gen_Item *it)
4108 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4113 elm_genlist_item_subitems_clear(Elm_Gen_Item *it)
4115 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4116 Eina_List *tl = NULL, *l;
4119 EINA_LIST_FOREACH(it->item->items, l, it2)
4120 tl = eina_list_append(tl, it2);
4121 EINA_LIST_FREE(tl, it2)
4122 elm_genlist_item_del(it2);
4126 elm_genlist_item_selected_set(Elm_Gen_Item *it,
4129 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4130 Widget_Data *wd = it->wd;
4132 if ((it->generation < wd->generation) || (it->disabled)) return;
4133 selected = !!selected;
4134 if (it->selected == selected) return;
4140 while (wd->selected)
4142 if (it->unhighlight_cb) it->unhighlight_cb(wd->selected->data);
4143 it->unsel_cb(wd->selected->data);
4146 it->highlight_cb(it);
4150 if (it->unhighlight_cb) it->unhighlight_cb(it);
4155 elm_genlist_item_selected_get(const Elm_Gen_Item *it)
4157 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4158 return it->selected;
4162 elm_genlist_item_expanded_set(Elm_Gen_Item *it,
4165 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4166 if (it->item->expanded == expanded) return;
4167 it->item->expanded = expanded;
4168 it->wd->expanded_item = it;
4169 if (it->item->expanded)
4172 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
4173 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
4174 it->wd->auto_scroll_enabled = EINA_TRUE;
4179 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
4180 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
4181 it->wd->auto_scroll_enabled = EINA_FALSE;
4186 elm_genlist_item_expanded_get(const Elm_Gen_Item *it)
4188 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4189 return it->item->expanded;
4193 elm_genlist_item_expanded_depth_get(const Elm_Gen_Item *it)
4195 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, 0);
4196 return it->item->expanded_depth;
4200 elm_genlist_item_disabled_set(Elm_Gen_Item *it,
4203 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4206 if (it->disabled == disabled) return;
4207 if (it->generation < it->wd->generation) return;
4208 it->disabled = !!disabled;
4210 elm_genlist_item_selected_set(it, EINA_FALSE);
4214 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4216 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
4217 EINA_LIST_FOREACH(it->content_objs, l, obj)
4218 elm_widget_disabled_set(obj, disabled);
4223 elm_genlist_item_disabled_get(const Elm_Gen_Item *it)
4225 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4226 if (it->generation < it->wd->generation) return EINA_FALSE;
4227 return it->disabled;
4231 elm_genlist_item_display_only_set(Elm_Gen_Item *it,
4232 Eina_Bool display_only)
4234 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4235 if (it->display_only == display_only) return;
4236 if (it->generation < it->wd->generation) return;
4237 it->display_only = display_only;
4238 it->item->mincalcd = EINA_FALSE;
4239 it->item->updateme = EINA_TRUE;
4240 if (it->item->block) it->item->block->updateme = EINA_TRUE;
4241 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4242 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4246 elm_genlist_item_display_only_get(const Elm_Gen_Item *it)
4248 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4249 if (it->generation < it->wd->generation) return EINA_FALSE;
4250 return it->display_only;
4254 elm_genlist_item_show(Elm_Gen_Item *it)
4256 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4257 Evas_Coord gith = 0;
4258 if (it->generation < it->wd->generation) return;
4259 if ((it->item->queued) || (!it->item->mincalcd))
4261 it->wd->show_item = it;
4262 it->wd->bring_in = EINA_TRUE;
4263 it->item->showme = EINA_TRUE;
4266 if (it->wd->show_item)
4268 it->wd->show_item->item->showme = EINA_FALSE;
4269 it->wd->show_item = NULL;
4271 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4272 gith = it->item->group_item->item->h;
4273 elm_smart_scroller_child_region_show(it->wd->scr,
4274 it->x + it->item->block->x,
4275 it->y + it->item->block->y - gith,
4276 it->item->block->w, it->item->h);
4280 elm_genlist_item_promote(Elm_Gen_Item *it)
4282 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4283 if (it->generation < it->wd->generation) return;
4284 _item_move_before(it, elm_genlist_first_item_get(WIDGET(it)));
4288 elm_genlist_item_demote(Elm_Gen_Item *it)
4290 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4291 if (it->generation < it->wd->generation) return;
4292 _item_move_after(it, elm_genlist_last_item_get(WIDGET(it)));
4296 elm_genlist_item_bring_in(Elm_Gen_Item *it)
4298 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4299 Evas_Coord gith = 0;
4300 if (it->generation < it->wd->generation) return;
4301 if ((it->item->queued) || (!it->item->mincalcd))
4303 it->wd->show_item = it;
4304 it->wd->bring_in = EINA_TRUE;
4305 it->item->showme = EINA_TRUE;
4308 if (it->wd->show_item)
4310 it->wd->show_item->item->showme = EINA_FALSE;
4311 it->wd->show_item = NULL;
4313 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4314 gith = it->item->group_item->item->h;
4315 elm_smart_scroller_region_bring_in(it->wd->scr,
4316 it->x + it->item->block->x,
4317 it->y + it->item->block->y - gith,
4318 it->item->block->w, it->item->h);
4322 elm_genlist_item_top_show(Elm_Gen_Item *it)
4324 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4326 Evas_Coord gith = 0;
4328 if (it->generation < it->wd->generation) return;
4329 if ((it->item->queued) || (!it->item->mincalcd))
4331 it->wd->show_item = it;
4332 it->wd->bring_in = EINA_TRUE;
4333 it->item->showme = EINA_TRUE;
4336 if (it->wd->show_item)
4338 it->wd->show_item->item->showme = EINA_FALSE;
4339 it->wd->show_item = NULL;
4341 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4342 if (it->item->group_item) gith = it->item->group_item->item->h;
4343 elm_smart_scroller_child_region_show(it->wd->scr,
4344 it->x + it->item->block->x,
4345 it->y + it->item->block->y - gith,
4346 it->item->block->w, oh);
4350 elm_genlist_item_top_bring_in(Elm_Gen_Item *it)
4352 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4354 Evas_Coord gith = 0;
4356 if (it->generation < it->wd->generation) return;
4357 if ((it->item->queued) || (!it->item->mincalcd))
4359 it->wd->show_item = it;
4360 it->wd->bring_in = EINA_TRUE;
4361 it->item->showme = EINA_TRUE;
4364 if (it->wd->show_item)
4366 it->wd->show_item->item->showme = EINA_FALSE;
4367 it->wd->show_item = NULL;
4369 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4370 if (it->item->group_item) gith = it->item->group_item->item->h;
4371 elm_smart_scroller_region_bring_in(it->wd->scr,
4372 it->x + it->item->block->x,
4373 it->y + it->item->block->y - gith,
4374 it->item->block->w, oh);
4378 elm_genlist_item_middle_show(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_child_region_show(it->wd->scr,
4398 it->x + it->item->block->x,
4399 it->y + it->item->block->y - oh / 2 +
4400 it->item->h / 2, it->item->block->w, oh);
4404 elm_genlist_item_middle_bring_in(Elm_Gen_Item *it)
4406 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4409 if (it->generation < it->wd->generation) return;
4410 if ((it->item->queued) || (!it->item->mincalcd))
4412 it->wd->show_item = it;
4413 it->wd->bring_in = EINA_TRUE;
4414 it->item->showme = EINA_TRUE;
4417 if (it->wd->show_item)
4419 it->wd->show_item->item->showme = EINA_FALSE;
4420 it->wd->show_item = NULL;
4422 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4423 elm_smart_scroller_region_bring_in(it->wd->scr,
4424 it->x + it->item->block->x,
4425 it->y + it->item->block->y - oh / 2 + it->item->h / 2,
4426 it->item->block->w, oh);
4430 elm_genlist_item_del(Elm_Gen_Item *it)
4432 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4433 if ((it->relcount > 0) || (it->walking > 0))
4435 elm_genlist_item_subitems_clear(it);
4436 if (it->wd->show_item == it) it->wd->show_item = NULL;
4437 _elm_genlist_item_del_notserious(it);
4438 if (it->item->block)
4440 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
4441 it->item->block->changed = EINA_TRUE;
4442 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
4443 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
4447 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
4456 elm_genlist_item_data_set(Elm_Gen_Item *it,
4459 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4460 elm_widget_item_data_set(it, data);
4464 elm_genlist_item_data_get(const Elm_Gen_Item *it)
4466 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4467 return elm_widget_item_data_get(it);
4471 elm_genlist_item_icons_orphan(Elm_Gen_Item *it)
4473 elm_genlist_item_contents_orphan(it);
4477 elm_genlist_item_contents_orphan(Elm_Gen_Item *it)
4479 Evas_Object *content;
4480 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4481 EINA_LIST_FREE(it->content_objs, content)
4483 elm_widget_sub_object_del(WIDGET(it), content);
4484 evas_object_smart_member_del(content);
4485 evas_object_hide(content);
4489 EAPI const Evas_Object *
4490 elm_genlist_item_object_get(const Elm_Gen_Item *it)
4492 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4497 elm_genlist_item_update(Elm_Gen_Item *it)
4499 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4500 if (!it->item->block) return;
4501 if (it->generation < it->wd->generation) return;
4502 it->item->mincalcd = EINA_FALSE;
4503 it->item->updateme = EINA_TRUE;
4504 it->item->block->updateme = EINA_TRUE;
4505 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4506 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4510 elm_genlist_item_fields_update(Elm_Genlist_Item *it,
4512 Elm_Genlist_Item_Field_Flags itf)
4514 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4515 if (!it->item->block) return;
4516 if (it->generation < it->wd->generation) return;
4518 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_LABEL))
4519 _item_label_realize(it, it->base.view, &it->labels, parts);
4520 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
4522 it->content_objs = _item_content_unrealize(it, it->base.view,
4523 &it->contents, parts);
4524 it->content_objs = _item_content_realize(it, it->base.view,
4525 &it->contents, parts);
4527 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
4528 _item_state_realize(it, it->base.view, &it->states, parts);
4532 elm_genlist_item_item_class_update(Elm_Gen_Item *it,
4533 const Elm_Genlist_Item_Class *itc)
4535 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4536 if (!it->item->block) return;
4537 EINA_SAFETY_ON_NULL_RETURN(itc);
4538 if (it->generation < it->wd->generation) return;
4540 it->item->nocache = EINA_TRUE;
4541 elm_genlist_item_update(it);
4544 EAPI const Elm_Genlist_Item_Class *
4545 elm_genlist_item_item_class_get(const Elm_Gen_Item *it)
4547 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4548 if (it->generation < it->wd->generation) return NULL;
4552 static Evas_Object *
4553 _elm_genlist_item_label_create(void *data,
4554 Evas_Object *obj __UNUSED__,
4555 Evas_Object *tooltip,
4556 void *it __UNUSED__)
4558 Evas_Object *label = elm_label_add(tooltip);
4561 elm_object_style_set(label, "tooltip");
4562 elm_object_text_set(label, data);
4567 _elm_genlist_item_label_del_cb(void *data,
4568 Evas_Object *obj __UNUSED__,
4569 void *event_info __UNUSED__)
4571 eina_stringshare_del(data);
4575 elm_genlist_item_tooltip_text_set(Elm_Gen_Item *it,
4578 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4579 text = eina_stringshare_add(text);
4580 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
4582 _elm_genlist_item_label_del_cb);
4586 elm_genlist_item_tooltip_content_cb_set(Elm_Gen_Item *it,
4587 Elm_Tooltip_Item_Content_Cb func,
4589 Evas_Smart_Cb del_cb)
4591 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, error);
4593 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4596 if (it->tooltip.del_cb)
4597 it->tooltip.del_cb((void *)it->tooltip.data,
4600 it->tooltip.content_cb = func;
4601 it->tooltip.data = data;
4602 it->tooltip.del_cb = del_cb;
4606 elm_widget_item_tooltip_content_cb_set(it,
4607 it->tooltip.content_cb,
4608 it->tooltip.data, NULL);
4609 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4610 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
4616 if (del_cb) del_cb((void *)data, NULL, NULL);
4620 elm_genlist_item_tooltip_unset(Elm_Gen_Item *it)
4622 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4623 if ((VIEW(it)) && (it->tooltip.content_cb))
4624 elm_widget_item_tooltip_unset(it);
4626 if (it->tooltip.del_cb)
4627 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4628 it->tooltip.del_cb = NULL;
4629 it->tooltip.content_cb = NULL;
4630 it->tooltip.data = NULL;
4631 it->tooltip.free_size = EINA_FALSE;
4632 if (it->tooltip.style)
4633 elm_genlist_item_tooltip_style_set(it, NULL);
4637 elm_genlist_item_tooltip_style_set(Elm_Gen_Item *it,
4640 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4641 eina_stringshare_replace(&it->tooltip.style, style);
4642 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4646 elm_genlist_item_tooltip_style_get(const Elm_Gen_Item *it)
4648 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4649 return it->tooltip.style;
4653 elm_genlist_item_tooltip_window_mode_set(Elm_Gen_Item *it, Eina_Bool disable)
4655 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4656 it->tooltip.free_size = disable;
4657 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
4662 elm_genlist_item_tooltip_window_mode_get(const Elm_Gen_Item *it)
4664 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4665 return it->tooltip.free_size;
4669 elm_genlist_item_cursor_set(Elm_Gen_Item *it,
4672 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4673 eina_stringshare_replace(&it->mouse_cursor, cursor);
4674 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4678 elm_genlist_item_cursor_get(const Elm_Gen_Item *it)
4680 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4681 return elm_widget_item_cursor_get(it);
4685 elm_genlist_item_cursor_unset(Elm_Gen_Item *it)
4687 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4688 if (!it->mouse_cursor)
4692 elm_widget_item_cursor_unset(it);
4694 eina_stringshare_del(it->mouse_cursor);
4695 it->mouse_cursor = NULL;
4699 elm_genlist_item_cursor_style_set(Elm_Gen_Item *it,
4702 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4703 elm_widget_item_cursor_style_set(it, style);
4707 elm_genlist_item_cursor_style_get(const Elm_Gen_Item *it)
4709 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4710 return elm_widget_item_cursor_style_get(it);
4714 elm_genlist_item_cursor_engine_only_set(Elm_Gen_Item *it,
4715 Eina_Bool engine_only)
4717 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4718 elm_widget_item_cursor_engine_only_set(it, engine_only);
4722 elm_genlist_item_cursor_engine_only_get(const Elm_Gen_Item *it)
4724 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4725 return elm_widget_item_cursor_engine_only_get(it);
4729 elm_genlist_horizontal_set(Evas_Object *obj,
4732 ELM_CHECK_WIDTYPE(obj, widtype);
4733 Widget_Data *wd = elm_widget_data_get(obj);
4735 if (wd->mode == mode) return;
4741 elm_genlist_horizontal_mode_set(Evas_Object *obj,
4744 elm_genlist_horizontal_set(obj, mode);
4748 elm_genlist_horizontal_get(const Evas_Object *obj)
4750 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4751 Widget_Data *wd = elm_widget_data_get(obj);
4752 if (!wd) return ELM_LIST_LAST;
4757 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4759 return elm_genlist_horizontal_get(obj);
4763 elm_genlist_always_select_mode_set(Evas_Object *obj,
4764 Eina_Bool always_select)
4766 ELM_CHECK_WIDTYPE(obj, widtype);
4767 Widget_Data *wd = elm_widget_data_get(obj);
4769 wd->always_select = always_select;
4773 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4775 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4776 Widget_Data *wd = elm_widget_data_get(obj);
4777 if (!wd) return EINA_FALSE;
4778 return wd->always_select;
4782 elm_genlist_no_select_mode_set(Evas_Object *obj,
4783 Eina_Bool no_select)
4785 ELM_CHECK_WIDTYPE(obj, widtype);
4786 Widget_Data *wd = elm_widget_data_get(obj);
4788 wd->no_select = no_select;
4792 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4794 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4795 Widget_Data *wd = elm_widget_data_get(obj);
4796 if (!wd) return EINA_FALSE;
4797 return wd->no_select;
4801 elm_genlist_compress_mode_set(Evas_Object *obj,
4804 ELM_CHECK_WIDTYPE(obj, widtype);
4805 Widget_Data *wd = elm_widget_data_get(obj);
4807 wd->compress = compress;
4808 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
4812 elm_genlist_compress_mode_get(const Evas_Object *obj)
4814 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4815 Widget_Data *wd = elm_widget_data_get(obj);
4816 if (!wd) return EINA_FALSE;
4817 return wd->compress;
4821 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
4822 Eina_Bool height_for_width)
4824 ELM_CHECK_WIDTYPE(obj, widtype);
4825 Widget_Data *wd = elm_widget_data_get(obj);
4827 wd->height_for_width = !!height_for_width;
4828 if (wd->height_for_width)
4830 elm_genlist_homogeneous_set(obj, EINA_FALSE);
4831 elm_genlist_compress_mode_set(obj, EINA_TRUE);
4836 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
4838 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4839 Widget_Data *wd = elm_widget_data_get(obj);
4840 if (!wd) return EINA_FALSE;
4841 return wd->height_for_width;
4845 elm_genlist_bounce_set(Evas_Object *obj,
4849 ELM_CHECK_WIDTYPE(obj, widtype);
4850 Widget_Data *wd = elm_widget_data_get(obj);
4852 elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
4853 wd->h_bounce = h_bounce;
4854 wd->v_bounce = v_bounce;
4858 elm_genlist_bounce_get(const Evas_Object *obj,
4859 Eina_Bool *h_bounce,
4860 Eina_Bool *v_bounce)
4862 ELM_CHECK_WIDTYPE(obj, widtype);
4863 Widget_Data *wd = elm_widget_data_get(obj);
4865 if (h_bounce) *h_bounce = wd->h_bounce;
4866 if (v_bounce) *v_bounce = wd->v_bounce;
4870 elm_genlist_homogeneous_set(Evas_Object *obj,
4871 Eina_Bool homogeneous)
4873 ELM_CHECK_WIDTYPE(obj, widtype);
4874 Widget_Data *wd = elm_widget_data_get(obj);
4876 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
4877 wd->homogeneous = homogeneous;
4881 elm_genlist_homogeneous_get(const Evas_Object *obj)
4883 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4884 Widget_Data *wd = elm_widget_data_get(obj);
4885 if (!wd) return EINA_FALSE;
4886 return wd->homogeneous;
4890 elm_genlist_block_count_set(Evas_Object *obj,
4893 ELM_CHECK_WIDTYPE(obj, widtype);
4894 Widget_Data *wd = elm_widget_data_get(obj);
4896 wd->max_items_per_block = n;
4897 wd->item_cache_max = wd->max_items_per_block * 2;
4898 _item_cache_clean(wd);
4902 elm_genlist_block_count_get(const Evas_Object *obj)
4904 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4905 Widget_Data *wd = elm_widget_data_get(obj);
4907 return wd->max_items_per_block;
4911 elm_genlist_longpress_timeout_set(Evas_Object *obj,
4914 ELM_CHECK_WIDTYPE(obj, widtype);
4915 Widget_Data *wd = elm_widget_data_get(obj);
4917 wd->longpress_timeout = timeout;
4921 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
4923 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4924 Widget_Data *wd = elm_widget_data_get(obj);
4926 return wd->longpress_timeout;
4930 elm_genlist_scroller_policy_set(Evas_Object *obj,
4931 Elm_Scroller_Policy policy_h,
4932 Elm_Scroller_Policy policy_v)
4934 ELM_CHECK_WIDTYPE(obj, widtype);
4935 Widget_Data *wd = elm_widget_data_get(obj);
4936 if ((!wd) || (!wd->scr)) return;
4937 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4938 (policy_v >= ELM_SCROLLER_POLICY_LAST))
4940 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
4944 elm_genlist_scroller_policy_get(const Evas_Object *obj,
4945 Elm_Scroller_Policy *policy_h,
4946 Elm_Scroller_Policy *policy_v)
4948 ELM_CHECK_WIDTYPE(obj, widtype);
4949 Widget_Data *wd = elm_widget_data_get(obj);
4950 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
4951 if ((!wd) || (!wd->scr)) return;
4952 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
4953 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
4954 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
4958 elm_genlist_realized_items_update(Evas_Object *obj)
4960 ELM_CHECK_WIDTYPE(obj, widtype);
4962 Eina_List *list, *l;
4965 list = elm_genlist_realized_items_get(obj);
4966 EINA_LIST_FOREACH(list, l, it)
4967 elm_genlist_item_update(it);
4971 elm_genlist_item_mode_set(Elm_Gen_Item *it,
4972 const char *mode_type,
4975 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4976 Widget_Data *wd = it->wd;
4981 if (!mode_type) return;
4982 if ((it->generation < it->wd->generation) || (it->disabled)) return;
4984 if ((wd->mode_item == it) &&
4985 (!strcmp(mode_type, wd->mode_type)) &&
4988 if (!wd->mode_item_style) return;
4989 it->mode_set = mode_set;
4993 EINA_LIST_FOREACH(wd->selected, l, it2)
4995 elm_genlist_item_selected_set(it2, EINA_FALSE);
4999 it2 = elm_genlist_selected_item_get(wd->obj);
5000 if ((it2) && (it2->realized))
5001 elm_genlist_item_selected_set(it2, EINA_FALSE);
5004 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
5006 ((it == wd->mode_item) && (!mode_set)))
5007 _item_mode_unset(wd);
5009 eina_stringshare_replace(&wd->mode_type, mode_type);
5010 if (mode_set) _item_mode_set(it);
5015 elm_genlist_mode_item_style_get(const Evas_Object *obj)
5017 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5018 Widget_Data *wd = elm_widget_data_get(obj);
5019 if (!wd) return NULL;
5020 return wd->mode_item_style;
5024 elm_genlist_mode_item_style_set(Evas_Object *obj, const char *style)
5026 ELM_CHECK_WIDTYPE(obj, widtype);
5027 Widget_Data *wd = elm_widget_data_get(obj);
5029 if ((style == wd->mode_item_style) || (style && wd->mode_item_style &&
5030 (!strcmp(style, wd->mode_item_style))))
5032 eina_stringshare_replace(&wd->mode_item_style, style);
5033 elm_genlist_realized_items_update(obj);
5037 elm_genlist_mode_get(const Evas_Object *obj)
5039 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5040 Widget_Data *wd = elm_widget_data_get(obj);
5041 if (!wd) return NULL;
5042 return wd->mode_type;
5045 EAPI const Elm_Gen_Item *
5046 elm_genlist_mode_item_get(const Evas_Object *obj)
5048 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5049 Widget_Data *wd = elm_widget_data_get(obj);
5050 if (!wd) return NULL;
5051 return wd->mode_item;
5055 elm_genlist_reorder_mode_set(Evas_Object *obj,
5056 Eina_Bool reorder_mode)
5058 ELM_CHECK_WIDTYPE(obj, widtype);
5059 Widget_Data *wd = elm_widget_data_get(obj);
5061 wd->reorder_mode = reorder_mode;
5065 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5067 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5068 Widget_Data *wd = elm_widget_data_get(obj);
5069 if (!wd) return EINA_FALSE;
5070 return wd->reorder_mode;
5073 /* for gengrid as of now */
5075 _elm_genlist_page_relative_set(Evas_Object *obj,
5079 Evas_Coord pagesize_h;
5080 Evas_Coord pagesize_v;
5082 ELM_CHECK_WIDTYPE(obj, widtype);
5083 Widget_Data *wd = elm_widget_data_get(obj);
5086 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5087 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5091 /* for gengrid as of now */
5093 _elm_genlist_page_relative_get(const Evas_Object *obj,
5097 ELM_CHECK_WIDTYPE(obj, widtype);
5098 Widget_Data *wd = elm_widget_data_get(obj);
5101 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5104 /* for gengrid as of now */
5106 _elm_genlist_page_size_set(Evas_Object *obj,
5107 Evas_Coord h_pagesize,
5108 Evas_Coord v_pagesize)
5113 ELM_CHECK_WIDTYPE(obj, widtype);
5114 Widget_Data *wd = elm_widget_data_get(obj);
5116 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5117 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5121 /* for gengrid as of now */
5123 _elm_genlist_current_page_get(const Evas_Object *obj,
5127 ELM_CHECK_WIDTYPE(obj, widtype);
5128 Widget_Data *wd = elm_widget_data_get(obj);
5131 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5134 /* for gengrid as of now */
5136 _elm_genlist_last_page_get(const Evas_Object *obj,
5140 ELM_CHECK_WIDTYPE(obj, widtype);
5141 Widget_Data *wd = elm_widget_data_get(obj);
5144 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5147 /* for gengrid as of now */
5149 _elm_genlist_page_show(const Evas_Object *obj,
5153 ELM_CHECK_WIDTYPE(obj, widtype);
5154 Widget_Data *wd = elm_widget_data_get(obj);
5157 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5160 /* for gengrid as of now */
5162 _elm_genlist_page_bring_in(const Evas_Object *obj,
5166 ELM_CHECK_WIDTYPE(obj, widtype);
5167 Widget_Data *wd = elm_widget_data_get(obj);
5170 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5174 _elm_genlist_item_widget_get(const Elm_Gen_Item *it)
5176 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
5181 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5184 Evas_Object *content;
5186 if (!it->realized) return;
5187 if (it->wd->reorder_it == it) return;
5188 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5190 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5193 ecore_timer_del(it->long_timer);
5194 it->long_timer = NULL;
5197 elm_widget_stringlist_free(it->labels);
5199 elm_widget_stringlist_free(it->contents);
5200 it->contents = NULL;
5201 elm_widget_stringlist_free(it->states);
5204 EINA_LIST_FREE(it->content_objs, content)
5205 evas_object_del(content);
5207 it->unrealize_cb(it);
5209 it->realized = EINA_FALSE;
5210 it->want_unrealize = EINA_FALSE;
5211 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5212 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5216 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5218 elm_widget_item_pre_notify_del(it);
5219 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5220 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5222 if (it->itc->func.del)
5223 it->itc->func.del((void *)it->base.data, WIDGET(it));
5227 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5229 _elm_genlist_item_del_notserious(it);
5230 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5231 if (it->tooltip.del_cb)
5232 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5233 it->wd->walking -= it->walking;
5234 if (it->long_timer) ecore_timer_del(it->long_timer);
5236 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5238 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5239 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5242 elm_widget_item_del(it);