3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_genlist.h"
9 #define MAX_ITEMS_PER_BLOCK 32
10 #define REORDER_EFFECT_TIME 0.5
12 #define ELM_GEN_SETUP(wd) \
13 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
14 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
15 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
17 #define ELM_GEN_ITEM_SETUP(it) \
18 (it)->del_cb = (Ecore_Cb)_item_del; \
19 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
20 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
21 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
22 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
24 typedef struct _Item_Block Item_Block;
25 typedef struct _Item_Cache Item_Cache;
27 struct Elm_Gen_Item_Type
32 Evas_Coord w, h, minw, minh;
33 Elm_Gen_Item *group_item;
34 Elm_Genlist_Item_Flags flags;
35 Eina_List *mode_texts, *mode_contents, *mode_states, *mode_content_objs;
36 Ecore_Timer *swipe_timer;
37 Evas_Coord scrl_x, scrl_y, old_scrl_y;
40 Evas_Object *mode_view;
46 Eina_Bool want_realize : 1;
47 Eina_Bool expanded : 1;
48 Eina_Bool mincalcd : 1;
51 Eina_Bool updateme : 1;
52 Eina_Bool nocache : 1;
53 Eina_Bool stacking_even : 1;
54 Eina_Bool nostacking : 1;
55 Eina_Bool move_effect_enabled : 1;
66 Evas_Coord x, y, w, h, minw, minh;
68 int item_position_stamp;
70 Eina_Bool position_update : 1;
71 Eina_Bool want_unrealize : 1;
72 Eina_Bool realized : 1;
73 Eina_Bool changed : 1;
74 Eina_Bool updateme : 1;
76 Eina_Bool must_recalc : 1;
83 Evas_Object *base_view, *spacer;
85 const char *item_style; // it->itc->item_style
86 Eina_Bool tree : 1; // it->group
87 Eina_Bool compress : 1; // it->wd->compress
89 Eina_Bool selected : 1; // it->selected
90 Eina_Bool disabled : 1; // it->disabled
91 Eina_Bool expanded : 1; // it->item->expanded
94 static const char *widtype = NULL;
95 static void _item_cache_zero(Widget_Data *wd);
96 static void _del_hook(Evas_Object *obj);
97 static void _mirrored_set(Evas_Object *obj,
99 static void _theme_hook(Evas_Object *obj);
100 static void _show_region_hook(void *data,
102 static void _sizing_eval(Evas_Object *obj);
103 static void _item_realize(Elm_Gen_Item *it,
106 static void _item_unrealize_cb(Elm_Gen_Item *it);
107 static void _item_block_unrealize(Item_Block *itb);
108 static void _calc_job(void *data);
109 static void _on_focus_hook(void *data,
111 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
112 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
113 static Eina_Bool _item_single_select_up(Widget_Data *wd);
114 static Eina_Bool _item_single_select_down(Widget_Data *wd);
115 static Eina_Bool _event_hook(Evas_Object *obj,
117 Evas_Callback_Type type,
119 static void _signal_emit_hook(Evas_Object *obj,
120 const char *emission,
122 static Eina_Bool _deselect_all_items(Widget_Data *wd);
123 static void _pan_calculate(Evas_Object *obj);
124 static void _pan_max_get(Evas_Object *obj,
127 static void _item_position(Elm_Gen_Item *it,
131 static void _mode_item_realize(Elm_Gen_Item *it);
132 static void _mode_item_unrealize(Elm_Gen_Item *it);
133 static void _item_mode_set(Elm_Gen_Item *it);
134 static void _item_mode_unset(Widget_Data *wd);
135 static void _group_items_recalc(void *data);
136 static void _item_move_after(Elm_Gen_Item *it,
137 Elm_Gen_Item *after);
138 static void _item_move_before(Elm_Gen_Item *it,
139 Elm_Gen_Item *before);
140 static void _item_auto_scroll(Widget_Data *wd);
141 static void _elm_genlist_clear(Evas_Object *obj,
143 static void _pan_child_size_get(Evas_Object *obj,
147 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
149 static const char SIG_ACTIVATED[] = "activated";
150 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
151 static const char SIG_SELECTED[] = "selected";
152 static const char SIG_UNSELECTED[] = "unselected";
153 static const char SIG_EXPANDED[] = "expanded";
154 static const char SIG_CONTRACTED[] = "contracted";
155 static const char SIG_EXPAND_REQUEST[] = "expand,request";
156 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
157 static const char SIG_REALIZED[] = "realized";
158 static const char SIG_UNREALIZED[] = "unrealized";
159 static const char SIG_DRAG_START_UP[] = "drag,start,up";
160 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
161 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
162 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
163 static const char SIG_DRAG_STOP[] = "drag,stop";
164 static const char SIG_DRAG[] = "drag";
165 static const char SIG_LONGPRESSED[] = "longpressed";
166 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
167 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
168 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
169 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
170 static const char SIG_EDGE_TOP[] = "edge,top";
171 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
172 static const char SIG_EDGE_LEFT[] = "edge,left";
173 static const char SIG_EDGE_RIGHT[] = "edge,right";
174 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
175 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
176 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
177 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
178 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
179 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
180 static const char SIG_SWIPE[] = "swipe";
181 static const char SIG_MOVED[] = "moved";
182 static const char SIG_INDEX_UPDATE[] = "index,update";
184 static const Evas_Smart_Cb_Description _signals[] = {
185 {SIG_CLICKED_DOUBLE, ""},
188 {SIG_UNSELECTED, ""},
190 {SIG_CONTRACTED, ""},
191 {SIG_EXPAND_REQUEST, ""},
192 {SIG_CONTRACT_REQUEST, ""},
194 {SIG_UNREALIZED, ""},
195 {SIG_DRAG_START_UP, ""},
196 {SIG_DRAG_START_DOWN, ""},
197 {SIG_DRAG_START_LEFT, ""},
198 {SIG_DRAG_START_RIGHT, ""},
201 {SIG_LONGPRESSED, ""},
202 {SIG_SCROLL_ANIM_START, ""},
203 {SIG_SCROLL_ANIM_STOP, ""},
204 {SIG_SCROLL_DRAG_START, ""},
205 {SIG_SCROLL_DRAG_STOP, ""},
207 {SIG_EDGE_BOTTOM, ""},
209 {SIG_EDGE_RIGHT, ""},
210 {SIG_MULTI_SWIPE_LEFT, ""},
211 {SIG_MULTI_SWIPE_RIGHT, ""},
212 {SIG_MULTI_SWIPE_UP, ""},
213 {SIG_MULTI_SWIPE_DOWN, ""},
214 {SIG_MULTI_PINCH_OUT, ""},
215 {SIG_MULTI_PINCH_IN, ""},
222 #undef ELM_CHECK_WIDTYPE
223 #define ELM_CHECK_WIDTYPE(obj, widtype) \
224 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
225 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
226 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
227 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
228 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
230 static const char *_gengrid = NULL;
231 static const char *_genlist = NULL;
233 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
235 elm_genlist_type_check(const Evas_Object *obj,
238 const char *provided, *expected = "(unknown)";
239 static int abort_on_warn = -1;
240 provided = elm_widget_type_get(obj);
241 if (!_genlist) _genlist = eina_stringshare_add("genlist");
242 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
243 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
245 if ((!provided) || (!provided[0]))
247 provided = evas_object_type_get(obj);
248 if ((!provided) || (!provided[0]))
249 provided = "(unknown)";
251 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
252 if (abort_on_warn == -1)
254 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
255 else abort_on_warn = 0;
257 if (abort_on_warn == 1) abort();
262 _event_hook(Evas_Object *obj,
263 Evas_Object *src __UNUSED__,
264 Evas_Callback_Type type,
267 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
268 Evas_Event_Key_Down *ev = event_info;
269 Widget_Data *wd = elm_widget_data_get(obj);
270 Evas_Coord pan_max_x = 0, pan_max_y = 0;
271 if (!wd) return EINA_FALSE;
272 if (!wd->items) return EINA_FALSE;
273 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
274 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
276 Elm_Gen_Item *it = NULL;
279 Evas_Coord step_x = 0;
280 Evas_Coord step_y = 0;
283 Evas_Coord page_x = 0;
284 Evas_Coord page_y = 0;
286 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
287 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
288 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
289 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
291 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
295 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
299 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
301 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
302 (_item_multi_select_up(wd)))
303 || (_item_single_select_up(wd)))
305 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
311 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
313 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
314 (_item_multi_select_down(wd)))
315 || (_item_single_select_down(wd)))
317 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
323 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
325 it = elm_genlist_first_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, "End")) || (!strcmp(ev->keyname, "KP_End")))
332 it = elm_genlist_last_item_get(obj);
333 elm_genlist_item_bring_in(it);
334 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
337 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
340 y -= -(page_y * v_h) / 100;
344 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
347 y += -(page_y * v_h) / 100;
351 else if (!strcmp(ev->keyname, "Escape"))
353 if (!_deselect_all_items(wd)) return EINA_FALSE;
354 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
357 else if (((!strcmp(ev->keyname, "Return")) ||
358 (!strcmp(ev->keyname, "KP_Enter")) ||
359 (!strcmp(ev->keyname, "space")))
360 && (!wd->multi) && (wd->selected))
362 it = elm_genlist_selected_item_get(obj);
363 elm_genlist_item_expanded_set(it,
364 !elm_genlist_item_expanded_get(it));
365 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
367 else return EINA_FALSE;
369 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
370 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
372 if (x > pan_max_x) x = pan_max_x;
374 if (y > pan_max_y) y = pan_max_y;
375 elm_smart_scroller_child_pos_set(wd->scr, x, y);
380 _deselect_all_items(Widget_Data *wd)
382 if (!wd->selected) return EINA_FALSE;
384 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
390 _item_multi_select_up(Widget_Data *wd)
392 if (!wd->selected) return EINA_FALSE;
393 if (!wd->multi) return EINA_FALSE;
395 Elm_Gen_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
396 if (!prev) return EINA_TRUE;
398 if (elm_genlist_item_selected_get(prev))
400 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
401 wd->last_selected_item = prev;
402 elm_genlist_item_show(wd->last_selected_item);
406 elm_genlist_item_selected_set(prev, EINA_TRUE);
407 elm_genlist_item_show(prev);
413 _item_multi_select_down(Widget_Data *wd)
415 if (!wd->selected) return EINA_FALSE;
416 if (!wd->multi) return EINA_FALSE;
418 Elm_Gen_Item *next = elm_genlist_item_next_get(wd->last_selected_item);
419 if (!next) return EINA_TRUE;
421 if (elm_genlist_item_selected_get(next))
423 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
424 wd->last_selected_item = next;
425 elm_genlist_item_show(wd->last_selected_item);
429 elm_genlist_item_selected_set(next, EINA_TRUE);
430 elm_genlist_item_show(next);
436 _item_single_select_up(Widget_Data *wd)
441 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
442 while ((prev) && (prev->generation < wd->generation))
443 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
445 else prev = elm_genlist_item_prev_get(wd->last_selected_item);
447 if (!prev) return EINA_FALSE;
449 _deselect_all_items(wd);
451 elm_genlist_item_selected_set(prev, EINA_TRUE);
452 elm_genlist_item_show(prev);
457 _item_single_select_down(Widget_Data *wd)
462 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
463 while ((next) && (next->generation < wd->generation))
464 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
466 else next = elm_genlist_item_next_get(wd->last_selected_item);
468 if (!next) return EINA_FALSE;
470 _deselect_all_items(wd);
472 elm_genlist_item_selected_set(next, EINA_TRUE);
473 elm_genlist_item_show(next);
478 _on_focus_hook(void *data __UNUSED__,
481 Widget_Data *wd = elm_widget_data_get(obj);
483 if (elm_widget_focus_get(obj))
485 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
486 evas_object_focus_set(wd->obj, EINA_TRUE);
487 if ((wd->selected) && (!wd->last_selected_item))
488 wd->last_selected_item = eina_list_data_get(wd->selected);
492 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
493 evas_object_focus_set(wd->obj, EINA_FALSE);
498 _del_hook(Evas_Object *obj)
500 Widget_Data *wd = elm_widget_data_get(obj);
502 _item_cache_zero(wd);
503 if (wd->calc_job) ecore_job_del(wd->calc_job);
504 if (wd->update_job) ecore_job_del(wd->update_job);
505 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
506 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
507 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
508 if (wd->mode_type) eina_stringshare_del(wd->mode_type);
509 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
514 _del_pre_hook(Evas_Object *obj)
516 Widget_Data *wd = elm_widget_data_get(obj);
518 elm_genlist_clear(obj);
519 evas_object_del(wd->pan_smart);
520 wd->pan_smart = NULL;
524 _mirrored_set(Evas_Object *obj,
527 Widget_Data *wd = elm_widget_data_get(obj);
529 _item_cache_zero(wd);
530 elm_smart_scroller_mirrored_set(wd->scr, rtl);
534 _theme_hook(Evas_Object *obj)
536 Widget_Data *wd = elm_widget_data_get(obj);
539 evas_event_freeze(evas_object_evas_get(wd->obj));
540 _item_cache_zero(wd);
541 _elm_widget_mirrored_reload(obj);
542 _mirrored_set(obj, elm_widget_mirrored_get(obj));
543 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
544 elm_widget_style_get(obj));
545 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
546 wd->item_width = wd->item_height = 0;
547 wd->group_item_width = wd->group_item_height = 0;
548 wd->minw = wd->minh = wd->realminw = 0;
549 EINA_INLIST_FOREACH(wd->blocks, itb)
554 if (itb->realized) _item_block_unrealize(itb);
555 EINA_LIST_FOREACH(itb->items, l, it)
556 it->item->mincalcd = EINA_FALSE;
558 itb->changed = EINA_TRUE;
560 if (wd->calc_job) ecore_job_del(wd->calc_job);
561 wd->calc_job = ecore_job_add(_calc_job, wd);
563 evas_event_thaw(evas_object_evas_get(wd->obj));
564 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
568 _show_region_hook(void *data,
571 Widget_Data *wd = elm_widget_data_get(data);
572 Evas_Coord x, y, w, h;
574 elm_widget_show_region_get(obj, &x, &y, &w, &h);
575 //x & y are screen coordinates, Add with pan coordinates
578 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
582 _translate_hook(Evas_Object *obj)
584 evas_object_smart_callback_call(obj, "language,changed", NULL);
588 _sizing_eval(Evas_Object *obj)
590 Widget_Data *wd = elm_widget_data_get(obj);
591 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
593 evas_object_size_hint_min_get(wd->scr, &minw, &minh);
594 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
596 if (wd->height_for_width)
600 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
601 if ((vw != 0) && (vw != wd->prev_viewport_w))
605 wd->prev_viewport_w = vw;
606 EINA_INLIST_FOREACH(wd->blocks, itb)
608 itb->must_recalc = EINA_TRUE;
610 if (wd->calc_job) ecore_job_del(wd->calc_job);
611 wd->calc_job = ecore_job_add(_calc_job, wd);
614 if (wd->mode == ELM_LIST_LIMIT)
620 edje_object_size_min_calc
621 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
628 edje_object_size_min_calc
629 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
633 evas_object_size_hint_min_set(obj, minw, minh);
634 evas_object_size_hint_max_set(obj, maxw, maxh);
638 _signal_emit_hook(Evas_Object *obj,
639 const char *emission,
642 Widget_Data *wd = elm_widget_data_get(obj);
643 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
648 _item_highlight(Elm_Gen_Item *it)
650 const char *selectraise;
651 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->highlighted) ||
652 (it->disabled) || (it->display_only) || (it->item->mode_view))
654 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
655 selectraise = edje_object_data_get(VIEW(it), "selectraise");
656 if ((selectraise) && (!strcmp(selectraise, "on")))
658 evas_object_raise(VIEW(it));
659 if ((it->item->group_item) && (it->item->group_item->realized))
660 evas_object_raise(it->item->VIEW(group_item));
662 it->highlighted = EINA_TRUE;
666 _item_unhighlight(Elm_Gen_Item *it)
668 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
669 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
670 if (!it->item->nostacking)
672 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even) evas_object_lower(VIEW(it));
673 else evas_object_raise(VIEW(it));
675 it->highlighted = EINA_FALSE;
679 _item_block_position_update(Eina_Inlist *list, int idx)
683 EINA_INLIST_FOREACH(list, tmp)
685 tmp->position = idx++;
686 tmp->position_update = EINA_TRUE;
691 _item_position_update(Eina_List *list, int idx)
696 EINA_LIST_FOREACH(list, l, it)
698 it->position = idx++;
699 it->position_update = EINA_TRUE;
704 _item_block_del(Elm_Gen_Item *it)
707 Item_Block *itb = it->item->block;
709 itb->items = eina_list_remove(itb->items, it);
711 itb->changed = EINA_TRUE;
712 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
713 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
716 il = EINA_INLIST_GET(itb);
717 Item_Block *itbn = (Item_Block *)(il->next);
719 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
722 _item_block_position_update(il->next, itb->position);
723 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
726 if (itbn) itbn->changed = EINA_TRUE;
730 if (itb->count < itb->wd->max_items_per_block/2)
732 il = EINA_INLIST_GET(itb);
733 Item_Block *itbp = (Item_Block *)(il->prev);
734 Item_Block *itbn = (Item_Block *)(il->next);
735 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
739 EINA_LIST_FREE(itb->items, it2)
741 it2->item->block = itbp;
742 itbp->items = eina_list_append(itbp->items, it2);
744 itbp->changed = EINA_TRUE;
746 _item_block_position_update(EINA_INLIST_GET(itb)->next,
748 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
749 EINA_INLIST_GET(itb));
752 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
756 Eina_List *last = eina_list_last(itb->items);
757 Elm_Gen_Item *it2 = last->data;
759 it2->item->block = itbn;
760 itb->items = eina_list_remove_list(itb->items, last);
761 itbn->items = eina_list_prepend(itbn->items, it2);
763 itbn->changed = EINA_TRUE;
765 _item_block_position_update(EINA_INLIST_GET(itb)->next,
768 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
776 _item_del(Elm_Gen_Item *it)
778 Evas_Object *obj = WIDGET(it);
780 evas_event_freeze(evas_object_evas_get(obj));
781 elm_genlist_item_subitems_clear(it);
782 if (it->wd->show_item == it) it->wd->show_item = NULL;
783 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
784 if (it->item->block) _item_block_del(it);
785 if (it->item->queued)
786 it->wd->queue = eina_list_remove(it->wd->queue, it);
787 if (it->wd->anchor_item == it)
789 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
790 if (!it->wd->anchor_item)
791 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
794 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
795 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
796 _elm_genlist_item_del_serious(it);
797 evas_event_thaw(evas_object_evas_get(obj));
798 evas_event_thaw_eval(evas_object_evas_get(obj));
802 _clear_cb(Widget_Data *wd)
804 wd->anchor_item = NULL;
807 Item_Block *itb = (Item_Block *)(wd->blocks);
809 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
810 if (itb->items) eina_list_free(itb->items);
813 if (wd->queue_idle_enterer)
815 ecore_idle_enterer_del(wd->queue_idle_enterer);
816 wd->queue_idle_enterer = NULL;
818 if (wd->must_recalc_idler)
820 ecore_idler_del(wd->must_recalc_idler);
821 wd->must_recalc_idler = NULL;
823 if (wd->queue) wd->queue = eina_list_free(wd->queue);
824 if (wd->reorder_move_animator)
826 ecore_animator_del(wd->reorder_move_animator);
827 wd->reorder_move_animator = NULL;
829 wd->show_item = NULL;
830 wd->reorder_old_pan_y = 0;
834 _item_unselect(Elm_Gen_Item *it)
836 if ((it->generation < it->wd->generation) || (!it->selected)) return;
837 it->selected = EINA_FALSE;
838 it->wd->selected = eina_list_remove(it->wd->selected, it);
839 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
843 _mouse_move(void *data,
844 Evas *evas __UNUSED__,
848 Elm_Gen_Item *it = data;
849 Evas_Event_Mouse_Move *ev = event_info;
850 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
851 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
853 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
855 if (!it->wd->on_hold)
857 it->wd->on_hold = EINA_TRUE;
858 if (!it->wd->wasselected)
860 _item_unhighlight(it);
865 if (it->wd->multitouched)
867 it->wd->cur_x = ev->cur.canvas.x;
868 it->wd->cur_y = ev->cur.canvas.y;
871 if ((it->dragging) && (it->down))
873 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
876 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
877 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
878 if (abs((it->wd->history[it->wd->movements].x -
879 it->wd->history[0].x)) > 40)
880 it->wd->swipe = EINA_TRUE;
886 ecore_timer_del(it->long_timer);
887 it->long_timer = NULL;
889 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
892 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
896 ecore_timer_del(it->long_timer);
897 it->long_timer = NULL;
899 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
901 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
902 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
904 if (!it->wd->reorder_start_y)
905 it->wd->reorder_start_y = it->item->block->y + it->y;
909 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
910 y_pos = oy + oh - it->wd->reorder_it->item->h;
914 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
916 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
917 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
921 if (!it->display_only)
922 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
923 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
924 x = ev->cur.canvas.x - x;
925 y = ev->cur.canvas.y - y;
928 if (adx < 0) adx = -dx;
931 if (ady < 0) ady = -dy;
934 if ((adx > minw) || (ady > minh))
936 it->dragging = EINA_TRUE;
939 ecore_timer_del(it->long_timer);
940 it->long_timer = NULL;
942 if (!it->wd->wasselected)
944 _item_unhighlight(it);
950 evas_object_smart_callback_call(WIDGET(it),
951 SIG_DRAG_START_UP, it);
955 evas_object_smart_callback_call(WIDGET(it),
956 SIG_DRAG_START_LEFT, it);
958 evas_object_smart_callback_call(WIDGET(it),
959 SIG_DRAG_START_RIGHT, it);
965 evas_object_smart_callback_call(WIDGET(it),
966 SIG_DRAG_START_DOWN, it);
970 evas_object_smart_callback_call(WIDGET(it),
971 SIG_DRAG_START_LEFT, it);
973 evas_object_smart_callback_call(WIDGET(it),
974 SIG_DRAG_START_RIGHT, it);
981 _long_press(void *data)
983 Elm_Gen_Item *it = data, *it_tmp;
986 it->long_timer = NULL;
987 if ((it->disabled) || (it->dragging) || (it->display_only))
988 return ECORE_CALLBACK_CANCEL;
989 it->wd->longpressed = EINA_TRUE;
990 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
991 if ((it->wd->reorder_mode) && (!it->group))
993 it->wd->reorder_it = it;
994 it->wd->reorder_start_y = 0;
996 evas_object_raise(VIEW(it));
997 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
998 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1000 list = elm_genlist_realized_items_get(it->wd->obj);
1001 EINA_LIST_FOREACH(list, l, it_tmp)
1003 if (it != it_tmp) _item_unselect(it_tmp);
1005 if (elm_genlist_item_expanded_get(it))
1007 elm_genlist_item_expanded_set(it, EINA_FALSE);
1008 return ECORE_CALLBACK_RENEW;
1010 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1012 return ECORE_CALLBACK_CANCEL;
1016 _swipe(Elm_Gen_Item *it)
1021 if ((it->display_only) || (it->disabled)) return;
1022 it->wd->swipe = EINA_FALSE;
1023 for (i = 0; i < it->wd->movements; i++)
1025 sum += it->wd->history[i].x;
1026 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1029 sum /= it->wd->movements;
1030 if (abs(sum - it->wd->history[0].x) <= 10) return;
1031 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1035 _swipe_cancel(void *data)
1037 Elm_Gen_Item *it = data;
1039 if (!it) return ECORE_CALLBACK_CANCEL;
1040 it->wd->swipe = EINA_FALSE;
1041 it->wd->movements = 0;
1042 return ECORE_CALLBACK_RENEW;
1046 _multi_cancel(void *data)
1048 Widget_Data *wd = data;
1050 if (!wd) return ECORE_CALLBACK_CANCEL;
1051 wd->multi_timeout = EINA_TRUE;
1052 return ECORE_CALLBACK_RENEW;
1056 _multi_touch_gesture_eval(void *data)
1058 Elm_Gen_Item *it = data;
1060 it->wd->multitouched = EINA_FALSE;
1061 if (it->wd->multi_timer)
1063 ecore_timer_del(it->wd->multi_timer);
1064 it->wd->multi_timer = NULL;
1066 if (it->wd->multi_timeout)
1068 it->wd->multi_timeout = EINA_FALSE;
1072 Evas_Coord minw = 0, minh = 0;
1073 Evas_Coord off_x, off_y, off_mx, off_my;
1075 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1076 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1077 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1078 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1079 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1081 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1083 if ((off_x + off_mx) > (off_y + off_my))
1085 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1086 evas_object_smart_callback_call(WIDGET(it),
1087 SIG_MULTI_SWIPE_RIGHT, it);
1088 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1089 evas_object_smart_callback_call(WIDGET(it),
1090 SIG_MULTI_SWIPE_LEFT, it);
1091 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1092 evas_object_smart_callback_call(WIDGET(it),
1093 SIG_MULTI_PINCH_OUT, it);
1095 evas_object_smart_callback_call(WIDGET(it),
1096 SIG_MULTI_PINCH_IN, it);
1100 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1101 evas_object_smart_callback_call(WIDGET(it),
1102 SIG_MULTI_SWIPE_DOWN, it);
1103 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1104 evas_object_smart_callback_call(WIDGET(it),
1105 SIG_MULTI_SWIPE_UP, it);
1106 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1107 evas_object_smart_callback_call(WIDGET(it),
1108 SIG_MULTI_PINCH_OUT, it);
1110 evas_object_smart_callback_call(WIDGET(it),
1111 SIG_MULTI_PINCH_IN, it);
1114 it->wd->multi_timeout = EINA_FALSE;
1118 _multi_down(void *data,
1119 Evas *evas __UNUSED__,
1120 Evas_Object *obj __UNUSED__,
1123 Elm_Gen_Item *it = data;
1124 Evas_Event_Multi_Down *ev = event_info;
1126 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1127 it->wd->multi_device = ev->device;
1128 it->wd->multi_down = EINA_TRUE;
1129 it->wd->multitouched = EINA_TRUE;
1130 it->wd->prev_mx = ev->canvas.x;
1131 it->wd->prev_my = ev->canvas.y;
1132 if (!it->wd->wasselected)
1134 _item_unhighlight(it);
1137 it->wd->wasselected = EINA_FALSE;
1138 it->wd->longpressed = EINA_FALSE;
1141 ecore_timer_del(it->long_timer);
1142 it->long_timer = NULL;
1146 it->dragging = EINA_FALSE;
1147 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1149 if (it->item->swipe_timer)
1151 ecore_timer_del(it->item->swipe_timer);
1152 it->item->swipe_timer = NULL;
1154 if (it->wd->on_hold)
1156 it->wd->swipe = EINA_FALSE;
1157 it->wd->movements = 0;
1158 it->wd->on_hold = EINA_FALSE;
1163 _multi_up(void *data,
1164 Evas *evas __UNUSED__,
1165 Evas_Object *obj __UNUSED__,
1168 Elm_Gen_Item *it = data;
1169 Evas_Event_Multi_Up *ev = event_info;
1171 if (it->wd->multi_device != ev->device) return;
1172 it->wd->multi_device = 0;
1173 it->wd->multi_down = EINA_FALSE;
1174 if (it->wd->mouse_down) return;
1175 _multi_touch_gesture_eval(data);
1179 _multi_move(void *data,
1180 Evas *evas __UNUSED__,
1181 Evas_Object *obj __UNUSED__,
1184 Elm_Gen_Item *it = data;
1185 Evas_Event_Multi_Move *ev = event_info;
1187 if (it->wd->multi_device != ev->device) return;
1188 it->wd->cur_mx = ev->cur.canvas.x;
1189 it->wd->cur_my = ev->cur.canvas.y;
1193 _mouse_down(void *data,
1194 Evas *evas __UNUSED__,
1198 Elm_Gen_Item *it = data;
1199 Evas_Event_Mouse_Down *ev = event_info;
1202 if (ev->button != 1) return;
1203 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1205 it->wd->on_hold = EINA_TRUE;
1208 it->down = EINA_TRUE;
1209 it->dragging = EINA_FALSE;
1210 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1211 it->dx = ev->canvas.x - x;
1212 it->dy = ev->canvas.y - y;
1213 it->wd->mouse_down = EINA_TRUE;
1214 if (!it->wd->multitouched)
1216 it->wd->prev_x = ev->canvas.x;
1217 it->wd->prev_y = ev->canvas.y;
1218 it->wd->multi_timeout = EINA_FALSE;
1219 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1220 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1222 it->wd->longpressed = EINA_FALSE;
1223 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1224 else it->wd->on_hold = EINA_FALSE;
1225 if (it->wd->on_hold) return;
1226 it->wd->wasselected = it->selected;
1227 _item_highlight(it);
1228 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1229 if ((!it->disabled) && (!it->display_only))
1231 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1232 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1234 if (it->long_timer) ecore_timer_del(it->long_timer);
1235 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1236 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1238 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1241 it->long_timer = NULL;
1242 it->wd->swipe = EINA_FALSE;
1243 it->wd->movements = 0;
1247 _mouse_up(void *data,
1248 Evas *evas __UNUSED__,
1249 Evas_Object *obj __UNUSED__,
1252 Elm_Gen_Item *it = data;
1253 Evas_Event_Mouse_Up *ev = event_info;
1254 Eina_Bool dragged = EINA_FALSE;
1256 if (ev->button != 1) return;
1257 it->down = EINA_FALSE;
1258 it->wd->mouse_down = EINA_FALSE;
1259 if (it->wd->multitouched)
1261 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1262 if (it->wd->multi_down) return;
1263 _multi_touch_gesture_eval(data);
1266 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1267 else it->wd->on_hold = EINA_FALSE;
1270 ecore_timer_del(it->long_timer);
1271 it->long_timer = NULL;
1275 it->dragging = EINA_FALSE;
1276 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1279 if (it->item->swipe_timer)
1281 ecore_timer_del(it->item->swipe_timer);
1282 it->item->swipe_timer = NULL;
1284 if (it->wd->multi_timer)
1286 ecore_timer_del(it->wd->multi_timer);
1287 it->wd->multi_timer = NULL;
1288 it->wd->multi_timeout = EINA_FALSE;
1290 if (it->wd->on_hold)
1292 if (it->wd->swipe) _swipe(data);
1293 it->wd->longpressed = EINA_FALSE;
1294 it->wd->on_hold = EINA_FALSE;
1297 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1299 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1301 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1303 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1304 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1306 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1310 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1311 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1313 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1314 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1315 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1316 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1318 if (it->wd->longpressed)
1320 it->wd->longpressed = EINA_FALSE;
1321 if (!it->wd->wasselected)
1323 _item_unhighlight(it);
1326 it->wd->wasselected = EINA_FALSE;
1331 if (it->want_unrealize)
1333 _elm_genlist_item_unrealize(it, EINA_FALSE);
1334 if (it->item->block->want_unrealize)
1335 _item_block_unrealize(it->item->block);
1338 if ((it->disabled) || (dragged) || (it->display_only)) return;
1339 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1344 _item_highlight(it);
1349 _item_unhighlight(it);
1357 Widget_Data *wd = it->wd;
1360 while (wd->selected)
1362 _item_unhighlight(wd->selected->data);
1363 _item_unselect(wd->selected->data);
1369 const Eina_List *l, *l_next;
1372 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1375 _item_unhighlight(it2);
1376 _item_unselect(it2);
1378 //_item_highlight(it);
1381 _item_highlight(it);
1387 _signal_expand_toggle(void *data,
1388 Evas_Object *obj __UNUSED__,
1389 const char *emission __UNUSED__,
1390 const char *source __UNUSED__)
1392 Elm_Gen_Item *it = data;
1394 if (it->item->expanded)
1395 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1397 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1401 _signal_expand(void *data,
1402 Evas_Object *obj __UNUSED__,
1403 const char *emission __UNUSED__,
1404 const char *source __UNUSED__)
1406 Elm_Gen_Item *it = data;
1408 if (!it->item->expanded)
1409 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1413 _signal_contract(void *data,
1414 Evas_Object *obj __UNUSED__,
1415 const char *emission __UNUSED__,
1416 const char *source __UNUSED__)
1418 Elm_Gen_Item *it = data;
1420 if (it->item->expanded)
1421 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1425 _scr_hold_timer_cb(void *data)
1427 if (!data) return ECORE_CALLBACK_CANCEL;
1428 Widget_Data *wd = data;
1429 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1430 wd->scr_hold_timer = NULL;
1431 return ECORE_CALLBACK_CANCEL;
1435 _mode_finished_signal_cb(void *data,
1437 const char *emission __UNUSED__,
1438 const char *source __UNUSED__)
1442 Elm_Gen_Item *it = data;
1443 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1445 Evas *te = evas_object_evas_get(obj);
1447 evas_event_freeze(te);
1448 it->item->nocache = EINA_FALSE;
1449 _mode_item_unrealize(it);
1450 if (it->item->group_item)
1451 evas_object_raise(it->item->VIEW(group_item));
1452 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->mode_type);
1453 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1454 evas_event_thaw(te);
1455 evas_event_thaw_eval(te);
1459 _item_cache_clean(Widget_Data *wd)
1461 evas_event_freeze(evas_object_evas_get(wd->obj));
1462 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1466 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1467 wd->item_cache = eina_inlist_remove(wd->item_cache,
1468 wd->item_cache->last);
1469 wd->item_cache_count--;
1470 if (itc->spacer) evas_object_del(itc->spacer);
1471 if (itc->base_view) evas_object_del(itc->base_view);
1472 if (itc->item_style) eina_stringshare_del(itc->item_style);
1475 evas_event_thaw(evas_object_evas_get(wd->obj));
1476 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1480 _item_cache_zero(Widget_Data *wd)
1482 int pmax = wd->item_cache_max;
1483 wd->item_cache_max = 0;
1484 _item_cache_clean(wd);
1485 wd->item_cache_max = pmax;
1489 _item_cache_add(Elm_Gen_Item *it)
1493 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1494 if (it->wd->item_cache_max <= 0)
1496 evas_object_del(VIEW(it));
1498 evas_object_del(it->spacer);
1500 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1501 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1505 it->wd->item_cache_count++;
1506 itc = calloc(1, sizeof(Item_Cache));
1507 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1508 EINA_INLIST_GET(itc));
1509 itc->spacer = it->spacer;
1511 itc->base_view = VIEW(it);
1513 evas_object_hide(itc->base_view);
1514 evas_object_move(itc->base_view, -9999, -9999);
1515 itc->item_style = eina_stringshare_add(it->itc->item_style);
1516 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) itc->tree = 1;
1517 itc->compress = (it->wd->compress);
1518 itc->selected = it->selected;
1519 itc->disabled = it->disabled;
1520 itc->expanded = it->item->expanded;
1523 ecore_timer_del(it->long_timer);
1524 it->long_timer = NULL;
1526 if (it->item->swipe_timer)
1528 ecore_timer_del(it->item->swipe_timer);
1529 it->item->swipe_timer = NULL;
1531 // FIXME: other callbacks?
1532 edje_object_signal_callback_del_full(itc->base_view,
1533 "elm,action,expand,toggle",
1534 "elm", _signal_expand_toggle, it);
1535 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1537 _signal_expand, it);
1538 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1539 "elm", _signal_contract, it);
1540 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1542 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1544 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1546 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1548 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1550 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1552 _item_cache_clean(it->wd);
1553 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1554 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1558 _item_cache_find(Elm_Gen_Item *it)
1563 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) tree = 1;
1564 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1566 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1568 if ((itc->tree == tree) &&
1569 (itc->compress == it->wd->compress) &&
1570 (!strcmp(it->itc->item_style, itc->item_style)))
1572 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1573 EINA_INLIST_GET(itc));
1574 it->wd->item_cache_count--;
1582 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1584 if (it->position_update || it->item->block->position_update)
1586 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1587 it->position_update = EINA_FALSE;
1592 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1594 if (!it->item->nostacking)
1596 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1597 evas_object_lower(VIEW(it));
1599 evas_object_raise(VIEW(it));
1602 if (it->item->order_num_in & 0x1)
1603 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1605 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1609 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1613 if (it->selected != itc->selected)
1616 edje_object_signal_emit(VIEW(it),
1617 "elm,state,selected", "elm");
1619 if (it->disabled != itc->disabled)
1622 edje_object_signal_emit(VIEW(it),
1623 "elm,state,disabled", "elm");
1625 if (it->item->expanded != itc->expanded)
1627 if (it->item->expanded)
1628 edje_object_signal_emit(VIEW(it),
1629 "elm,state,expanded", "elm");
1635 edje_object_signal_emit(VIEW(it),
1636 "elm,state,selected", "elm");
1638 edje_object_signal_emit(VIEW(it),
1639 "elm,state,disabled", "elm");
1640 if (it->item->expanded)
1641 edje_object_signal_emit(VIEW(it),
1642 "elm,state,expanded", "elm");
1647 _item_cache_free(Item_Cache *itc)
1649 if (itc->spacer) evas_object_del(itc->spacer);
1650 if (itc->base_view) evas_object_del(itc->base_view);
1651 if (itc->item_style) eina_stringshare_del(itc->item_style);
1656 _item_del_hook(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1658 Elm_Gen_Item *it = event_info;
1660 if (it->wd->last_selected_item == it)
1661 it->wd->last_selected_item = NULL;
1665 _item_text_realize(Elm_Gen_Item *it,
1666 Evas_Object *target,
1670 if (it->itc->func.text_get)
1675 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1676 EINA_LIST_FOREACH(*source, l, key)
1678 if (parts && fnmatch(parts, key, FNM_PERIOD))
1681 char *s = it->itc->func.text_get
1682 ((void *)it->base.data, WIDGET(it), key);
1686 edje_object_part_text_set(target, key, s);
1691 edje_object_part_text_set(target, key, "");
1698 _item_content_unrealize(Elm_Gen_Item *it,
1699 Evas_Object *target,
1703 Eina_List *res = it->content_objs;
1705 if (it->itc->func.content_get)
1709 Evas_Object *ic = NULL;
1711 EINA_LIST_FOREACH(*source, l, key)
1713 if (parts && fnmatch(parts, key, FNM_PERIOD))
1716 ic = edje_object_part_swallow_get(target, key);
1719 res = eina_list_remove(res, ic);
1720 edje_object_part_unswallow(target, ic);
1721 evas_object_del(ic);
1730 _item_content_realize(Elm_Gen_Item *it,
1731 Evas_Object *target,
1735 Eina_List *res = NULL;
1737 if (it->itc->func.content_get)
1741 Evas_Object *ic = NULL;
1743 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1745 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
1746 res = it->content_objs;
1748 EINA_LIST_FOREACH(*source, l, key)
1750 if (parts && fnmatch(parts, key, FNM_PERIOD))
1753 if (it->itc->func.content_get)
1754 ic = it->itc->func.content_get
1755 ((void *)it->base.data, WIDGET(it), key);
1758 res = eina_list_append(res, ic);
1759 edje_object_part_swallow(target, key, ic);
1760 evas_object_show(ic);
1761 elm_widget_sub_object_add(WIDGET(it), ic);
1763 elm_widget_disabled_set(ic, EINA_TRUE);
1772 _item_state_realize(Elm_Gen_Item *it,
1773 Evas_Object *target,
1777 if (it->itc->func.state_get)
1783 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
1784 EINA_LIST_FOREACH(*source, l, key)
1786 if (parts && fnmatch(parts, key, FNM_PERIOD))
1789 Eina_Bool on = it->itc->func.state_get
1790 ((void *)it->base.data, WIDGET(it), key);
1794 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1795 edje_object_signal_emit(target, buf, "elm");
1799 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1800 edje_object_signal_emit(target, buf, "elm");
1807 _item_realize(Elm_Gen_Item *it,
1811 const char *treesize;
1814 Item_Cache *itc = NULL;
1816 if (it->generation < it->wd->generation) return;
1817 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1820 if (it->item->order_num_in != in)
1822 it->item->order_num_in = in;
1823 _elm_genlist_item_odd_even_update(it);
1824 _elm_genlist_item_state_update(it, NULL);
1825 _elm_genlist_item_index_update(it);
1827 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1828 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1831 it->item->order_num_in = in;
1833 if (it->item->nocache)
1834 it->item->nocache = EINA_FALSE;
1836 itc = _item_cache_find(it);
1839 VIEW(it) = itc->base_view;
1840 itc->base_view = NULL;
1841 it->spacer = itc->spacer;
1846 const char *stacking_even;
1847 const char *stacking;
1849 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1850 edje_object_scale_set(VIEW(it),
1851 elm_widget_scale_get(WIDGET(it)) *
1852 _elm_config->scale);
1853 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
1854 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1856 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
1857 strncpy(buf, "tree", sizeof(buf));
1858 else strncpy(buf, "item", sizeof(buf));
1859 if (it->wd->compress)
1860 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1862 strncat(buf, "/", sizeof(buf) - strlen(buf));
1863 strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1865 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
1866 elm_widget_style_get(WIDGET(it)));
1868 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1869 if (!stacking_even) stacking_even = "above";
1870 it->item->stacking_even = !!strcmp("above", stacking_even);
1872 stacking = edje_object_data_get(VIEW(it), "stacking");
1873 if (!stacking) stacking = "yes";
1874 it->item->nostacking = !!strcmp("yes", stacking);
1876 edje_object_mirrored_set(VIEW(it),
1877 elm_widget_mirrored_get(WIDGET(it)));
1879 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1880 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1881 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1884 _elm_genlist_item_odd_even_update(it);
1886 treesize = edje_object_data_get(VIEW(it), "treesize");
1887 if (treesize) tsize = atoi(treesize);
1888 evas_object_size_hint_min_set(it->spacer,
1889 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
1890 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1893 edje_object_signal_callback_add(VIEW(it),
1894 "elm,action,expand,toggle",
1895 "elm", _signal_expand_toggle, it);
1896 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
1897 "elm", _signal_expand, it);
1898 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
1899 "elm", _signal_contract, it);
1900 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
1902 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
1904 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1906 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
1908 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
1910 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
1913 _elm_genlist_item_state_update(it, itc);
1914 _elm_genlist_item_index_update(it);
1917 if ((calc) && (it->wd->homogeneous) &&
1918 ((it->wd->item_width) ||
1919 ((it->wd->item_width) && (it->wd->group_item_width))))
1921 /* homogenous genlist shortcut */
1922 if (!it->item->mincalcd)
1926 it->item->w = it->item->minw = it->wd->group_item_width;
1927 it->item->h = it->item->minh = it->wd->group_item_height;
1931 it->item->w = it->item->minw = it->wd->item_width;
1932 it->item->h = it->item->minh = it->wd->item_height;
1934 it->item->mincalcd = EINA_TRUE;
1939 /* FIXME: If you see that assert, please notify us and we
1940 will clean our mess */
1941 assert(eina_list_count(it->content_objs) == 0);
1943 _item_text_realize(it, VIEW(it), &it->texts, NULL);
1944 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
1945 _item_state_realize(it, VIEW(it), &it->states, NULL);
1947 if (!it->item->mincalcd)
1949 Evas_Coord mw = -1, mh = -1;
1951 if (!it->display_only)
1952 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1953 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
1954 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
1956 if (!it->display_only)
1957 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1958 it->item->w = it->item->minw = mw;
1959 it->item->h = it->item->minh = mh;
1960 it->item->mincalcd = EINA_TRUE;
1962 if ((!it->wd->group_item_width) && (it->group))
1964 it->wd->group_item_width = mw;
1965 it->wd->group_item_height = mh;
1967 else if ((!it->wd->item_width) && (it->item->flags == ELM_GENLIST_ITEM_NONE))
1969 it->wd->item_width = mw;
1970 it->wd->item_height = mh;
1973 if (!calc) evas_object_show(VIEW(it));
1976 if (it->tooltip.content_cb)
1978 elm_widget_item_tooltip_content_cb_set(it,
1979 it->tooltip.content_cb,
1980 it->tooltip.data, NULL);
1981 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1982 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1985 if (it->mouse_cursor)
1986 elm_widget_item_cursor_set(it, it->mouse_cursor);
1988 it->realized = EINA_TRUE;
1989 it->want_unrealize = EINA_FALSE;
1991 if (itc) _item_cache_free(itc);
1992 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1993 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1995 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1996 edje_object_message_signal_process(VIEW(it));
2000 _item_unrealize_cb(Elm_Gen_Item *it)
2002 if (it->item->nocache)
2004 evas_object_del(VIEW(it));
2006 evas_object_del(it->spacer);
2011 edje_object_mirrored_set(VIEW(it),
2012 elm_widget_mirrored_get(WIDGET(it)));
2013 edje_object_scale_set(VIEW(it),
2014 elm_widget_scale_get(WIDGET(it))
2015 * _elm_config->scale);
2016 _item_cache_add(it);
2019 _mode_item_unrealize(it);
2021 it->realized = EINA_FALSE;
2022 it->want_unrealize = EINA_FALSE;
2026 _item_block_recalc(Item_Block *itb,
2032 Evas_Coord minw = 0, minh = 0;
2033 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2036 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2038 EINA_LIST_FOREACH(itb->items, l, it)
2040 if (it->generation < it->wd->generation) continue;
2041 showme |= it->item->showme;
2046 if (!it->item->mincalcd) changed = EINA_TRUE;
2049 _item_realize(it, in, EINA_TRUE);
2050 _elm_genlist_item_unrealize(it, EINA_TRUE);
2055 _item_realize(it, in, EINA_TRUE);
2056 _elm_genlist_item_unrealize(it, EINA_TRUE);
2060 _item_realize(it, in, EINA_FALSE);
2061 minh += it->item->minh;
2062 if (minw < it->item->minw) minw = it->item->minw;
2070 itb->changed = EINA_FALSE;
2071 itb->position_update = EINA_FALSE;
2072 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2073 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2078 _item_block_realize(Item_Block *itb)
2080 if (itb->realized) return;
2081 itb->realized = EINA_TRUE;
2082 itb->want_unrealize = EINA_FALSE;
2086 _item_block_unrealize(Item_Block *itb)
2090 Eina_Bool dragging = EINA_FALSE;
2092 if (!itb->realized) return;
2093 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2094 EINA_LIST_FOREACH(itb->items, l, it)
2096 if (itb->must_recalc || !it->group)
2100 dragging = EINA_TRUE;
2101 it->want_unrealize = EINA_TRUE;
2104 _elm_genlist_item_unrealize(it, EINA_FALSE);
2109 itb->realized = EINA_FALSE;
2110 itb->want_unrealize = EINA_TRUE;
2113 itb->want_unrealize = EINA_FALSE;
2114 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2115 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2119 _get_space_for_reorder_item(Elm_Gen_Item *it)
2121 Evas_Coord rox, roy, row, roh, oy, oh;
2122 Eina_Bool top = EINA_FALSE;
2123 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2124 if (!reorder_it) return 0;
2126 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2127 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2129 if ((it->wd->reorder_start_y < it->item->block->y) &&
2130 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2132 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2133 if (it->item->block->count == 1)
2134 it->wd->reorder_rel = it;
2136 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2137 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2139 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2142 it->item->block->reorder_offset = 0;
2144 it->item->scrl_y += it->item->block->reorder_offset;
2146 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2147 rox, roy + (roh / 2), row, 1));
2150 it->wd->reorder_rel = it;
2151 it->item->scrl_y += it->wd->reorder_it->item->h;
2152 return it->wd->reorder_it->item->h;
2159 _reorder_move_animator_cb(void *data)
2161 Elm_Gen_Item *it = data;
2162 Eina_Bool down = EINA_FALSE;
2164 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2166 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2168 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2171 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2172 if (diff > it->item->h) y = diff / 2;
2174 if (it->item->old_scrl_y < it->item->scrl_y)
2176 it->item->old_scrl_y += y;
2179 else if (it->item->old_scrl_y > it->item->scrl_y)
2181 it->item->old_scrl_y -= y;
2184 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2185 _group_items_recalc(it->wd);
2187 if ((it->wd->reorder_pan_move) ||
2188 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2189 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2191 it->item->old_scrl_y = it->item->scrl_y;
2192 it->item->move_effect_enabled = EINA_FALSE;
2193 it->wd->reorder_move_animator = NULL;
2194 return ECORE_CALLBACK_CANCEL;
2196 return ECORE_CALLBACK_RENEW;
2200 _item_position(Elm_Gen_Item *it,
2208 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2209 evas_object_resize(view, it->item->w, it->item->h);
2210 evas_object_move(view, it_x, it_y);
2211 evas_object_show(view);
2212 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2213 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2217 _item_block_position(Item_Block *itb,
2223 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2224 Eina_Bool vis = EINA_FALSE;
2226 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2227 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2228 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2230 EINA_LIST_FOREACH(itb->items, l, it)
2232 if (it->generation < it->wd->generation) continue;
2233 else if (it->wd->reorder_it == it) continue;
2236 it->item->w = itb->w;
2237 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2238 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2240 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2241 cvx, cvy, cvw, cvh));
2244 if ((itb->realized) && (!it->realized))
2246 if (vis) _item_realize(it, in, EINA_FALSE);
2252 if (it->wd->reorder_mode)
2253 y += _get_space_for_reorder_item(it);
2254 git = it->item->group_item;
2257 if (git->item->scrl_y < oy)
2258 git->item->scrl_y = oy;
2259 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2260 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2261 git->item->want_realize = EINA_TRUE;
2263 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2265 if (!it->item->move_effect_enabled)
2267 it->item->move_effect_enabled = EINA_TRUE;
2268 it->wd->reorder_move_animator =
2270 _reorder_move_animator_cb, it);
2273 if (!it->item->move_effect_enabled)
2275 if (it->item->mode_view)
2276 _item_position(it, it->item->mode_view, it->item->scrl_x,
2279 _item_position(it, VIEW(it), it->item->scrl_x,
2281 it->item->old_scrl_y = it->item->scrl_y;
2286 if (!it->dragging) _elm_genlist_item_unrealize(it, EINA_FALSE);
2293 if (vis) it->item->want_realize = EINA_TRUE;
2297 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2298 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2302 _group_items_recalc(void *data)
2304 Widget_Data *wd = data;
2308 evas_event_freeze(evas_object_evas_get(wd->obj));
2309 EINA_LIST_FOREACH(wd->group_items, l, git)
2311 if (git->item->want_realize)
2314 _item_realize(git, 0, EINA_FALSE);
2315 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2316 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2317 evas_object_show(VIEW(git));
2318 evas_object_raise(VIEW(git));
2320 else if (!git->item->want_realize && git->realized)
2323 _elm_genlist_item_unrealize(git, EINA_FALSE);
2326 evas_event_thaw(evas_object_evas_get(wd->obj));
2327 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2331 _must_recalc_idler(void *data)
2333 Widget_Data *wd = data;
2334 if (wd->calc_job) ecore_job_del(wd->calc_job);
2335 wd->calc_job = ecore_job_add(_calc_job, wd);
2336 wd->must_recalc_idler = NULL;
2337 return ECORE_CALLBACK_CANCEL;
2341 _scroll_item(Widget_Data *wd)
2343 Elm_Genlist_Item *it = NULL;
2344 Evas_Coord gith = 0;
2345 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2347 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2349 dx = it->x + it->item->block->x;
2350 dy = it->y + it->item->block->y;
2351 dw = it->item->block->w;
2353 switch (wd->scrollto_type)
2355 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2356 if (it->item->group_item) gith = it->item->group_item->item->h;
2359 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2360 dy += (it->item->h / 2 - oh / 2);
2362 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2364 if ((wd->expanded_item) &&
2365 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2366 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2368 it = wd->expanded_item;
2369 if (it->item->group_item) gith = it->item->group_item->item->h;
2370 dx = it->x + it->item->block->x;
2371 dy = it->y + it->item->block->y - gith;
2372 dw = it->item->block->w;
2376 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2377 gith = it->item->group_item->item->h;
2384 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2386 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2388 it->item->showme = EINA_FALSE;
2389 wd->show_item = NULL;
2390 wd->auto_scroll_enabled = EINA_FALSE;
2391 wd->check_scroll = EINA_FALSE;
2395 _calc_job(void *data)
2397 Widget_Data *wd = data;
2398 Item_Block *itb, *chb = NULL;
2399 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0;
2400 Evas_Coord pan_w = 0, pan_h = 0;
2402 Eina_Bool minw_change = EINA_FALSE;
2403 Eina_Bool did_must_recalc = EINA_FALSE;
2406 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2410 evas_event_freeze(evas_object_evas_get(wd->obj));
2411 EINA_INLIST_FOREACH(wd->blocks, itb)
2413 Eina_Bool showme = EINA_FALSE;
2416 showme = itb->showme;
2417 itb->showme = EINA_FALSE;
2420 if (itb->realized) _item_block_unrealize(itb);
2422 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2424 if (itb->must_recalc)
2428 EINA_LIST_FOREACH(itb->items, l, it)
2429 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2430 itb->changed = EINA_TRUE;
2431 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2432 if (itb->realized) _item_block_unrealize(itb);
2433 itb->must_recalc = EINA_FALSE;
2435 showme = _item_block_recalc(itb, in, EINA_FALSE);
2441 if (minw == -1) minw = itb->minw;
2442 else if ((!itb->must_recalc) && (minw < itb->minw))
2445 minw_change = EINA_TRUE;
2451 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2452 wd->check_scroll = EINA_TRUE;
2456 EINA_INLIST_FOREACH(wd->blocks, itb)
2462 if ((chb) && (EINA_INLIST_GET(chb)->next))
2464 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2466 if (itb->realized) _item_block_unrealize(itb);
2469 wd->realminw = minw;
2470 if (minw < wd->w) minw = wd->w;
2471 if ((minw != wd->minw) || (minh != wd->minh))
2475 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2476 _sizing_eval(wd->obj);
2477 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2482 it = wd->anchor_item;
2483 it_y = wd->anchor_y;
2484 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2485 it->item->block->y + it->y + it_y);
2486 wd->anchor_item = it;
2487 wd->anchor_y = it_y;
2490 if (did_must_recalc)
2492 if (!wd->must_recalc_idler)
2493 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2495 if (wd->check_scroll)
2497 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2498 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2499 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2500 switch (wd->scrollto_type)
2502 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2505 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2508 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2513 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2514 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2519 wd->calc_job = NULL;
2520 evas_object_smart_changed(wd->pan_smart);
2521 evas_event_thaw(evas_object_evas_get(wd->obj));
2522 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2526 _update_job(void *data)
2528 Widget_Data *wd = data;
2532 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2534 wd->update_job = NULL;
2537 evas_event_freeze(evas_object_evas_get(wd->obj));
2538 EINA_INLIST_FOREACH(wd->blocks, itb)
2540 Evas_Coord itminw, itminh;
2547 _item_block_position(itb, num);
2551 recalc = EINA_FALSE;
2552 EINA_LIST_FOREACH(itb->items, l2, it)
2554 if (it->item->updateme)
2556 itminw = it->item->minw;
2557 itminh = it->item->minh;
2559 it->item->updateme = EINA_FALSE;
2562 _elm_genlist_item_unrealize(it, EINA_FALSE);
2563 _item_realize(it, num, EINA_FALSE);
2564 position = EINA_TRUE;
2568 _item_realize(it, num, EINA_TRUE);
2569 _elm_genlist_item_unrealize(it, EINA_TRUE);
2571 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2576 itb->updateme = EINA_FALSE;
2579 position = EINA_TRUE;
2580 itb->changed = EINA_TRUE;
2581 _item_block_recalc(itb, num0, EINA_FALSE);
2582 _item_block_position(itb, num0);
2587 if (wd->calc_job) ecore_job_del(wd->calc_job);
2588 wd->calc_job = ecore_job_add(_calc_job, wd);
2590 evas_event_thaw(evas_object_evas_get(wd->obj));
2591 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2595 _pan_set(Evas_Object *obj,
2599 Pan *sd = evas_object_smart_data_get(obj);
2603 // Evas_Coord ow, oh;
2604 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2605 // ow = sd->wd->minw - ow;
2606 // if (ow < 0) ow = 0;
2607 // oh = sd->wd->minh - oh;
2608 // if (oh < 0) oh = 0;
2609 // if (x < 0) x = 0;
2610 // if (y < 0) y = 0;
2611 // if (x > ow) x = ow;
2612 // if (y > oh) y = oh;
2613 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2617 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2619 if ((itb->y + itb->h) > y)
2624 EINA_LIST_FOREACH(itb->items, l2, it)
2626 if ((itb->y + it->y) >= y)
2628 sd->wd->anchor_item = it;
2629 sd->wd->anchor_y = -(itb->y + it->y - y);
2636 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2640 _pan_get(Evas_Object *obj,
2644 Pan *sd = evas_object_smart_data_get(obj);
2647 if (x) *x = sd->wd->pan_x;
2648 if (y) *y = sd->wd->pan_y;
2652 _pan_max_get(Evas_Object *obj,
2656 Pan *sd = evas_object_smart_data_get(obj);
2660 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2661 ow = sd->wd->minw - ow;
2663 oh = sd->wd->minh - oh;
2670 _pan_min_get(Evas_Object *obj __UNUSED__,
2679 _pan_child_size_get(Evas_Object *obj,
2683 Pan *sd = evas_object_smart_data_get(obj);
2686 if (w) *w = sd->wd->minw;
2687 if (h) *h = sd->wd->minh;
2691 _pan_add(Evas_Object *obj)
2694 Evas_Object_Smart_Clipped_Data *cd;
2697 cd = evas_object_smart_data_get(obj);
2700 sd->__clipped_data = *cd;
2702 evas_object_smart_data_set(obj, sd);
2706 _pan_del(Evas_Object *obj)
2708 Pan *sd = evas_object_smart_data_get(obj);
2713 ecore_job_del(sd->resize_job);
2714 sd->resize_job = NULL;
2720 _pan_resize_job(void *data)
2724 _sizing_eval(sd->wd->obj);
2725 sd->resize_job = NULL;
2729 _pan_resize(Evas_Object *obj,
2733 Pan *sd = evas_object_smart_data_get(obj);
2737 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2738 if ((ow == w) && (oh == h)) return;
2739 if ((sd->wd->height_for_width) && (ow != w))
2742 if (sd->resize_job) ecore_job_del(sd->resize_job);
2743 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2745 sd->wd->pan_changed = EINA_TRUE;
2746 evas_object_smart_changed(obj);
2747 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2748 sd->wd->calc_job = NULL;
2750 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2751 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2756 _pan_calculate(Evas_Object *obj)
2758 Pan *sd = evas_object_smart_data_get(obj);
2760 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2766 evas_event_freeze(evas_object_evas_get(obj));
2768 if (sd->wd->pan_changed)
2771 sd->wd->pan_changed = EINA_FALSE;
2774 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2775 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2776 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2778 git->item->want_realize = EINA_FALSE;
2780 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2782 itb->w = sd->wd->minw;
2783 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2784 itb->y - sd->wd->pan_y + oy,
2786 cvx, cvy, cvw, cvh))
2788 if ((!itb->realized) || (itb->changed))
2789 _item_block_realize(itb);
2790 _item_block_position(itb, in);
2794 if (itb->realized) _item_block_unrealize(itb);
2798 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2799 _group_items_recalc(sd->wd);
2800 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2802 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2803 sd->wd->reorder_pan_move = EINA_TRUE;
2804 else sd->wd->reorder_pan_move = EINA_FALSE;
2805 evas_object_raise(sd->wd->VIEW(reorder_it));
2806 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2807 sd->wd->start_time = ecore_loop_time_get();
2809 _item_auto_scroll(sd->wd);
2810 evas_event_thaw(evas_object_evas_get(obj));
2811 evas_event_thaw_eval(evas_object_evas_get(obj));
2815 _pan_move(Evas_Object *obj,
2816 Evas_Coord x __UNUSED__,
2817 Evas_Coord y __UNUSED__)
2819 Pan *sd = evas_object_smart_data_get(obj);
2823 sd->wd->pan_changed = EINA_TRUE;
2824 evas_object_smart_changed(obj);
2825 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2826 sd->wd->calc_job = NULL;
2830 _hold_on(void *data __UNUSED__,
2832 void *event_info __UNUSED__)
2834 Widget_Data *wd = elm_widget_data_get(obj);
2836 elm_smart_scroller_hold_set(wd->scr, 1);
2840 _hold_off(void *data __UNUSED__,
2842 void *event_info __UNUSED__)
2844 Widget_Data *wd = elm_widget_data_get(obj);
2846 elm_smart_scroller_hold_set(wd->scr, 0);
2850 _freeze_on(void *data __UNUSED__,
2852 void *event_info __UNUSED__)
2854 Widget_Data *wd = elm_widget_data_get(obj);
2856 elm_smart_scroller_freeze_set(wd->scr, 1);
2860 _freeze_off(void *data __UNUSED__,
2862 void *event_info __UNUSED__)
2864 Widget_Data *wd = elm_widget_data_get(obj);
2866 elm_smart_scroller_freeze_set(wd->scr, 0);
2870 _scr_anim_start(void *data,
2871 Evas_Object *obj __UNUSED__,
2872 void *event_info __UNUSED__)
2874 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
2878 _scr_anim_stop(void *data,
2879 Evas_Object *obj __UNUSED__,
2880 void *event_info __UNUSED__)
2882 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
2886 _scr_drag_start(void *data,
2887 Evas_Object *obj __UNUSED__,
2888 void *event_info __UNUSED__)
2890 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
2894 _scr_drag_stop(void *data,
2895 Evas_Object *obj __UNUSED__,
2896 void *event_info __UNUSED__)
2898 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
2902 _edge_left(void *data,
2903 Evas_Object *scr __UNUSED__,
2904 void *event_info __UNUSED__)
2906 Evas_Object *obj = data;
2907 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2911 _edge_right(void *data,
2912 Evas_Object *scr __UNUSED__,
2913 void *event_info __UNUSED__)
2915 Evas_Object *obj = data;
2916 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2920 _edge_top(void *data,
2921 Evas_Object *scr __UNUSED__,
2922 void *event_info __UNUSED__)
2924 Evas_Object *obj = data;
2925 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2929 _edge_bottom(void *data,
2930 Evas_Object *scr __UNUSED__,
2931 void *event_info __UNUSED__)
2933 Evas_Object *obj = data;
2934 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2938 _mode_item_realize(Elm_Gen_Item *it)
2942 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
2944 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2945 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
2946 edje_object_scale_set(it->item->mode_view,
2947 elm_widget_scale_get(WIDGET(it)) *
2948 _elm_config->scale);
2949 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
2950 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
2952 strncpy(buf, "item", sizeof(buf));
2953 if (it->wd->compress)
2954 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
2956 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
2957 strncat(buf, "/", sizeof(buf) - strlen(buf));
2958 strncat(buf, it->wd->mode_item_style, sizeof(buf) - strlen(buf));
2960 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
2961 elm_widget_style_get(WIDGET(it)));
2962 edje_object_mirrored_set(it->item->mode_view,
2963 elm_widget_mirrored_get(WIDGET(it)));
2965 /* signal callback add */
2966 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
2968 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
2970 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
2973 /* text_get, content_get, state_get */
2974 /* FIXME: If you see that assert, please notify us and we
2975 will clean our mess */
2976 assert(eina_list_count(it->item->mode_content_objs) == 0);
2978 _item_text_realize(it, it->item->mode_view, &it->item->mode_texts, NULL);
2979 it->item->mode_content_objs =
2980 _item_content_realize(it, it->item->mode_view,
2981 &it->item->mode_contents, NULL);
2982 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
2984 edje_object_part_swallow(it->item->mode_view,
2985 edje_object_data_get(it->item->mode_view, "mode_part"),
2988 it->want_unrealize = EINA_FALSE;
2989 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2990 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2994 _mode_item_unrealize(Elm_Gen_Item *it)
2996 Widget_Data *wd = it->wd;
2997 Evas_Object *content;
2998 if (!it->item->mode_view) return;
3000 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3001 elm_widget_stringlist_free(it->item->mode_texts);
3002 it->item->mode_texts = NULL;
3003 elm_widget_stringlist_free(it->item->mode_contents);
3004 it->item->mode_contents = NULL;
3005 elm_widget_stringlist_free(it->item->mode_states);
3007 EINA_LIST_FREE(it->item->mode_content_objs, content)
3008 evas_object_del(content);
3010 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
3011 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3012 evas_object_del(it->item->mode_view);
3013 it->item->mode_view = NULL;
3015 if (wd->mode_item == it)
3016 wd->mode_item = NULL;
3017 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3018 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3022 _item_mode_set(Elm_Gen_Item *it)
3025 Widget_Data *wd = it->wd;
3030 it->item->nocache = EINA_TRUE;
3032 if (wd->scr_hold_timer)
3034 ecore_timer_del(wd->scr_hold_timer);
3035 wd->scr_hold_timer = NULL;
3037 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3038 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3040 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3041 _mode_item_realize(it);
3042 if (it->item->group_item)
3043 evas_object_raise(it->item->VIEW(group_item));
3044 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
3045 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3046 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3048 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
3049 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3053 _item_mode_unset(Widget_Data *wd)
3056 if (!wd->mode_item) return;
3057 char buf[1024], buf2[1024];
3061 it->item->nocache = EINA_TRUE;
3063 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
3064 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
3066 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3067 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
3069 wd->mode_item = NULL;
3073 _item_auto_scroll(Widget_Data *wd)
3076 Elm_Gen_Item *tmp_item = NULL;
3078 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3080 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3081 if (!tmp_item) return;
3082 wd->show_item = tmp_item;
3083 wd->bring_in = EINA_TRUE;
3084 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3085 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3087 wd->show_item->item->showme = EINA_TRUE;
3088 wd->auto_scroll_enabled = EINA_FALSE;
3096 elm_genlist_add(Evas_Object *parent)
3101 Evas_Coord minw, minh;
3102 static Evas_Smart *smart = NULL;
3106 static Evas_Smart_Class sc;
3108 evas_object_smart_clipped_smart_set(&_pan_sc);
3110 sc.name = "elm_genlist_pan";
3111 sc.version = EVAS_SMART_CLASS_VERSION;
3114 sc.resize = _pan_resize;
3115 sc.move = _pan_move;
3116 sc.calculate = _pan_calculate;
3117 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3120 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3122 ELM_SET_WIDTYPE(widtype, "genlist");
3124 elm_widget_type_set(obj, "genlist");
3125 elm_widget_sub_object_add(parent, obj);
3126 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3127 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3128 elm_widget_data_set(obj, wd);
3129 elm_widget_del_hook_set(obj, _del_hook);
3130 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3131 elm_widget_theme_hook_set(obj, _theme_hook);
3132 elm_widget_can_focus_set(obj, EINA_TRUE);
3133 elm_widget_event_hook_set(obj, _event_hook);
3134 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3135 elm_widget_translate_hook_set(obj, _translate_hook);
3138 wd->scr = elm_smart_scroller_add(e);
3139 elm_smart_scroller_widget_set(wd->scr, obj);
3140 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3141 elm_widget_style_get(obj));
3142 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3143 _elm_config->thumbscroll_bounce_enable);
3144 elm_widget_resize_object_set(obj, wd->scr);
3146 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3147 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3148 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3149 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3150 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3151 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3152 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3153 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3156 wd->mode = ELM_LIST_SCROLL;
3157 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3158 wd->item_cache_max = wd->max_items_per_block * 2;
3159 wd->longpress_timeout = _elm_config->longpress_timeout;
3161 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3162 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3163 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3164 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3166 wd->pan_smart = evas_object_smart_add(e, smart);
3167 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3170 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3171 _pan_set, _pan_get, _pan_max_get,
3172 _pan_min_get, _pan_child_size_get);
3174 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3176 evas_object_size_hint_min_set(obj, minw, minh);
3178 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3180 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3186 _item_select(Elm_Gen_Item *it)
3188 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3191 it->selected = EINA_TRUE;
3192 it->wd->selected = eina_list_append(it->wd->selected, it);
3194 else if (!it->wd->always_select) return;
3196 evas_object_ref(WIDGET(it));
3199 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3200 if (it->generation == it->wd->generation)
3201 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3204 evas_object_unref(WIDGET(it));
3205 if ((it->wd->clear_me) && (!it->wd->walking))
3206 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3209 if ((!it->walking) && (it->generation < it->wd->generation))
3211 if (!it->relcount) it->del_cb(it);
3214 it->wd->last_selected_item = it;
3218 static Evas_Object *
3219 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3221 return edje_object_part_swallow_get(VIEW(it), part);
3225 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3227 edje_object_part_swallow(VIEW(it), part, content);
3230 static Evas_Object *
3231 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3235 obj = edje_object_part_swallow_get(VIEW(it), part);
3236 if (!obj) return NULL;
3237 edje_object_part_unswallow(VIEW(it), obj);
3242 _item_text_hook(Elm_Gen_Item *it, const char *part)
3244 if (!it->itc->func.text_get) return NULL;
3245 return edje_object_part_text_get(VIEW(it), part);
3249 _elm_genlist_item_new(Widget_Data *wd,
3250 const Elm_Gen_Item_Class *itc,
3252 Elm_Gen_Item *parent,
3254 const void *func_data)
3258 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3259 if (!it) return NULL;
3261 it->generation = wd->generation;
3263 it->base.data = data;
3264 it->parent = parent;
3265 it->func.func = func;
3266 it->func.data = func_data;
3267 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3268 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3269 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3271 it->sel_cb = (Ecore_Cb)_item_select;
3273 elm_widget_item_text_get_hook_set(it, _item_text_hook);
3277 static Elm_Gen_Item *
3278 _item_new(Widget_Data *wd,
3279 const Elm_Genlist_Item_Class *itc,
3281 Elm_Gen_Item *parent,
3282 Elm_Genlist_Item_Flags flags,
3284 const void *func_data)
3286 Elm_Gen_Item *it, *it2;
3289 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3290 if (!it) return NULL;
3291 it->item = ELM_NEW(Elm_Gen_Item_Type);
3292 it->item->flags = flags;
3293 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3294 it->item->expanded_depth = 0;
3295 elm_widget_item_del_cb_set(it, _item_del_hook);
3296 ELM_GEN_ITEM_SETUP(it);
3299 if (it->parent->group)
3300 it->item->group_item = parent;
3301 else if (it->parent->item->group_item)
3302 it->item->group_item = it->parent->item->group_item;
3304 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3306 if (!it2->parent->group) depth += 1;
3308 it->item->expanded_depth = depth;
3313 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3317 itb = calloc(1, sizeof(Item_Block));
3318 if (!itb) return NULL;
3322 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3323 _item_block_position_update(wd->blocks, 0);
3327 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3328 itb->position_update = EINA_TRUE;
3329 if (wd->blocks != EINA_INLIST_GET(itb))
3331 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3342 _item_block_add(Widget_Data *wd,
3345 Item_Block *itb = NULL;
3352 itb = calloc(1, sizeof(Item_Block));
3353 if (!itb) return EINA_FALSE;
3355 if (!it->item->rel->item->block)
3358 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3359 itb->items = eina_list_append(itb->items, it);
3360 itb->position_update = EINA_TRUE;
3361 it->position = eina_list_count(itb->items);
3362 it->position_update = EINA_TRUE;
3364 if (wd->blocks != EINA_INLIST_GET(itb))
3366 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3377 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3378 if (it->item->before)
3380 wd->blocks = eina_inlist_prepend_relative
3381 (wd->blocks, EINA_INLIST_GET(itb),
3382 EINA_INLIST_GET(it->item->rel->item->block));
3384 eina_list_prepend_relative_list(itb->items, it, tmp);
3386 /* Update index from where we prepended */
3387 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3388 _item_block_position_update(EINA_INLIST_GET(itb),
3389 it->item->rel->item->block->position);
3393 wd->blocks = eina_inlist_append_relative
3394 (wd->blocks, EINA_INLIST_GET(itb),
3395 EINA_INLIST_GET(it->item->rel->item->block));
3397 eina_list_append_relative_list(itb->items, it, tmp);
3399 /* Update block index from where we appended */
3400 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3401 _item_block_position_update(EINA_INLIST_GET(itb),
3402 it->item->rel->item->block->position + 1);
3408 if (it->item->before)
3412 itb = (Item_Block *)(wd->blocks);
3413 if (itb->count >= wd->max_items_per_block)
3415 itb = _item_block_new(wd, EINA_TRUE);
3416 if (!itb) return EINA_FALSE;
3421 itb = _item_block_new(wd, EINA_TRUE);
3422 if (!itb) return EINA_FALSE;
3424 itb->items = eina_list_prepend(itb->items, it);
3426 _item_position_update(itb->items, 0);
3432 itb = (Item_Block *)(wd->blocks->last);
3433 if (itb->count >= wd->max_items_per_block)
3435 itb = _item_block_new(wd, EINA_FALSE);
3436 if (!itb) return EINA_FALSE;
3441 itb = _item_block_new(wd, EINA_FALSE);
3442 if (!itb) return EINA_FALSE;
3444 itb->items = eina_list_append(itb->items, it);
3445 it->position = eina_list_count(itb->items);
3453 if (it->item->rel->item->queued)
3455 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3456 on sorted insertion order, so the queue is not always ordered like the item list.
3457 This lead to issue where we depend on an item that is not yet created. As a quick
3458 work around, we reschedule the calc of the item and stop reordering the list to
3459 prevent any nasty issue to show up here.
3461 wd->queue = eina_list_append(wd->queue, it);
3462 wd->requeued = EINA_TRUE;
3463 it->item->queued = EINA_TRUE;
3466 itb = it->item->rel->item->block;
3467 if (!itb) goto newblock;
3468 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3469 if (it->item->before)
3471 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3472 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3476 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3477 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3481 itb->changed = EINA_TRUE;
3482 it->item->block = itb;
3483 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3484 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3487 it->item->rel->relcount--;
3488 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3489 _item_del(it->item->rel);
3490 it->item->rel = NULL;
3492 if (itb->count > itb->wd->max_items_per_block)
3497 Eina_Bool done = EINA_FALSE;
3499 newc = itb->count / 2;
3501 if (EINA_INLIST_GET(itb)->prev)
3503 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3505 if (itbp->count + newc < wd->max_items_per_block / 2)
3507 /* moving items to previous block */
3508 while ((itb->count > newc) && (itb->items))
3510 it2 = eina_list_data_get(itb->items);
3511 itb->items = eina_list_remove_list(itb->items, itb->items);
3514 itbp->items = eina_list_append(itbp->items, it2);
3515 it2->item->block = itbp;
3523 if (!done && EINA_INLIST_GET(itb)->next)
3525 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3527 if (itbn->count + newc < wd->max_items_per_block / 2)
3529 /* moving items to next block */
3530 while ((itb->count > newc) && (itb->items))
3534 l = eina_list_last(itb->items);
3535 it2 = eina_list_data_get(l);
3536 itb->items = eina_list_remove_list(itb->items, l);
3539 itbn->items = eina_list_prepend(itbn->items, it2);
3540 it2->item->block = itbn;
3550 /* moving items to new block */
3551 itb2 = calloc(1, sizeof(Item_Block));
3552 if (!itb2) return EINA_FALSE;
3555 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3556 EINA_INLIST_GET(itb));
3557 itb2->changed = EINA_TRUE;
3558 while ((itb->count > newc) && (itb->items))
3562 l = eina_list_last(itb->items);
3564 itb->items = eina_list_remove_list(itb->items, l);
3567 itb2->items = eina_list_prepend(itb2->items, it2);
3568 it2->item->block = itb2;
3578 _queue_process(Widget_Data *wd)
3581 Eina_Bool showme = EINA_FALSE;
3584 t0 = ecore_loop_time_get();
3585 //evas_event_freeze(evas_object_evas_get(wd->obj));
3586 for (n = 0; (wd->queue) && (n < 128); n++)
3590 it = eina_list_data_get(wd->queue);
3591 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3592 it->item->queued = EINA_FALSE;
3593 if (!_item_block_add(wd, it)) continue;
3595 _item_block_realize(it->item->block);
3596 t = ecore_time_get();
3597 if (it->item->block->changed)
3599 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3600 it->item->block->changed = 0;
3601 if (wd->pan_changed)
3603 if (wd->calc_job) ecore_job_del(wd->calc_job);
3604 wd->calc_job = NULL;
3606 wd->pan_changed = EINA_FALSE;
3609 if (showme) it->item->block->showme = EINA_TRUE;
3610 /* same as eina_inlist_count > 1 */
3611 if (wd->blocks && wd->blocks->next)
3613 if ((t - t0) > (ecore_animator_frametime_get())) break;
3616 //evas_event_thaw(evas_object_evas_get(wd->obj));
3617 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3622 _idle_process(void *data, Eina_Bool *wakeup)
3624 Widget_Data *wd = data;
3627 //static double q_start = 0.0;
3628 //if (q_start == 0.0) q_start = ecore_time_get();
3630 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
3634 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
3636 return ECORE_CALLBACK_CANCEL;
3638 return ECORE_CALLBACK_RENEW;
3642 _item_idle_enterer(void *data)
3644 Widget_Data *wd = data;
3645 Eina_Bool wakeup = EINA_FALSE;
3646 Eina_Bool ok = _idle_process(data, &wakeup);
3651 if (wd->calc_job) ecore_job_del(wd->calc_job);
3652 wd->calc_job = ecore_job_add(_calc_job, wd);
3654 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
3659 _item_queue(Widget_Data *wd,
3663 if (it->item->queued) return;
3664 it->item->queued = EINA_TRUE;
3665 if (cb && !wd->requeued)
3666 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
3668 wd->queue = eina_list_append(wd->queue, it);
3669 // FIXME: why does a freeze then thaw here cause some genlist
3670 // elm_genlist_item_append() to be much much slower?
3671 // evas_event_freeze(evas_object_evas_get(wd->obj));
3672 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
3674 if (wd->queue_idle_enterer)
3676 ecore_idle_enterer_del(wd->queue_idle_enterer);
3677 wd->queue_idle_enterer = NULL;
3681 // evas_event_thaw(evas_object_evas_get(wd->obj));
3682 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3683 if (!wd->queue_idle_enterer)
3684 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
3688 _elm_genlist_item_compare_data(const void *data, const void *data1)
3690 const Elm_Gen_Item *it = data;
3691 const Elm_Gen_Item *item1 = data1;
3693 return it->wd->item_compare_data_cb(it->base.data, item1->base.data);
3697 _elm_genlist_item_compare(const void *data, const void *data1)
3699 const Elm_Gen_Item *it, *item1;
3700 it = ELM_GEN_ITEM_FROM_INLIST(data);
3701 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
3702 return it->wd->item_compare_cb(it, item1);
3706 _elm_genlist_item_list_compare(const void *data, const void *data1)
3708 const Elm_Gen_Item *it = data;
3709 const Elm_Gen_Item *item1 = data1;
3710 return it->wd->item_compare_cb(it, item1);
3714 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
3719 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3720 _item_block_del(it);
3722 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3723 it->item->rel = after;
3724 it->item->rel->relcount++;
3725 it->item->before = EINA_FALSE;
3726 if (after->item->group_item) it->item->group_item = after->item->group_item;
3727 _item_queue(it->wd, it, NULL);
3729 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3733 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
3736 if (!before) return;
3738 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3739 _item_block_del(it);
3740 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
3741 it->item->rel = before;
3742 it->item->rel->relcount++;
3743 it->item->before = EINA_TRUE;
3744 if (before->item->group_item) it->item->group_item = before->item->group_item;
3745 _item_queue(it->wd, it, NULL);
3747 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3751 elm_genlist_item_append(Evas_Object *obj,
3752 const Elm_Genlist_Item_Class *itc,
3754 Elm_Gen_Item *parent,
3755 Elm_Genlist_Item_Flags flags,
3757 const void *func_data)
3759 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3760 Widget_Data *wd = elm_widget_data_get(obj);
3761 if (!wd) return NULL;
3762 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3764 if (!it) return NULL;
3768 wd->group_items = eina_list_append(wd->group_items, it);
3769 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
3770 it->item->rel = NULL;
3774 Elm_Gen_Item *it2 = NULL;
3775 Eina_List *ll = eina_list_last(it->parent->item->items);
3776 if (ll) it2 = ll->data;
3777 it->parent->item->items = eina_list_append(it->parent->item->items, it);
3778 if (!it2) it2 = it->parent;
3780 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3781 EINA_INLIST_GET(it2));
3782 it->item->rel = it2;
3783 it->item->rel->relcount++;
3785 it->item->before = EINA_FALSE;
3786 _item_queue(wd, it, NULL);
3791 elm_genlist_item_prepend(Evas_Object *obj,
3792 const Elm_Genlist_Item_Class *itc,
3794 Elm_Gen_Item *parent,
3795 Elm_Genlist_Item_Flags flags,
3797 const void *func_data)
3799 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3800 Widget_Data *wd = elm_widget_data_get(obj);
3801 if (!wd) return NULL;
3802 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3804 if (!it) return NULL;
3808 wd->group_items = eina_list_prepend(wd->group_items, it);
3809 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
3810 it->item->rel = NULL;
3814 Elm_Gen_Item *it2 = NULL;
3815 Eina_List *ll = it->parent->item->items;
3816 if (ll) it2 = ll->data;
3817 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
3818 if (!it2) it2 = it->parent;
3820 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3821 EINA_INLIST_GET(it2));
3822 it->item->rel = it2;
3823 it->item->rel->relcount++;
3825 it->item->before = EINA_TRUE;
3826 _item_queue(wd, it, NULL);
3831 elm_genlist_item_insert_after(Evas_Object *obj,
3832 const Elm_Genlist_Item_Class *itc,
3834 Elm_Gen_Item *parent,
3835 Elm_Gen_Item *after,
3836 Elm_Genlist_Item_Flags flags,
3838 const void *func_data)
3840 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3841 EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3842 Widget_Data *wd = elm_widget_data_get(obj);
3843 if (!wd) return NULL;
3844 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
3845 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3847 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3849 if (!it) return NULL;
3854 wd->group_items = eina_list_append_relative(wd->group_items, it,
3859 it->parent->item->items = eina_list_append_relative(it->parent->item->items, it,
3862 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3863 EINA_INLIST_GET(after));
3864 it->item->rel = after;
3865 it->item->rel->relcount++;
3866 it->item->before = EINA_FALSE;
3867 _item_queue(wd, it, NULL);
3872 elm_genlist_item_insert_before(Evas_Object *obj,
3873 const Elm_Genlist_Item_Class *itc,
3875 Elm_Gen_Item *parent,
3876 Elm_Gen_Item *before,
3877 Elm_Genlist_Item_Flags flags,
3879 const void *func_data)
3881 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3882 EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
3883 Widget_Data *wd = elm_widget_data_get(obj);
3884 if (!wd) return NULL;
3885 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
3886 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3888 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3890 if (!it) return NULL;
3893 if (it->group && before->group)
3894 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
3899 it->parent->item->items = eina_list_prepend_relative(it->parent->item->items, it,
3902 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3903 EINA_INLIST_GET(before));
3904 it->item->rel = before;
3905 it->item->rel->relcount++;
3906 it->item->before = EINA_TRUE;
3907 _item_queue(wd, it, NULL);
3912 elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
3913 const Elm_Genlist_Item_Class *itc,
3915 Elm_Gen_Item *parent,
3916 Elm_Genlist_Item_Flags flags,
3917 Eina_Compare_Cb comp,
3919 const void *func_data)
3921 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3922 Widget_Data *wd = elm_widget_data_get(obj);
3923 if (!wd) return NULL;
3924 Elm_Gen_Item *rel = NULL;
3925 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3927 if (!it) return NULL;
3929 wd->item_compare_cb = comp;
3936 l = eina_list_search_sorted_near_list(it->parent->item->items,
3937 _elm_genlist_item_list_compare, it,
3940 rel = eina_list_data_get(l);
3944 if (cmp_result >= 0)
3946 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
3947 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3948 it->item->before = EINA_FALSE;
3950 else if (cmp_result < 0)
3952 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
3953 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3954 it->item->before = EINA_TRUE;
3961 wd->state = eina_inlist_sorted_state_new();
3962 eina_inlist_sorted_state_init(wd->state, wd->items);
3963 wd->requeued = EINA_FALSE;
3967 wd->group_items = eina_list_append(wd->group_items, it);
3969 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
3970 _elm_genlist_item_compare, wd->state);
3972 if (EINA_INLIST_GET(it)->next)
3974 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3975 it->item->before = EINA_TRUE;
3977 else if (EINA_INLIST_GET(it)->prev)
3979 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3980 it->item->before = EINA_FALSE;
3986 it->item->rel = rel;
3987 it->item->rel->relcount++;
3990 _item_queue(wd, it, _elm_genlist_item_list_compare);
3996 elm_genlist_item_sorted_insert(Evas_Object *obj,
3997 const Elm_Genlist_Item_Class *itc,
3999 Elm_Gen_Item *parent,
4000 Elm_Genlist_Item_Flags flags,
4001 Eina_Compare_Cb comp,
4003 const void *func_data)
4005 Widget_Data *wd = elm_widget_data_get(obj);
4006 wd->item_compare_data_cb = comp;
4008 return elm_genlist_item_direct_sorted_insert(obj, itc, data, parent, flags,
4009 _elm_genlist_item_compare_data, func, func_data);
4013 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4015 Eina_Inlist *next, *l;
4017 ELM_CHECK_WIDTYPE(obj, widtype);
4018 Widget_Data *wd = elm_widget_data_get(obj);
4021 if (!standby) wd->generation++;
4025 eina_inlist_sorted_state_free(wd->state);
4029 if (wd->walking > 0)
4034 evas_event_freeze(evas_object_evas_get(wd->obj));
4035 for (l = wd->items, next = l ? l->next : NULL;
4037 l = next, next = next ? next->next : NULL)
4039 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4041 if (it->generation < wd->generation)
4043 Elm_Gen_Item *itn = NULL;
4045 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4046 if (itn) itn->walking++; /* prevent early death of subitem */
4048 if (itn) itn->walking--;
4052 wd->pan_changed = EINA_TRUE;
4055 ecore_job_del(wd->calc_job);
4056 wd->calc_job = NULL;
4058 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4059 if (wd->clear_cb) wd->clear_cb(wd);
4067 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4068 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4070 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4071 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4072 evas_event_thaw(evas_object_evas_get(wd->obj));
4073 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4077 elm_genlist_clear(Evas_Object *obj)
4079 _elm_genlist_clear(obj, EINA_FALSE);
4083 elm_genlist_multi_select_set(Evas_Object *obj,
4086 ELM_CHECK_WIDTYPE(obj, widtype);
4087 Widget_Data *wd = elm_widget_data_get(obj);
4093 elm_genlist_multi_select_get(const Evas_Object *obj)
4095 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4096 Widget_Data *wd = elm_widget_data_get(obj);
4097 if (!wd) return EINA_FALSE;
4102 elm_genlist_selected_item_get(const Evas_Object *obj)
4104 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4105 Widget_Data *wd = elm_widget_data_get(obj);
4106 if (!wd) return NULL;
4107 if (wd->selected) return wd->selected->data;
4111 EAPI const Eina_List *
4112 elm_genlist_selected_items_get(const Evas_Object *obj)
4114 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4115 Widget_Data *wd = elm_widget_data_get(obj);
4116 if (!wd) return NULL;
4117 return wd->selected;
4121 elm_genlist_realized_items_get(const Evas_Object *obj)
4123 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4124 Widget_Data *wd = elm_widget_data_get(obj);
4125 Eina_List *list = NULL;
4127 Eina_Bool done = EINA_FALSE;
4128 if (!wd) return NULL;
4129 EINA_INLIST_FOREACH(wd->blocks, itb)
4137 EINA_LIST_FOREACH(itb->items, l, it)
4139 if (it->realized) list = eina_list_append(list, it);
4151 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4156 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4157 Widget_Data *wd = elm_widget_data_get(obj);
4158 Evas_Coord ox, oy, ow, oh;
4161 if (!wd) return NULL;
4162 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4164 EINA_INLIST_FOREACH(wd->blocks, itb)
4169 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4170 oy + itb->y - itb->wd->pan_y,
4171 itb->w, itb->h, x, y, 1, 1))
4173 EINA_LIST_FOREACH(itb->items, l, it)
4175 Evas_Coord itx, ity;
4177 itx = ox + itb->x + it->x - itb->wd->pan_x;
4178 ity = oy + itb->y + it->y - itb->wd->pan_y;
4179 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4183 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4184 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4190 lasty = ity + it->item->h;
4195 if (y > lasty) *posret = 1;
4202 elm_genlist_first_item_get(const Evas_Object *obj)
4204 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4205 Widget_Data *wd = elm_widget_data_get(obj);
4206 if (!wd) return NULL;
4207 if (!wd->items) return NULL;
4208 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4209 while ((it) && (it->generation < wd->generation))
4210 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4215 elm_genlist_last_item_get(const Evas_Object *obj)
4217 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4218 Widget_Data *wd = elm_widget_data_get(obj);
4219 if (!wd) return NULL;
4220 if (!wd->items) return NULL;
4221 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4222 while ((it) && (it->generation < wd->generation))
4223 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4228 elm_genlist_item_next_get(const Elm_Gen_Item *it)
4230 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4233 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4234 if ((it) && (it->generation == it->wd->generation)) break;
4236 return (Elm_Gen_Item *)it;
4240 elm_genlist_item_prev_get(const Elm_Gen_Item *it)
4242 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4245 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4246 if ((it) && (it->generation == it->wd->generation)) break;
4248 return (Elm_Gen_Item *)it;
4252 elm_genlist_item_genlist_get(const Elm_Gen_Item *it)
4254 return _elm_genlist_item_widget_get(it);
4258 elm_genlist_item_parent_get(const Elm_Gen_Item *it)
4260 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4265 elm_genlist_item_subitems_clear(Elm_Gen_Item *it)
4267 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4268 Eina_List *tl = NULL, *l;
4271 EINA_LIST_FOREACH(it->item->items, l, it2)
4272 tl = eina_list_append(tl, it2);
4273 EINA_LIST_FREE(tl, it2)
4274 elm_genlist_item_del(it2);
4278 elm_genlist_item_selected_set(Elm_Gen_Item *it,
4281 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4282 Widget_Data *wd = it->wd;
4284 if ((it->generation < wd->generation) || (it->disabled)) return;
4285 selected = !!selected;
4286 if (it->selected == selected) return;
4292 while (wd->selected)
4294 if (it->unhighlight_cb) it->unhighlight_cb(wd->selected->data);
4295 it->unsel_cb(wd->selected->data);
4298 it->highlight_cb(it);
4302 if (it->unhighlight_cb) it->unhighlight_cb(it);
4307 elm_genlist_item_selected_get(const Elm_Gen_Item *it)
4309 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4310 return it->selected;
4314 elm_genlist_item_expanded_set(Elm_Gen_Item *it,
4317 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4318 if (it->item->expanded == expanded) return;
4319 it->item->expanded = expanded;
4320 it->wd->expanded_item = it;
4321 if (it->item->expanded)
4324 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
4325 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
4326 it->wd->auto_scroll_enabled = EINA_TRUE;
4331 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
4332 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
4333 it->wd->auto_scroll_enabled = EINA_FALSE;
4338 elm_genlist_item_expanded_get(const Elm_Gen_Item *it)
4340 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4341 return it->item->expanded;
4345 elm_genlist_item_expanded_depth_get(const Elm_Gen_Item *it)
4347 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, 0);
4348 return it->item->expanded_depth;
4352 elm_genlist_item_disabled_set(Elm_Gen_Item *it,
4355 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4358 if (it->disabled == disabled) return;
4359 if (it->generation < it->wd->generation) return;
4360 it->disabled = !!disabled;
4362 elm_genlist_item_selected_set(it, EINA_FALSE);
4366 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4368 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
4369 EINA_LIST_FOREACH(it->content_objs, l, obj)
4370 elm_widget_disabled_set(obj, disabled);
4375 elm_genlist_item_disabled_get(const Elm_Gen_Item *it)
4377 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4378 if (it->generation < it->wd->generation) return EINA_FALSE;
4379 return it->disabled;
4383 elm_genlist_item_display_only_set(Elm_Gen_Item *it,
4384 Eina_Bool display_only)
4386 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4387 if (it->display_only == display_only) return;
4388 if (it->generation < it->wd->generation) return;
4389 it->display_only = display_only;
4390 it->item->mincalcd = EINA_FALSE;
4391 it->item->updateme = EINA_TRUE;
4392 if (it->item->block) it->item->block->updateme = EINA_TRUE;
4393 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4394 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4398 elm_genlist_item_display_only_get(const Elm_Gen_Item *it)
4400 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4401 if (it->generation < it->wd->generation) return EINA_FALSE;
4402 return it->display_only;
4406 elm_genlist_item_show(Elm_Gen_Item *it)
4408 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4409 Evas_Coord gith = 0;
4410 if (it->generation < it->wd->generation) return;
4411 if ((it->item->queued) || (!it->item->mincalcd))
4413 it->wd->show_item = it;
4414 it->wd->bring_in = EINA_FALSE;
4415 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
4416 it->item->showme = EINA_TRUE;
4419 if (it->wd->show_item)
4421 it->wd->show_item->item->showme = EINA_FALSE;
4422 it->wd->show_item = NULL;
4424 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4425 gith = it->item->group_item->item->h;
4426 elm_smart_scroller_child_region_show(it->wd->scr,
4427 it->x + it->item->block->x,
4428 it->y + it->item->block->y - gith,
4429 it->item->block->w, it->item->h);
4433 elm_genlist_item_promote(Elm_Gen_Item *it)
4435 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4436 if (it->generation < it->wd->generation) return;
4437 _item_move_before(it, elm_genlist_first_item_get(WIDGET(it)));
4441 elm_genlist_item_demote(Elm_Gen_Item *it)
4443 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4444 if (it->generation < it->wd->generation) return;
4445 _item_move_after(it, elm_genlist_last_item_get(WIDGET(it)));
4449 elm_genlist_item_bring_in(Elm_Gen_Item *it)
4451 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4452 Evas_Coord gith = 0;
4453 if (it->generation < it->wd->generation) return;
4454 if ((it->item->queued) || (!it->item->mincalcd))
4456 it->wd->show_item = it;
4457 it->wd->bring_in = EINA_TRUE;
4458 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
4459 it->item->showme = EINA_TRUE;
4462 if (it->wd->show_item)
4464 it->wd->show_item->item->showme = EINA_FALSE;
4465 it->wd->show_item = NULL;
4467 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4468 gith = it->item->group_item->item->h;
4469 elm_smart_scroller_region_bring_in(it->wd->scr,
4470 it->x + it->item->block->x,
4471 it->y + it->item->block->y - gith,
4472 it->item->block->w, it->item->h);
4476 elm_genlist_item_top_show(Elm_Gen_Item *it)
4478 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4480 Evas_Coord gith = 0;
4482 if (it->generation < it->wd->generation) return;
4483 if ((it->item->queued) || (!it->item->mincalcd))
4485 it->wd->show_item = it;
4486 it->wd->bring_in = EINA_FALSE;
4487 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
4488 it->item->showme = EINA_TRUE;
4491 if (it->wd->show_item)
4493 it->wd->show_item->item->showme = EINA_FALSE;
4494 it->wd->show_item = NULL;
4496 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4497 if (it->item->group_item) gith = it->item->group_item->item->h;
4498 elm_smart_scroller_child_region_show(it->wd->scr,
4499 it->x + it->item->block->x,
4500 it->y + it->item->block->y - gith,
4501 it->item->block->w, oh);
4505 elm_genlist_item_top_bring_in(Elm_Gen_Item *it)
4507 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4509 Evas_Coord gith = 0;
4511 if (it->generation < it->wd->generation) return;
4512 if ((it->item->queued) || (!it->item->mincalcd))
4514 it->wd->show_item = it;
4515 it->wd->bring_in = EINA_TRUE;
4516 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
4517 it->item->showme = EINA_TRUE;
4520 if (it->wd->show_item)
4522 it->wd->show_item->item->showme = EINA_FALSE;
4523 it->wd->show_item = NULL;
4525 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4526 if (it->item->group_item) gith = it->item->group_item->item->h;
4527 elm_smart_scroller_region_bring_in(it->wd->scr,
4528 it->x + it->item->block->x,
4529 it->y + it->item->block->y - gith,
4530 it->item->block->w, oh);
4534 elm_genlist_item_middle_show(Elm_Gen_Item *it)
4536 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4539 if (it->generation < it->wd->generation) return;
4540 if ((it->item->queued) || (!it->item->mincalcd))
4542 it->wd->show_item = it;
4543 it->wd->bring_in = EINA_FALSE;
4544 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE;
4545 it->item->showme = EINA_TRUE;
4548 if (it->wd->show_item)
4550 it->wd->show_item->item->showme = EINA_FALSE;
4551 it->wd->show_item = NULL;
4553 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4554 elm_smart_scroller_child_region_show(it->wd->scr,
4555 it->x + it->item->block->x,
4556 it->y + it->item->block->y - oh / 2 +
4557 it->item->h / 2, it->item->block->w, oh);
4561 elm_genlist_item_middle_bring_in(Elm_Gen_Item *it)
4563 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4566 if (it->generation < it->wd->generation) return;
4567 if ((it->item->queued) || (!it->item->mincalcd))
4569 it->wd->show_item = it;
4570 it->wd->bring_in = EINA_TRUE;
4571 it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE;
4572 it->item->showme = EINA_TRUE;
4575 if (it->wd->show_item)
4577 it->wd->show_item->item->showme = EINA_FALSE;
4578 it->wd->show_item = NULL;
4580 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4581 elm_smart_scroller_region_bring_in(it->wd->scr,
4582 it->x + it->item->block->x,
4583 it->y + it->item->block->y - oh / 2 + it->item->h / 2,
4584 it->item->block->w, oh);
4588 elm_genlist_item_del(Elm_Gen_Item *it)
4590 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4591 if ((it->relcount > 0) || (it->walking > 0))
4593 elm_genlist_item_subitems_clear(it);
4594 if (it->wd->show_item == it) it->wd->show_item = NULL;
4595 _elm_genlist_item_del_notserious(it);
4596 if (it->item->block)
4598 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
4599 it->item->block->changed = EINA_TRUE;
4600 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
4601 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
4605 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
4614 elm_genlist_item_data_set(Elm_Gen_Item *it,
4617 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4618 elm_widget_item_data_set(it, data);
4622 elm_genlist_item_data_get(const Elm_Gen_Item *it)
4624 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4625 return elm_widget_item_data_get(it);
4629 elm_genlist_item_icons_orphan(Elm_Gen_Item *it)
4631 elm_genlist_item_contents_orphan(it);
4635 elm_genlist_item_contents_orphan(Elm_Gen_Item *it)
4637 Evas_Object *content;
4638 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4639 EINA_LIST_FREE(it->content_objs, content)
4641 elm_widget_sub_object_del(WIDGET(it), content);
4642 evas_object_smart_member_del(content);
4643 evas_object_hide(content);
4647 EAPI const Evas_Object *
4648 elm_genlist_item_object_get(const Elm_Gen_Item *it)
4650 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4655 elm_genlist_item_update(Elm_Gen_Item *it)
4657 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4658 if (!it->item->block) return;
4659 if (it->generation < it->wd->generation) return;
4660 it->item->mincalcd = EINA_FALSE;
4661 it->item->updateme = EINA_TRUE;
4662 it->item->block->updateme = EINA_TRUE;
4663 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4664 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4668 elm_genlist_item_fields_update(Elm_Genlist_Item *it,
4670 Elm_Genlist_Item_Field_Flags itf)
4672 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4673 if (!it->item->block) return;
4674 if (it->generation < it->wd->generation) return;
4676 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_LABEL))
4677 _item_text_realize(it, it->base.view, &it->texts, parts);
4678 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
4680 it->content_objs = _item_content_unrealize(it, it->base.view,
4681 &it->contents, parts);
4682 it->content_objs = _item_content_realize(it, it->base.view,
4683 &it->contents, parts);
4685 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
4686 _item_state_realize(it, it->base.view, &it->states, parts);
4690 elm_genlist_item_item_class_update(Elm_Gen_Item *it,
4691 const Elm_Genlist_Item_Class *itc)
4693 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4694 if (!it->item->block) return;
4695 EINA_SAFETY_ON_NULL_RETURN(itc);
4696 if (it->generation < it->wd->generation) return;
4698 it->item->nocache = EINA_TRUE;
4699 elm_genlist_item_update(it);
4702 EAPI const Elm_Genlist_Item_Class *
4703 elm_genlist_item_item_class_get(const Elm_Gen_Item *it)
4705 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4706 if (it->generation < it->wd->generation) return NULL;
4710 static Evas_Object *
4711 _elm_genlist_item_label_create(void *data,
4712 Evas_Object *obj __UNUSED__,
4713 Evas_Object *tooltip,
4714 void *it __UNUSED__)
4716 Evas_Object *label = elm_label_add(tooltip);
4719 elm_object_style_set(label, "tooltip");
4720 elm_object_text_set(label, data);
4725 _elm_genlist_item_label_del_cb(void *data,
4726 Evas_Object *obj __UNUSED__,
4727 void *event_info __UNUSED__)
4729 eina_stringshare_del(data);
4733 elm_genlist_item_tooltip_text_set(Elm_Gen_Item *it,
4736 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4737 text = eina_stringshare_add(text);
4738 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
4740 _elm_genlist_item_label_del_cb);
4744 elm_genlist_item_tooltip_content_cb_set(Elm_Gen_Item *it,
4745 Elm_Tooltip_Item_Content_Cb func,
4747 Evas_Smart_Cb del_cb)
4749 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, error);
4751 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4754 if (it->tooltip.del_cb)
4755 it->tooltip.del_cb((void *)it->tooltip.data,
4758 it->tooltip.content_cb = func;
4759 it->tooltip.data = data;
4760 it->tooltip.del_cb = del_cb;
4764 elm_widget_item_tooltip_content_cb_set(it,
4765 it->tooltip.content_cb,
4766 it->tooltip.data, NULL);
4767 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4768 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
4774 if (del_cb) del_cb((void *)data, NULL, NULL);
4778 elm_genlist_item_tooltip_unset(Elm_Gen_Item *it)
4780 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4781 if ((VIEW(it)) && (it->tooltip.content_cb))
4782 elm_widget_item_tooltip_unset(it);
4784 if (it->tooltip.del_cb)
4785 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4786 it->tooltip.del_cb = NULL;
4787 it->tooltip.content_cb = NULL;
4788 it->tooltip.data = NULL;
4789 it->tooltip.free_size = EINA_FALSE;
4790 if (it->tooltip.style)
4791 elm_genlist_item_tooltip_style_set(it, NULL);
4795 elm_genlist_item_tooltip_style_set(Elm_Gen_Item *it,
4798 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4799 eina_stringshare_replace(&it->tooltip.style, style);
4800 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4804 elm_genlist_item_tooltip_style_get(const Elm_Gen_Item *it)
4806 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4807 return it->tooltip.style;
4811 elm_genlist_item_tooltip_window_mode_set(Elm_Gen_Item *it, Eina_Bool disable)
4813 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4814 it->tooltip.free_size = disable;
4815 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
4820 elm_genlist_item_tooltip_window_mode_get(const Elm_Gen_Item *it)
4822 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4823 return it->tooltip.free_size;
4827 elm_genlist_item_cursor_set(Elm_Gen_Item *it,
4830 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4831 eina_stringshare_replace(&it->mouse_cursor, cursor);
4832 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4836 elm_genlist_item_cursor_get(const Elm_Gen_Item *it)
4838 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4839 return elm_widget_item_cursor_get(it);
4843 elm_genlist_item_cursor_unset(Elm_Gen_Item *it)
4845 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4846 if (!it->mouse_cursor)
4850 elm_widget_item_cursor_unset(it);
4852 eina_stringshare_del(it->mouse_cursor);
4853 it->mouse_cursor = NULL;
4857 elm_genlist_item_cursor_style_set(Elm_Gen_Item *it,
4860 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4861 elm_widget_item_cursor_style_set(it, style);
4865 elm_genlist_item_cursor_style_get(const Elm_Gen_Item *it)
4867 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4868 return elm_widget_item_cursor_style_get(it);
4872 elm_genlist_item_cursor_engine_only_set(Elm_Gen_Item *it,
4873 Eina_Bool engine_only)
4875 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4876 elm_widget_item_cursor_engine_only_set(it, engine_only);
4880 elm_genlist_item_cursor_engine_only_get(const Elm_Gen_Item *it)
4882 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4883 return elm_widget_item_cursor_engine_only_get(it);
4887 elm_genlist_item_index_get(Elm_Gen_Item *it)
4889 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, -1);
4890 if (it->item->block)
4891 return it->position + it->item->block->position;
4896 elm_genlist_horizontal_set(Evas_Object *obj,
4899 ELM_CHECK_WIDTYPE(obj, widtype);
4900 Widget_Data *wd = elm_widget_data_get(obj);
4902 if (wd->mode == mode) return;
4908 elm_genlist_horizontal_mode_set(Evas_Object *obj,
4911 elm_genlist_horizontal_set(obj, mode);
4915 elm_genlist_horizontal_get(const Evas_Object *obj)
4917 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4918 Widget_Data *wd = elm_widget_data_get(obj);
4919 if (!wd) return ELM_LIST_LAST;
4924 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4926 return elm_genlist_horizontal_get(obj);
4930 elm_genlist_always_select_mode_set(Evas_Object *obj,
4931 Eina_Bool always_select)
4933 ELM_CHECK_WIDTYPE(obj, widtype);
4934 Widget_Data *wd = elm_widget_data_get(obj);
4936 wd->always_select = always_select;
4940 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4942 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4943 Widget_Data *wd = elm_widget_data_get(obj);
4944 if (!wd) return EINA_FALSE;
4945 return wd->always_select;
4949 elm_genlist_no_select_mode_set(Evas_Object *obj,
4950 Eina_Bool no_select)
4952 ELM_CHECK_WIDTYPE(obj, widtype);
4953 Widget_Data *wd = elm_widget_data_get(obj);
4955 wd->no_select = no_select;
4959 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4961 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4962 Widget_Data *wd = elm_widget_data_get(obj);
4963 if (!wd) return EINA_FALSE;
4964 return wd->no_select;
4968 elm_genlist_compress_mode_set(Evas_Object *obj,
4971 ELM_CHECK_WIDTYPE(obj, widtype);
4972 Widget_Data *wd = elm_widget_data_get(obj);
4974 wd->compress = compress;
4975 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
4979 elm_genlist_compress_mode_get(const Evas_Object *obj)
4981 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4982 Widget_Data *wd = elm_widget_data_get(obj);
4983 if (!wd) return EINA_FALSE;
4984 return wd->compress;
4988 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
4989 Eina_Bool height_for_width)
4991 ELM_CHECK_WIDTYPE(obj, widtype);
4992 Widget_Data *wd = elm_widget_data_get(obj);
4994 wd->height_for_width = !!height_for_width;
4995 if (wd->height_for_width)
4997 elm_genlist_homogeneous_set(obj, EINA_FALSE);
4998 elm_genlist_compress_mode_set(obj, EINA_TRUE);
5003 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
5005 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5006 Widget_Data *wd = elm_widget_data_get(obj);
5007 if (!wd) return EINA_FALSE;
5008 return wd->height_for_width;
5012 elm_genlist_bounce_set(Evas_Object *obj,
5016 ELM_CHECK_WIDTYPE(obj, widtype);
5017 Widget_Data *wd = elm_widget_data_get(obj);
5019 elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
5020 wd->h_bounce = h_bounce;
5021 wd->v_bounce = v_bounce;
5025 elm_genlist_bounce_get(const Evas_Object *obj,
5026 Eina_Bool *h_bounce,
5027 Eina_Bool *v_bounce)
5029 ELM_CHECK_WIDTYPE(obj, widtype);
5030 Widget_Data *wd = elm_widget_data_get(obj);
5032 if (h_bounce) *h_bounce = wd->h_bounce;
5033 if (v_bounce) *v_bounce = wd->v_bounce;
5037 elm_genlist_homogeneous_set(Evas_Object *obj,
5038 Eina_Bool homogeneous)
5040 ELM_CHECK_WIDTYPE(obj, widtype);
5041 Widget_Data *wd = elm_widget_data_get(obj);
5043 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
5044 wd->homogeneous = homogeneous;
5048 elm_genlist_homogeneous_get(const Evas_Object *obj)
5050 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5051 Widget_Data *wd = elm_widget_data_get(obj);
5052 if (!wd) return EINA_FALSE;
5053 return wd->homogeneous;
5057 elm_genlist_block_count_set(Evas_Object *obj,
5060 ELM_CHECK_WIDTYPE(obj, widtype);
5061 Widget_Data *wd = elm_widget_data_get(obj);
5063 wd->max_items_per_block = n;
5064 wd->item_cache_max = wd->max_items_per_block * 2;
5065 _item_cache_clean(wd);
5069 elm_genlist_block_count_get(const Evas_Object *obj)
5071 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5072 Widget_Data *wd = elm_widget_data_get(obj);
5074 return wd->max_items_per_block;
5078 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5081 ELM_CHECK_WIDTYPE(obj, widtype);
5082 Widget_Data *wd = elm_widget_data_get(obj);
5084 wd->longpress_timeout = timeout;
5088 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5090 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5091 Widget_Data *wd = elm_widget_data_get(obj);
5093 return wd->longpress_timeout;
5097 elm_genlist_scroller_policy_set(Evas_Object *obj,
5098 Elm_Scroller_Policy policy_h,
5099 Elm_Scroller_Policy policy_v)
5101 ELM_CHECK_WIDTYPE(obj, widtype);
5102 Widget_Data *wd = elm_widget_data_get(obj);
5103 if ((!wd) || (!wd->scr)) return;
5104 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5105 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5107 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5111 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5112 Elm_Scroller_Policy *policy_h,
5113 Elm_Scroller_Policy *policy_v)
5115 ELM_CHECK_WIDTYPE(obj, widtype);
5116 Widget_Data *wd = elm_widget_data_get(obj);
5117 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5118 if ((!wd) || (!wd->scr)) return;
5119 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5120 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5121 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5125 elm_genlist_realized_items_update(Evas_Object *obj)
5127 ELM_CHECK_WIDTYPE(obj, widtype);
5129 Eina_List *list, *l;
5132 list = elm_genlist_realized_items_get(obj);
5133 EINA_LIST_FOREACH(list, l, it)
5134 elm_genlist_item_update(it);
5138 elm_genlist_item_mode_set(Elm_Gen_Item *it,
5139 const char *mode_type,
5142 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
5143 Widget_Data *wd = it->wd;
5148 if (!mode_type) return;
5149 if ((it->generation < it->wd->generation) || (it->disabled)) return;
5151 if ((wd->mode_item == it) &&
5152 (!strcmp(mode_type, wd->mode_type)) &&
5155 if (!wd->mode_item_style) return;
5156 it->mode_set = mode_set;
5160 EINA_LIST_FOREACH(wd->selected, l, it2)
5162 elm_genlist_item_selected_set(it2, EINA_FALSE);
5166 it2 = elm_genlist_selected_item_get(wd->obj);
5167 if ((it2) && (it2->realized))
5168 elm_genlist_item_selected_set(it2, EINA_FALSE);
5171 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
5173 ((it == wd->mode_item) && (!mode_set)))
5174 _item_mode_unset(wd);
5176 eina_stringshare_replace(&wd->mode_type, mode_type);
5177 if (mode_set) _item_mode_set(it);
5182 elm_genlist_mode_item_style_get(const Evas_Object *obj)
5184 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5185 Widget_Data *wd = elm_widget_data_get(obj);
5186 if (!wd) return NULL;
5187 return wd->mode_item_style;
5191 elm_genlist_mode_item_style_set(Evas_Object *obj, const char *style)
5193 ELM_CHECK_WIDTYPE(obj, widtype);
5194 Widget_Data *wd = elm_widget_data_get(obj);
5196 if ((style == wd->mode_item_style) || (style && wd->mode_item_style &&
5197 (!strcmp(style, wd->mode_item_style))))
5199 eina_stringshare_replace(&wd->mode_item_style, style);
5200 elm_genlist_realized_items_update(obj);
5204 elm_genlist_mode_get(const Evas_Object *obj)
5206 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5207 Widget_Data *wd = elm_widget_data_get(obj);
5208 if (!wd) return NULL;
5209 return wd->mode_type;
5212 EAPI const Elm_Gen_Item *
5213 elm_genlist_mode_item_get(const Evas_Object *obj)
5215 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5216 Widget_Data *wd = elm_widget_data_get(obj);
5217 if (!wd) return NULL;
5218 return wd->mode_item;
5222 elm_genlist_reorder_mode_set(Evas_Object *obj,
5223 Eina_Bool reorder_mode)
5225 ELM_CHECK_WIDTYPE(obj, widtype);
5226 Widget_Data *wd = elm_widget_data_get(obj);
5228 wd->reorder_mode = reorder_mode;
5232 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5234 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5235 Widget_Data *wd = elm_widget_data_get(obj);
5236 if (!wd) return EINA_FALSE;
5237 return wd->reorder_mode;
5240 /* for gengrid as of now */
5242 _elm_genlist_page_relative_set(Evas_Object *obj,
5246 Evas_Coord pagesize_h;
5247 Evas_Coord pagesize_v;
5249 ELM_CHECK_WIDTYPE(obj, widtype);
5250 Widget_Data *wd = elm_widget_data_get(obj);
5253 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5254 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5258 /* for gengrid as of now */
5260 _elm_genlist_page_relative_get(const Evas_Object *obj,
5264 ELM_CHECK_WIDTYPE(obj, widtype);
5265 Widget_Data *wd = elm_widget_data_get(obj);
5268 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5271 /* for gengrid as of now */
5273 _elm_genlist_page_size_set(Evas_Object *obj,
5274 Evas_Coord h_pagesize,
5275 Evas_Coord v_pagesize)
5280 ELM_CHECK_WIDTYPE(obj, widtype);
5281 Widget_Data *wd = elm_widget_data_get(obj);
5283 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5284 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5288 /* for gengrid as of now */
5290 _elm_genlist_current_page_get(const Evas_Object *obj,
5294 ELM_CHECK_WIDTYPE(obj, widtype);
5295 Widget_Data *wd = elm_widget_data_get(obj);
5298 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5301 /* for gengrid as of now */
5303 _elm_genlist_last_page_get(const Evas_Object *obj,
5307 ELM_CHECK_WIDTYPE(obj, widtype);
5308 Widget_Data *wd = elm_widget_data_get(obj);
5311 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5314 /* for gengrid as of now */
5316 _elm_genlist_page_show(const Evas_Object *obj,
5320 ELM_CHECK_WIDTYPE(obj, widtype);
5321 Widget_Data *wd = elm_widget_data_get(obj);
5324 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5327 /* for gengrid as of now */
5329 _elm_genlist_page_bring_in(const Evas_Object *obj,
5333 ELM_CHECK_WIDTYPE(obj, widtype);
5334 Widget_Data *wd = elm_widget_data_get(obj);
5337 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5341 _elm_genlist_item_widget_get(const Elm_Gen_Item *it)
5343 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
5348 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5351 Evas_Object *content;
5353 if (!it->realized) return;
5354 if (it->wd->reorder_it == it) return;
5355 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5357 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5360 ecore_timer_del(it->long_timer);
5361 it->long_timer = NULL;
5364 elm_widget_stringlist_free(it->texts);
5366 elm_widget_stringlist_free(it->contents);
5367 it->contents = NULL;
5368 elm_widget_stringlist_free(it->states);
5371 EINA_LIST_FREE(it->content_objs, content)
5372 evas_object_del(content);
5374 it->unrealize_cb(it);
5376 it->realized = EINA_FALSE;
5377 it->want_unrealize = EINA_FALSE;
5378 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5379 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5383 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5385 elm_widget_item_pre_notify_del(it);
5386 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5387 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5389 if (it->itc->func.del)
5390 it->itc->func.del((void *)it->base.data, WIDGET(it));
5394 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5396 _elm_genlist_item_del_notserious(it);
5397 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5398 if (it->tooltip.del_cb)
5399 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5400 it->wd->walking -= it->walking;
5401 if (it->long_timer) ecore_timer_del(it->long_timer);
5403 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5405 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5406 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5409 elm_widget_item_del(it);