3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_genlist.h"
9 #define MAX_ITEMS_PER_BLOCK 32
10 #define REORDER_EFFECT_TIME 0.5
12 #define ELM_GEN_SETUP(wd) \
13 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
14 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
15 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
17 #define ELM_GEN_ITEM_SETUP(it) \
18 (it)->del_cb = (Ecore_Cb)_item_del; \
19 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
20 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
21 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
22 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
24 typedef struct _Item_Block Item_Block;
25 typedef struct _Item_Cache Item_Cache;
27 struct Elm_Gen_Item_Type
32 Evas_Coord w, h, minw, minh;
33 Elm_Gen_Item *group_item;
34 Elm_Genlist_Item_Flags flags;
35 Eina_List *mode_labels, *mode_contents, *mode_states, *mode_content_objs;
36 Ecore_Timer *swipe_timer;
37 Evas_Coord scrl_x, scrl_y, old_scrl_y;
40 Evas_Object *mode_view;
46 Eina_Bool want_realize : 1;
47 Eina_Bool expanded : 1;
48 Eina_Bool mincalcd : 1;
51 Eina_Bool updateme : 1;
52 Eina_Bool nocache : 1;
53 Eina_Bool stacking_even : 1;
54 Eina_Bool nostacking : 1;
55 Eina_Bool move_effect_enabled : 1;
66 Evas_Coord x, y, w, h, minw, minh;
67 Eina_Bool want_unrealize : 1;
68 Eina_Bool realized : 1;
69 Eina_Bool changed : 1;
70 Eina_Bool updateme : 1;
72 Eina_Bool must_recalc : 1;
79 Evas_Object *base_view, *spacer;
81 const char *item_style; // it->itc->item_style
82 Eina_Bool tree : 1; // it->group
83 Eina_Bool compress : 1; // it->wd->compress
85 Eina_Bool selected : 1; // it->selected
86 Eina_Bool disabled : 1; // it->disabled
87 Eina_Bool expanded : 1; // it->item->expanded
90 static const char *widtype = NULL;
91 static void _item_cache_zero(Widget_Data *wd);
92 static void _del_hook(Evas_Object *obj);
93 static void _mirrored_set(Evas_Object *obj,
95 static void _theme_hook(Evas_Object *obj);
96 static void _show_region_hook(void *data,
98 static void _sizing_eval(Evas_Object *obj);
99 static void _item_realize(Elm_Gen_Item *it,
102 static void _item_unrealize_cb(Elm_Gen_Item *it);
103 static void _item_block_unrealize(Item_Block *itb);
104 static void _calc_job(void *data);
105 static void _on_focus_hook(void *data,
107 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
108 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
109 static Eina_Bool _item_single_select_up(Widget_Data *wd);
110 static Eina_Bool _item_single_select_down(Widget_Data *wd);
111 static Eina_Bool _event_hook(Evas_Object *obj,
113 Evas_Callback_Type type,
115 static void _signal_emit_hook(Evas_Object *obj,
116 const char *emission,
118 static Eina_Bool _deselect_all_items(Widget_Data *wd);
119 static void _pan_calculate(Evas_Object *obj);
120 static void _pan_max_get(Evas_Object *obj,
123 static void _item_position(Elm_Gen_Item *it,
127 static void _mode_item_realize(Elm_Gen_Item *it);
128 static void _mode_item_unrealize(Elm_Gen_Item *it);
129 static void _item_mode_set(Elm_Gen_Item *it);
130 static void _item_mode_unset(Widget_Data *wd);
131 static void _group_items_recalc(void *data);
132 static void _item_move_after(Elm_Gen_Item *it,
133 Elm_Gen_Item *after);
134 static void _item_move_before(Elm_Gen_Item *it,
135 Elm_Gen_Item *before);
136 static void _item_auto_scroll(Widget_Data *wd);
137 static void _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby);
139 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
141 static const char SIG_ACTIVATED[] = "activated";
142 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
143 static const char SIG_SELECTED[] = "selected";
144 static const char SIG_UNSELECTED[] = "unselected";
145 static const char SIG_EXPANDED[] = "expanded";
146 static const char SIG_CONTRACTED[] = "contracted";
147 static const char SIG_EXPAND_REQUEST[] = "expand,request";
148 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
149 static const char SIG_REALIZED[] = "realized";
150 static const char SIG_UNREALIZED[] = "unrealized";
151 static const char SIG_DRAG_START_UP[] = "drag,start,up";
152 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
153 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
154 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
155 static const char SIG_DRAG_STOP[] = "drag,stop";
156 static const char SIG_DRAG[] = "drag";
157 static const char SIG_LONGPRESSED[] = "longpressed";
158 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
159 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
160 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
161 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
162 static const char SIG_EDGE_TOP[] = "edge,top";
163 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
164 static const char SIG_EDGE_LEFT[] = "edge,left";
165 static const char SIG_EDGE_RIGHT[] = "edge,right";
166 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
167 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
168 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
169 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
170 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
171 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
172 static const char SIG_SWIPE[] = "swipe";
173 static const char SIG_MOVED[] = "moved";
175 static const Evas_Smart_Cb_Description _signals[] = {
176 {SIG_CLICKED_DOUBLE, ""},
179 {SIG_UNSELECTED, ""},
181 {SIG_CONTRACTED, ""},
182 {SIG_EXPAND_REQUEST, ""},
183 {SIG_CONTRACT_REQUEST, ""},
185 {SIG_UNREALIZED, ""},
186 {SIG_DRAG_START_UP, ""},
187 {SIG_DRAG_START_DOWN, ""},
188 {SIG_DRAG_START_LEFT, ""},
189 {SIG_DRAG_START_RIGHT, ""},
192 {SIG_LONGPRESSED, ""},
193 {SIG_SCROLL_ANIM_START, ""},
194 {SIG_SCROLL_ANIM_STOP, ""},
195 {SIG_SCROLL_DRAG_START, ""},
196 {SIG_SCROLL_DRAG_STOP, ""},
198 {SIG_EDGE_BOTTOM, ""},
200 {SIG_EDGE_RIGHT, ""},
201 {SIG_MULTI_SWIPE_LEFT, ""},
202 {SIG_MULTI_SWIPE_RIGHT, ""},
203 {SIG_MULTI_SWIPE_UP, ""},
204 {SIG_MULTI_SWIPE_DOWN, ""},
205 {SIG_MULTI_PINCH_OUT, ""},
206 {SIG_MULTI_PINCH_IN, ""},
213 #undef ELM_CHECK_WIDTYPE
214 #define ELM_CHECK_WIDTYPE(obj, widtype) \
215 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
216 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
217 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
218 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
219 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
221 static const char *_gengrid = NULL;
222 static const char *_genlist = NULL;
224 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
226 elm_genlist_type_check(const Evas_Object *obj,
229 const char *provided, *expected = "(unknown)";
230 static int abort_on_warn = -1;
231 provided = elm_widget_type_get(obj);
232 if (!_genlist) _genlist = eina_stringshare_add("genlist");
233 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
234 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
236 if ((!provided) || (!provided[0]))
238 provided = evas_object_type_get(obj);
239 if ((!provided) || (!provided[0]))
240 provided = "(unknown)";
242 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
243 if (abort_on_warn == -1)
245 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
246 else abort_on_warn = 0;
248 if (abort_on_warn == 1) abort();
253 _event_hook(Evas_Object *obj,
254 Evas_Object *src __UNUSED__,
255 Evas_Callback_Type type,
258 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
259 Evas_Event_Key_Down *ev = event_info;
260 Widget_Data *wd = elm_widget_data_get(obj);
261 Evas_Coord pan_max_x = 0, pan_max_y = 0;
262 if (!wd) return EINA_FALSE;
263 if (!wd->items) return EINA_FALSE;
264 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
265 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
267 Elm_Gen_Item *it = NULL;
270 Evas_Coord step_x = 0;
271 Evas_Coord step_y = 0;
274 Evas_Coord page_x = 0;
275 Evas_Coord page_y = 0;
277 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
278 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
279 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
280 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
282 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
286 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
290 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
292 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
293 (_item_multi_select_up(wd)))
294 || (_item_single_select_up(wd)))
296 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
302 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
304 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
305 (_item_multi_select_down(wd)))
306 || (_item_single_select_down(wd)))
308 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
314 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
316 it = elm_genlist_first_item_get(obj);
317 elm_genlist_item_bring_in(it);
318 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
321 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
323 it = elm_genlist_last_item_get(obj);
324 elm_genlist_item_bring_in(it);
325 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
328 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
331 y -= -(page_y * v_h) / 100;
335 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
338 y += -(page_y * v_h) / 100;
342 else if (!strcmp(ev->keyname, "Escape"))
344 if (!_deselect_all_items(wd)) return EINA_FALSE;
345 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
348 else if (((!strcmp(ev->keyname, "Return")) ||
349 (!strcmp(ev->keyname, "KP_Enter")) ||
350 (!strcmp(ev->keyname, "space")))
351 && (!wd->multi) && (wd->selected))
353 it = elm_genlist_selected_item_get(obj);
354 elm_genlist_item_expanded_set(it,
355 !elm_genlist_item_expanded_get(it));
356 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
358 else return EINA_FALSE;
360 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
361 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
363 if (x > pan_max_x) x = pan_max_x;
365 if (y > pan_max_y) y = pan_max_y;
366 elm_smart_scroller_child_pos_set(wd->scr, x, y);
371 _deselect_all_items(Widget_Data *wd)
373 if (!wd->selected) return EINA_FALSE;
375 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
381 _item_multi_select_up(Widget_Data *wd)
383 if (!wd->selected) return EINA_FALSE;
384 if (!wd->multi) return EINA_FALSE;
386 Elm_Gen_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
387 if (!prev) return EINA_TRUE;
389 if (elm_genlist_item_selected_get(prev))
391 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
392 wd->last_selected_item = prev;
393 elm_genlist_item_show(wd->last_selected_item);
397 elm_genlist_item_selected_set(prev, EINA_TRUE);
398 elm_genlist_item_show(prev);
404 _item_multi_select_down(Widget_Data *wd)
406 if (!wd->selected) return EINA_FALSE;
407 if (!wd->multi) return EINA_FALSE;
409 Elm_Gen_Item *next = elm_genlist_item_next_get(wd->last_selected_item);
410 if (!next) return EINA_TRUE;
412 if (elm_genlist_item_selected_get(next))
414 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
415 wd->last_selected_item = next;
416 elm_genlist_item_show(wd->last_selected_item);
420 elm_genlist_item_selected_set(next, EINA_TRUE);
421 elm_genlist_item_show(next);
427 _item_single_select_up(Widget_Data *wd)
432 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
433 while ((prev) && (prev->generation < wd->generation))
434 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
436 else prev = elm_genlist_item_prev_get(wd->last_selected_item);
438 if (!prev) return EINA_FALSE;
440 _deselect_all_items(wd);
442 elm_genlist_item_selected_set(prev, EINA_TRUE);
443 elm_genlist_item_show(prev);
448 _item_single_select_down(Widget_Data *wd)
453 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
454 while ((next) && (next->generation < wd->generation))
455 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
457 else next = elm_genlist_item_next_get(wd->last_selected_item);
459 if (!next) return EINA_FALSE;
461 _deselect_all_items(wd);
463 elm_genlist_item_selected_set(next, EINA_TRUE);
464 elm_genlist_item_show(next);
469 _on_focus_hook(void *data __UNUSED__,
472 Widget_Data *wd = elm_widget_data_get(obj);
474 if (elm_widget_focus_get(obj))
476 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
477 evas_object_focus_set(wd->obj, EINA_TRUE);
478 if ((wd->selected) && (!wd->last_selected_item))
479 wd->last_selected_item = eina_list_data_get(wd->selected);
483 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
484 evas_object_focus_set(wd->obj, EINA_FALSE);
489 _del_hook(Evas_Object *obj)
491 Widget_Data *wd = elm_widget_data_get(obj);
493 _item_cache_zero(wd);
494 if (wd->calc_job) ecore_job_del(wd->calc_job);
495 if (wd->update_job) ecore_job_del(wd->update_job);
496 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
497 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
498 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
499 if (wd->mode_type) eina_stringshare_del(wd->mode_type);
500 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
505 _del_pre_hook(Evas_Object *obj)
507 Widget_Data *wd = elm_widget_data_get(obj);
509 elm_genlist_clear(obj);
510 evas_object_del(wd->pan_smart);
511 wd->pan_smart = NULL;
515 _mirrored_set(Evas_Object *obj,
518 Widget_Data *wd = elm_widget_data_get(obj);
520 _item_cache_zero(wd);
521 elm_smart_scroller_mirrored_set(wd->scr, rtl);
525 _theme_hook(Evas_Object *obj)
527 Widget_Data *wd = elm_widget_data_get(obj);
530 evas_event_freeze(evas_object_evas_get(wd->obj));
531 _item_cache_zero(wd);
532 _elm_widget_mirrored_reload(obj);
533 _mirrored_set(obj, elm_widget_mirrored_get(obj));
534 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
535 elm_widget_style_get(obj));
536 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
537 wd->item_width = wd->item_height = 0;
538 wd->group_item_width = wd->group_item_height = 0;
539 wd->minw = wd->minh = wd->realminw = 0;
540 EINA_INLIST_FOREACH(wd->blocks, itb)
545 if (itb->realized) _item_block_unrealize(itb);
546 EINA_LIST_FOREACH(itb->items, l, it)
547 it->item->mincalcd = EINA_FALSE;
549 itb->changed = EINA_TRUE;
551 if (wd->calc_job) ecore_job_del(wd->calc_job);
552 wd->calc_job = ecore_job_add(_calc_job, wd);
554 evas_event_thaw(evas_object_evas_get(wd->obj));
555 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
559 _show_region_hook(void *data,
562 Widget_Data *wd = elm_widget_data_get(data);
563 Evas_Coord x, y, w, h;
565 elm_widget_show_region_get(obj, &x, &y, &w, &h);
566 //x & y are screen coordinates, Add with pan coordinates
569 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
573 _translate_hook(Evas_Object *obj)
575 evas_object_smart_callback_call(obj, "language,changed", NULL);
579 _sizing_eval(Evas_Object *obj)
581 Widget_Data *wd = elm_widget_data_get(obj);
582 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
584 evas_object_size_hint_min_get(wd->scr, &minw, &minh);
585 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
587 if (wd->height_for_width)
591 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
592 if ((vw != 0) && (vw != wd->prev_viewport_w))
596 wd->prev_viewport_w = vw;
597 EINA_INLIST_FOREACH(wd->blocks, itb)
599 itb->must_recalc = EINA_TRUE;
601 if (wd->calc_job) ecore_job_del(wd->calc_job);
602 wd->calc_job = ecore_job_add(_calc_job, wd);
605 if (wd->mode == ELM_LIST_LIMIT)
611 edje_object_size_min_calc
612 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
619 edje_object_size_min_calc
620 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
624 evas_object_size_hint_min_set(obj, minw, minh);
625 evas_object_size_hint_max_set(obj, maxw, maxh);
629 _signal_emit_hook(Evas_Object *obj,
630 const char *emission,
633 Widget_Data *wd = elm_widget_data_get(obj);
634 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
639 _item_highlight(Elm_Gen_Item *it)
641 const char *selectraise;
642 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->highlighted) ||
643 (it->disabled) || (it->display_only) || (it->item->mode_view))
645 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
646 selectraise = edje_object_data_get(VIEW(it), "selectraise");
647 if ((selectraise) && (!strcmp(selectraise, "on")))
649 evas_object_raise(VIEW(it));
650 if ((it->item->group_item) && (it->item->group_item->realized))
651 evas_object_raise(it->item->VIEW(group_item));
653 it->highlighted = EINA_TRUE;
657 _item_unhighlight(Elm_Gen_Item *it)
659 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
660 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
661 if (!it->item->nostacking)
663 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even) evas_object_lower(VIEW(it));
664 else evas_object_raise(VIEW(it));
666 it->highlighted = EINA_FALSE;
670 _item_block_del(Elm_Gen_Item *it)
673 Item_Block *itb = it->item->block;
675 itb->items = eina_list_remove(itb->items, it);
677 itb->changed = EINA_TRUE;
678 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
679 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
682 il = EINA_INLIST_GET(itb);
683 Item_Block *itbn = (Item_Block *)(il->next);
685 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
687 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
689 if (itbn) itbn->changed = EINA_TRUE;
693 if (itb->count < itb->wd->max_items_per_block/2)
695 il = EINA_INLIST_GET(itb);
696 Item_Block *itbp = (Item_Block *)(il->prev);
697 Item_Block *itbn = (Item_Block *)(il->next);
698 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
702 EINA_LIST_FREE(itb->items, it2)
704 it2->item->block = itbp;
705 itbp->items = eina_list_append(itbp->items, it2);
707 itbp->changed = EINA_TRUE;
709 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
710 EINA_INLIST_GET(itb));
713 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
717 Eina_List *last = eina_list_last(itb->items);
718 Elm_Gen_Item *it2 = last->data;
720 it2->item->block = itbn;
721 itb->items = eina_list_remove_list(itb->items, last);
722 itbn->items = eina_list_prepend(itbn->items, it2);
724 itbn->changed = EINA_TRUE;
727 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
735 _item_del(Elm_Gen_Item *it)
737 Evas_Object *obj = WIDGET(it);
739 evas_event_freeze(evas_object_evas_get(obj));
740 elm_genlist_item_subitems_clear(it);
741 if (it->wd->show_item == it) it->wd->show_item = NULL;
742 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
743 if (it->item->block) _item_block_del(it);
744 if (it->item->queued)
745 it->wd->queue = eina_list_remove(it->wd->queue, it);
746 if (it->wd->anchor_item == it)
748 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
749 if (!it->wd->anchor_item)
750 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
753 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
754 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
755 _elm_genlist_item_del_serious(it);
756 evas_event_thaw(evas_object_evas_get(obj));
757 evas_event_thaw_eval(evas_object_evas_get(obj));
761 _clear_cb(Widget_Data *wd)
763 wd->anchor_item = NULL;
766 Item_Block *itb = (Item_Block *)(wd->blocks);
768 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
769 if (itb->items) eina_list_free(itb->items);
772 if (wd->queue_idle_enterer)
774 ecore_idle_enterer_del(wd->queue_idle_enterer);
775 wd->queue_idle_enterer = NULL;
777 if (wd->must_recalc_idler)
779 ecore_idler_del(wd->must_recalc_idler);
780 wd->must_recalc_idler = NULL;
782 if (wd->queue) wd->queue = eina_list_free(wd->queue);
783 if (wd->reorder_move_animator)
785 ecore_animator_del(wd->reorder_move_animator);
786 wd->reorder_move_animator = NULL;
788 wd->show_item = NULL;
789 wd->reorder_old_pan_y = 0;
793 _item_unselect(Elm_Gen_Item *it)
795 if ((it->generation < it->wd->generation) || (!it->selected)) return;
796 it->selected = EINA_FALSE;
797 it->wd->selected = eina_list_remove(it->wd->selected, it);
798 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
802 _mouse_move(void *data,
803 Evas *evas __UNUSED__,
807 Elm_Gen_Item *it = data;
808 Evas_Event_Mouse_Move *ev = event_info;
809 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
810 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
812 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
814 if (!it->wd->on_hold)
816 it->wd->on_hold = EINA_TRUE;
817 if (!it->wd->wasselected)
819 _item_unhighlight(it);
824 if (it->wd->multitouched)
826 it->wd->cur_x = ev->cur.canvas.x;
827 it->wd->cur_y = ev->cur.canvas.y;
830 if ((it->dragging) && (it->down))
832 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
835 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
836 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
837 if (abs((it->wd->history[it->wd->movements].x -
838 it->wd->history[0].x)) > 40)
839 it->wd->swipe = EINA_TRUE;
845 ecore_timer_del(it->long_timer);
846 it->long_timer = NULL;
848 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
851 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
855 ecore_timer_del(it->long_timer);
856 it->long_timer = NULL;
858 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
860 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
861 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
863 if (!it->wd->reorder_start_y)
864 it->wd->reorder_start_y = it->item->block->y + it->y;
868 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
869 y_pos = oy + oh - it->wd->reorder_it->item->h;
873 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
875 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
876 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
880 if (!it->display_only)
881 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
882 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
883 x = ev->cur.canvas.x - x;
884 y = ev->cur.canvas.y - y;
887 if (adx < 0) adx = -dx;
890 if (ady < 0) ady = -dy;
893 if ((adx > minw) || (ady > minh))
895 it->dragging = EINA_TRUE;
898 ecore_timer_del(it->long_timer);
899 it->long_timer = NULL;
901 if (!it->wd->wasselected)
903 _item_unhighlight(it);
909 evas_object_smart_callback_call(WIDGET(it),
910 SIG_DRAG_START_UP, it);
914 evas_object_smart_callback_call(WIDGET(it),
915 SIG_DRAG_START_LEFT, it);
917 evas_object_smart_callback_call(WIDGET(it),
918 SIG_DRAG_START_RIGHT, it);
924 evas_object_smart_callback_call(WIDGET(it),
925 SIG_DRAG_START_DOWN, it);
929 evas_object_smart_callback_call(WIDGET(it),
930 SIG_DRAG_START_LEFT, it);
932 evas_object_smart_callback_call(WIDGET(it),
933 SIG_DRAG_START_RIGHT, it);
940 _long_press(void *data)
942 Elm_Gen_Item *it = data, *it_tmp;
945 it->long_timer = NULL;
946 if ((it->disabled) || (it->dragging) || (it->display_only))
947 return ECORE_CALLBACK_CANCEL;
948 it->wd->longpressed = EINA_TRUE;
949 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
950 if ((it->wd->reorder_mode) && (!it->group))
952 it->wd->reorder_it = it;
953 it->wd->reorder_start_y = 0;
955 evas_object_raise(VIEW(it));
956 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
957 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
959 list = elm_genlist_realized_items_get(it->wd->obj);
960 EINA_LIST_FOREACH(list, l, it_tmp)
962 if (it != it_tmp) _item_unselect(it_tmp);
964 if (elm_genlist_item_expanded_get(it))
966 elm_genlist_item_expanded_set(it, EINA_FALSE);
967 return ECORE_CALLBACK_RENEW;
969 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
971 return ECORE_CALLBACK_CANCEL;
975 _swipe(Elm_Gen_Item *it)
980 if ((it->display_only) || (it->disabled)) return;
981 it->wd->swipe = EINA_FALSE;
982 for (i = 0; i < it->wd->movements; i++)
984 sum += it->wd->history[i].x;
985 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
988 sum /= it->wd->movements;
989 if (abs(sum - it->wd->history[0].x) <= 10) return;
990 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
994 _swipe_cancel(void *data)
996 Elm_Gen_Item *it = data;
998 if (!it) return ECORE_CALLBACK_CANCEL;
999 it->wd->swipe = EINA_FALSE;
1000 it->wd->movements = 0;
1001 return ECORE_CALLBACK_RENEW;
1005 _multi_cancel(void *data)
1007 Widget_Data *wd = data;
1009 if (!wd) return ECORE_CALLBACK_CANCEL;
1010 wd->multi_timeout = EINA_TRUE;
1011 return ECORE_CALLBACK_RENEW;
1015 _multi_touch_gesture_eval(void *data)
1017 Elm_Gen_Item *it = data;
1019 it->wd->multitouched = EINA_FALSE;
1020 if (it->wd->multi_timer)
1022 ecore_timer_del(it->wd->multi_timer);
1023 it->wd->multi_timer = NULL;
1025 if (it->wd->multi_timeout)
1027 it->wd->multi_timeout = EINA_FALSE;
1031 Evas_Coord minw = 0, minh = 0;
1032 Evas_Coord off_x, off_y, off_mx, off_my;
1034 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1035 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1036 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1037 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1038 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1040 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1042 if ((off_x + off_mx) > (off_y + off_my))
1044 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1045 evas_object_smart_callback_call(WIDGET(it),
1046 SIG_MULTI_SWIPE_RIGHT, it);
1047 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1048 evas_object_smart_callback_call(WIDGET(it),
1049 SIG_MULTI_SWIPE_LEFT, it);
1050 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1051 evas_object_smart_callback_call(WIDGET(it),
1052 SIG_MULTI_PINCH_OUT, it);
1054 evas_object_smart_callback_call(WIDGET(it),
1055 SIG_MULTI_PINCH_IN, it);
1059 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1060 evas_object_smart_callback_call(WIDGET(it),
1061 SIG_MULTI_SWIPE_DOWN, it);
1062 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1063 evas_object_smart_callback_call(WIDGET(it),
1064 SIG_MULTI_SWIPE_UP, it);
1065 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1066 evas_object_smart_callback_call(WIDGET(it),
1067 SIG_MULTI_PINCH_OUT, it);
1069 evas_object_smart_callback_call(WIDGET(it),
1070 SIG_MULTI_PINCH_IN, it);
1073 it->wd->multi_timeout = EINA_FALSE;
1077 _multi_down(void *data,
1078 Evas *evas __UNUSED__,
1079 Evas_Object *obj __UNUSED__,
1082 Elm_Gen_Item *it = data;
1083 Evas_Event_Multi_Down *ev = event_info;
1085 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1086 it->wd->multi_device = ev->device;
1087 it->wd->multi_down = EINA_TRUE;
1088 it->wd->multitouched = EINA_TRUE;
1089 it->wd->prev_mx = ev->canvas.x;
1090 it->wd->prev_my = ev->canvas.y;
1091 if (!it->wd->wasselected)
1093 _item_unhighlight(it);
1096 it->wd->wasselected = EINA_FALSE;
1097 it->wd->longpressed = EINA_FALSE;
1100 ecore_timer_del(it->long_timer);
1101 it->long_timer = NULL;
1105 it->dragging = EINA_FALSE;
1106 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1108 if (it->item->swipe_timer)
1110 ecore_timer_del(it->item->swipe_timer);
1111 it->item->swipe_timer = NULL;
1113 if (it->wd->on_hold)
1115 it->wd->swipe = EINA_FALSE;
1116 it->wd->movements = 0;
1117 it->wd->on_hold = EINA_FALSE;
1122 _multi_up(void *data,
1123 Evas *evas __UNUSED__,
1124 Evas_Object *obj __UNUSED__,
1127 Elm_Gen_Item *it = data;
1128 Evas_Event_Multi_Up *ev = event_info;
1130 if (it->wd->multi_device != ev->device) return;
1131 it->wd->multi_device = 0;
1132 it->wd->multi_down = EINA_FALSE;
1133 if (it->wd->mouse_down) return;
1134 _multi_touch_gesture_eval(data);
1138 _multi_move(void *data,
1139 Evas *evas __UNUSED__,
1140 Evas_Object *obj __UNUSED__,
1143 Elm_Gen_Item *it = data;
1144 Evas_Event_Multi_Move *ev = event_info;
1146 if (it->wd->multi_device != ev->device) return;
1147 it->wd->cur_mx = ev->cur.canvas.x;
1148 it->wd->cur_my = ev->cur.canvas.y;
1152 _mouse_down(void *data,
1153 Evas *evas __UNUSED__,
1157 Elm_Gen_Item *it = data;
1158 Evas_Event_Mouse_Down *ev = event_info;
1161 if (ev->button != 1) return;
1162 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1164 it->wd->on_hold = EINA_TRUE;
1167 it->down = EINA_TRUE;
1168 it->dragging = EINA_FALSE;
1169 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1170 it->dx = ev->canvas.x - x;
1171 it->dy = ev->canvas.y - y;
1172 it->wd->mouse_down = EINA_TRUE;
1173 if (!it->wd->multitouched)
1175 it->wd->prev_x = ev->canvas.x;
1176 it->wd->prev_y = ev->canvas.y;
1177 it->wd->multi_timeout = EINA_FALSE;
1178 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1179 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1181 it->wd->longpressed = EINA_FALSE;
1182 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1183 else it->wd->on_hold = EINA_FALSE;
1184 if (it->wd->on_hold) return;
1185 it->wd->wasselected = it->selected;
1186 _item_highlight(it);
1187 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1188 if ((!it->disabled) && (!it->display_only))
1190 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1191 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1193 if (it->long_timer) ecore_timer_del(it->long_timer);
1194 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1195 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1197 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1200 it->long_timer = NULL;
1201 it->wd->swipe = EINA_FALSE;
1202 it->wd->movements = 0;
1206 _mouse_up(void *data,
1207 Evas *evas __UNUSED__,
1208 Evas_Object *obj __UNUSED__,
1211 Elm_Gen_Item *it = data;
1212 Evas_Event_Mouse_Up *ev = event_info;
1213 Eina_Bool dragged = EINA_FALSE;
1215 if (ev->button != 1) return;
1216 it->down = EINA_FALSE;
1217 it->wd->mouse_down = EINA_FALSE;
1218 if (it->wd->multitouched)
1220 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1221 if (it->wd->multi_down) return;
1222 _multi_touch_gesture_eval(data);
1225 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1226 else it->wd->on_hold = EINA_FALSE;
1229 ecore_timer_del(it->long_timer);
1230 it->long_timer = NULL;
1234 it->dragging = EINA_FALSE;
1235 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1238 if (it->item->swipe_timer)
1240 ecore_timer_del(it->item->swipe_timer);
1241 it->item->swipe_timer = NULL;
1243 if (it->wd->multi_timer)
1245 ecore_timer_del(it->wd->multi_timer);
1246 it->wd->multi_timer = NULL;
1247 it->wd->multi_timeout = EINA_FALSE;
1249 if (it->wd->on_hold)
1251 if (it->wd->swipe) _swipe(data);
1252 it->wd->longpressed = EINA_FALSE;
1253 it->wd->on_hold = EINA_FALSE;
1256 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1258 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1260 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1262 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1263 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1265 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1269 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1270 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1272 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1273 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1274 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1275 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1277 if (it->wd->longpressed)
1279 it->wd->longpressed = EINA_FALSE;
1280 if (!it->wd->wasselected)
1282 _item_unhighlight(it);
1285 it->wd->wasselected = EINA_FALSE;
1290 if (it->want_unrealize)
1292 _elm_genlist_item_unrealize(it, EINA_FALSE);
1293 if (it->item->block->want_unrealize)
1294 _item_block_unrealize(it->item->block);
1297 if ((it->disabled) || (dragged) || (it->display_only)) return;
1298 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1303 _item_highlight(it);
1308 _item_unhighlight(it);
1316 Widget_Data *wd = it->wd;
1319 while (wd->selected)
1321 _item_unhighlight(wd->selected->data);
1322 _item_unselect(wd->selected->data);
1328 const Eina_List *l, *l_next;
1331 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1334 _item_unhighlight(it2);
1335 _item_unselect(it2);
1337 //_item_highlight(it);
1340 _item_highlight(it);
1346 _signal_expand_toggle(void *data,
1347 Evas_Object *obj __UNUSED__,
1348 const char *emission __UNUSED__,
1349 const char *source __UNUSED__)
1351 Elm_Gen_Item *it = data;
1353 if (it->item->expanded)
1354 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1356 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1360 _signal_expand(void *data,
1361 Evas_Object *obj __UNUSED__,
1362 const char *emission __UNUSED__,
1363 const char *source __UNUSED__)
1365 Elm_Gen_Item *it = data;
1367 if (!it->item->expanded)
1368 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1372 _signal_contract(void *data,
1373 Evas_Object *obj __UNUSED__,
1374 const char *emission __UNUSED__,
1375 const char *source __UNUSED__)
1377 Elm_Gen_Item *it = data;
1379 if (it->item->expanded)
1380 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1384 _scr_hold_timer_cb(void *data)
1386 if (!data) return ECORE_CALLBACK_CANCEL;
1387 Widget_Data *wd = data;
1388 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1389 wd->scr_hold_timer = NULL;
1390 return ECORE_CALLBACK_CANCEL;
1394 _mode_finished_signal_cb(void *data,
1396 const char *emission __UNUSED__,
1397 const char *source __UNUSED__)
1401 Elm_Gen_Item *it = data;
1402 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1404 Evas *te = evas_object_evas_get(obj);
1406 evas_event_freeze(te);
1407 it->item->nocache = EINA_FALSE;
1408 _mode_item_unrealize(it);
1409 if (it->item->group_item)
1410 evas_object_raise(it->item->VIEW(group_item));
1411 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->mode_type);
1412 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1413 evas_event_thaw(te);
1414 evas_event_thaw_eval(te);
1418 _item_cache_clean(Widget_Data *wd)
1420 evas_event_freeze(evas_object_evas_get(wd->obj));
1421 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1425 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1426 wd->item_cache = eina_inlist_remove(wd->item_cache,
1427 wd->item_cache->last);
1428 wd->item_cache_count--;
1429 if (itc->spacer) evas_object_del(itc->spacer);
1430 if (itc->base_view) evas_object_del(itc->base_view);
1431 if (itc->item_style) eina_stringshare_del(itc->item_style);
1434 evas_event_thaw(evas_object_evas_get(wd->obj));
1435 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1439 _item_cache_zero(Widget_Data *wd)
1441 int pmax = wd->item_cache_max;
1442 wd->item_cache_max = 0;
1443 _item_cache_clean(wd);
1444 wd->item_cache_max = pmax;
1448 _item_cache_add(Elm_Gen_Item *it)
1452 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1453 if (it->wd->item_cache_max <= 0)
1455 evas_object_del(VIEW(it));
1457 evas_object_del(it->spacer);
1459 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1460 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1464 it->wd->item_cache_count++;
1465 itc = calloc(1, sizeof(Item_Cache));
1466 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1467 EINA_INLIST_GET(itc));
1468 itc->spacer = it->spacer;
1470 itc->base_view = VIEW(it);
1472 evas_object_hide(itc->base_view);
1473 evas_object_move(itc->base_view, -9999, -9999);
1474 itc->item_style = eina_stringshare_add(it->itc->item_style);
1475 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) itc->tree = 1;
1476 itc->compress = (it->wd->compress);
1477 itc->selected = it->selected;
1478 itc->disabled = it->disabled;
1479 itc->expanded = it->item->expanded;
1482 ecore_timer_del(it->long_timer);
1483 it->long_timer = NULL;
1485 if (it->item->swipe_timer)
1487 ecore_timer_del(it->item->swipe_timer);
1488 it->item->swipe_timer = NULL;
1490 // FIXME: other callbacks?
1491 edje_object_signal_callback_del_full(itc->base_view,
1492 "elm,action,expand,toggle",
1493 "elm", _signal_expand_toggle, it);
1494 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1496 _signal_expand, it);
1497 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1498 "elm", _signal_contract, it);
1499 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1501 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1503 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1505 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1507 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1509 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1511 _item_cache_clean(it->wd);
1512 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1513 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1517 _item_cache_find(Elm_Gen_Item *it)
1522 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) tree = 1;
1523 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1525 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1527 if ((itc->tree == tree) &&
1528 (itc->compress == it->wd->compress) &&
1529 (!strcmp(it->itc->item_style, itc->item_style)))
1531 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1532 EINA_INLIST_GET(itc));
1533 it->wd->item_cache_count--;
1541 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1543 if (!it->item->nostacking)
1545 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1546 evas_object_lower(VIEW(it));
1548 evas_object_raise(VIEW(it));
1551 if (it->item->order_num_in & 0x1)
1552 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1554 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1558 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1562 if (it->selected != itc->selected)
1565 edje_object_signal_emit(VIEW(it),
1566 "elm,state,selected", "elm");
1568 if (it->disabled != itc->disabled)
1571 edje_object_signal_emit(VIEW(it),
1572 "elm,state,disabled", "elm");
1574 if (it->item->expanded != itc->expanded)
1576 if (it->item->expanded)
1577 edje_object_signal_emit(VIEW(it),
1578 "elm,state,expanded", "elm");
1584 edje_object_signal_emit(VIEW(it),
1585 "elm,state,selected", "elm");
1587 edje_object_signal_emit(VIEW(it),
1588 "elm,state,disabled", "elm");
1589 if (it->item->expanded)
1590 edje_object_signal_emit(VIEW(it),
1591 "elm,state,expanded", "elm");
1596 _item_cache_free(Item_Cache *itc)
1598 if (itc->spacer) evas_object_del(itc->spacer);
1599 if (itc->base_view) evas_object_del(itc->base_view);
1600 if (itc->item_style) eina_stringshare_del(itc->item_style);
1605 _item_del_hook(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1607 Elm_Gen_Item *it = event_info;
1609 if (it->wd->last_selected_item == it)
1610 it->wd->last_selected_item = NULL;
1614 _item_label_realize(Elm_Gen_Item *it,
1615 Evas_Object *target,
1619 if (it->itc->func.text_get)
1624 *source = elm_widget_stringlist_get(edje_object_data_get(target, "labels"));
1625 EINA_LIST_FOREACH(*source, l, key)
1627 if (parts && fnmatch(parts, key, FNM_PERIOD))
1630 char *s = it->itc->func.text_get
1631 ((void *)it->base.data, WIDGET(it), key);
1635 edje_object_part_text_set(target, key, s);
1640 edje_object_part_text_set(target, key, "");
1647 _item_content_unrealize(Elm_Gen_Item *it,
1648 Evas_Object *target,
1652 Eina_List *res = it->content_objs;
1654 if (it->itc->func.content_get)
1658 Evas_Object *ic = NULL;
1660 EINA_LIST_FOREACH(*source, l, key)
1662 if (parts && fnmatch(parts, key, FNM_PERIOD))
1665 ic = edje_object_part_swallow_get(target, key);
1668 res = eina_list_remove(res, ic);
1669 edje_object_part_unswallow(target, ic);
1670 evas_object_del(ic);
1679 _item_content_realize(Elm_Gen_Item *it,
1680 Evas_Object *target,
1684 Eina_List *res = NULL;
1686 if (it->itc->func.content_get)
1690 Evas_Object *ic = NULL;
1692 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1694 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
1695 res = it->content_objs;
1697 EINA_LIST_FOREACH(*source, l, key)
1699 if (parts && fnmatch(parts, key, FNM_PERIOD))
1702 if (it->itc->func.content_get)
1703 ic = it->itc->func.content_get
1704 ((void *)it->base.data, WIDGET(it), key);
1707 res = eina_list_append(res, ic);
1708 edje_object_part_swallow(target, key, ic);
1709 evas_object_show(ic);
1710 elm_widget_sub_object_add(WIDGET(it), ic);
1712 elm_widget_disabled_set(ic, EINA_TRUE);
1721 _item_state_realize(Elm_Gen_Item *it,
1722 Evas_Object *target,
1726 if (it->itc->func.state_get)
1732 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
1733 EINA_LIST_FOREACH(*source, l, key)
1735 if (parts && fnmatch(parts, key, FNM_PERIOD))
1738 Eina_Bool on = it->itc->func.state_get
1739 ((void *)it->base.data, WIDGET(it), key);
1743 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1744 edje_object_signal_emit(target, buf, "elm");
1748 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1749 edje_object_signal_emit(target, buf, "elm");
1756 _item_realize(Elm_Gen_Item *it,
1761 const char *treesize;
1763 int depth, tsize = 20;
1764 Item_Cache *itc = NULL;
1766 if (it->generation < it->wd->generation) return;
1767 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1770 if (it->item->order_num_in != in)
1772 it->item->order_num_in = in;
1773 _elm_genlist_item_odd_even_update(it);
1774 _elm_genlist_item_state_update(it, NULL);
1776 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1777 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1780 it->item->order_num_in = in;
1782 if (it->item->nocache)
1783 it->item->nocache = EINA_FALSE;
1785 itc = _item_cache_find(it);
1788 VIEW(it) = itc->base_view;
1789 itc->base_view = NULL;
1790 it->spacer = itc->spacer;
1795 const char *stacking_even;
1796 const char *stacking;
1798 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1799 edje_object_scale_set(VIEW(it),
1800 elm_widget_scale_get(WIDGET(it)) *
1801 _elm_config->scale);
1802 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
1803 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1805 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
1806 strncpy(buf, "tree", sizeof(buf));
1807 else strncpy(buf, "item", sizeof(buf));
1808 if (it->wd->compress)
1809 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1811 strncat(buf, "/", sizeof(buf) - strlen(buf));
1812 strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1814 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
1815 elm_widget_style_get(WIDGET(it)));
1817 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1818 if (!stacking_even) stacking_even = "above";
1819 it->item->stacking_even = !!strcmp("above", stacking_even);
1821 stacking = edje_object_data_get(VIEW(it), "stacking");
1822 if (!stacking) stacking = "yes";
1823 it->item->nostacking = !!strcmp("yes", stacking);
1825 edje_object_mirrored_set(VIEW(it),
1826 elm_widget_mirrored_get(WIDGET(it)));
1828 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1829 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1830 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1833 _elm_genlist_item_odd_even_update(it);
1835 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
1837 if (!it2->parent->group) depth += 1;
1839 it->item->expanded_depth = depth;
1840 treesize = edje_object_data_get(VIEW(it), "treesize");
1841 if (treesize) tsize = atoi(treesize);
1842 evas_object_size_hint_min_set(it->spacer,
1843 (depth * tsize) * _elm_config->scale, 1);
1844 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1847 edje_object_signal_callback_add(VIEW(it),
1848 "elm,action,expand,toggle",
1849 "elm", _signal_expand_toggle, it);
1850 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
1851 "elm", _signal_expand, it);
1852 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
1853 "elm", _signal_contract, it);
1854 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
1856 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
1858 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1860 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
1862 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
1864 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
1867 _elm_genlist_item_state_update(it, itc);
1870 if ((calc) && (it->wd->homogeneous) &&
1871 ((it->wd->item_width) ||
1872 ((it->wd->item_width) && (it->wd->group_item_width))))
1874 /* homogenous genlist shortcut */
1875 if (!it->item->mincalcd)
1879 it->item->w = it->item->minw = it->wd->group_item_width;
1880 it->item->h = it->item->minh = it->wd->group_item_height;
1884 it->item->w = it->item->minw = it->wd->item_width;
1885 it->item->h = it->item->minh = it->wd->item_height;
1887 it->item->mincalcd = EINA_TRUE;
1892 /* FIXME: If you see that assert, please notify us and we
1893 will clean our mess */
1894 assert(eina_list_count(it->content_objs) == 0);
1896 _item_label_realize(it, VIEW(it), &it->labels, NULL);
1897 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
1898 _item_state_realize(it, VIEW(it), &it->states, NULL);
1900 if (!it->item->mincalcd)
1902 Evas_Coord mw = -1, mh = -1;
1904 if (!it->display_only)
1905 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1906 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
1907 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
1909 if (!it->display_only)
1910 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1911 it->item->w = it->item->minw = mw;
1912 it->item->h = it->item->minh = mh;
1913 it->item->mincalcd = EINA_TRUE;
1915 if ((!it->wd->group_item_width) && (it->group))
1917 it->wd->group_item_width = mw;
1918 it->wd->group_item_height = mh;
1920 else if ((!it->wd->item_width) && (it->item->flags == ELM_GENLIST_ITEM_NONE))
1922 it->wd->item_width = mw;
1923 it->wd->item_height = mh;
1926 if (!calc) evas_object_show(VIEW(it));
1929 if (it->tooltip.content_cb)
1931 elm_widget_item_tooltip_content_cb_set(it,
1932 it->tooltip.content_cb,
1933 it->tooltip.data, NULL);
1934 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1935 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1938 if (it->mouse_cursor)
1939 elm_widget_item_cursor_set(it, it->mouse_cursor);
1941 it->realized = EINA_TRUE;
1942 it->want_unrealize = EINA_FALSE;
1944 if (itc) _item_cache_free(itc);
1945 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1946 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1948 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1949 edje_object_message_signal_process(VIEW(it));
1953 _item_unrealize_cb(Elm_Gen_Item *it)
1955 if (it->item->nocache)
1957 evas_object_del(VIEW(it));
1959 evas_object_del(it->spacer);
1964 edje_object_mirrored_set(VIEW(it),
1965 elm_widget_mirrored_get(WIDGET(it)));
1966 edje_object_scale_set(VIEW(it),
1967 elm_widget_scale_get(WIDGET(it))
1968 * _elm_config->scale);
1969 _item_cache_add(it);
1972 _mode_item_unrealize(it);
1974 it->realized = EINA_FALSE;
1975 it->want_unrealize = EINA_FALSE;
1979 _item_block_recalc(Item_Block *itb,
1985 Evas_Coord minw = 0, minh = 0;
1986 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
1989 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
1991 EINA_LIST_FOREACH(itb->items, l, it)
1993 if (it->generation < it->wd->generation) continue;
1994 showme |= it->item->showme;
1999 if (!it->item->mincalcd) changed = EINA_TRUE;
2002 _item_realize(it, in, EINA_TRUE);
2003 _elm_genlist_item_unrealize(it, EINA_TRUE);
2008 _item_realize(it, in, EINA_TRUE);
2009 _elm_genlist_item_unrealize(it, EINA_TRUE);
2013 _item_realize(it, in, EINA_FALSE);
2014 minh += it->item->minh;
2015 if (minw < it->item->minw) minw = it->item->minw;
2023 itb->changed = EINA_FALSE;
2024 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2025 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2030 _item_block_realize(Item_Block *itb)
2032 if (itb->realized) return;
2033 itb->realized = EINA_TRUE;
2034 itb->want_unrealize = EINA_FALSE;
2038 _item_block_unrealize(Item_Block *itb)
2042 Eina_Bool dragging = EINA_FALSE;
2044 if (!itb->realized) return;
2045 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2046 EINA_LIST_FOREACH(itb->items, l, it)
2052 dragging = EINA_TRUE;
2053 it->want_unrealize = EINA_TRUE;
2056 _elm_genlist_item_unrealize(it, EINA_FALSE);
2061 itb->realized = EINA_FALSE;
2062 itb->want_unrealize = EINA_TRUE;
2065 itb->want_unrealize = EINA_FALSE;
2066 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2067 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2071 _get_space_for_reorder_item(Elm_Gen_Item *it)
2073 Evas_Coord rox, roy, row, roh, oy, oh;
2074 Eina_Bool top = EINA_FALSE;
2075 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2076 if (!reorder_it) return 0;
2078 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2079 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2081 if ((it->wd->reorder_start_y < it->item->block->y) &&
2082 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2084 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2085 if (it->item->block->count == 1)
2086 it->wd->reorder_rel = it;
2088 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2089 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2091 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2094 it->item->block->reorder_offset = 0;
2096 it->item->scrl_y += it->item->block->reorder_offset;
2098 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2099 rox, roy + (roh / 2), row, 1));
2102 it->wd->reorder_rel = it;
2103 it->item->scrl_y += it->wd->reorder_it->item->h;
2104 return it->wd->reorder_it->item->h;
2111 _reorder_move_animator_cb(void *data)
2113 Elm_Gen_Item *it = data;
2114 Eina_Bool down = EINA_FALSE;
2116 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2118 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2120 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2123 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2124 if (diff > it->item->h) y = diff / 2;
2126 if (it->item->old_scrl_y < it->item->scrl_y)
2128 it->item->old_scrl_y += y;
2131 else if (it->item->old_scrl_y > it->item->scrl_y)
2133 it->item->old_scrl_y -= y;
2136 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2137 _group_items_recalc(it->wd);
2139 if ((it->wd->reorder_pan_move) ||
2140 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2141 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2143 it->item->old_scrl_y = it->item->scrl_y;
2144 it->item->move_effect_enabled = EINA_FALSE;
2145 it->wd->reorder_move_animator = NULL;
2146 return ECORE_CALLBACK_CANCEL;
2148 return ECORE_CALLBACK_RENEW;
2152 _item_position(Elm_Gen_Item *it,
2160 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2161 evas_object_resize(view, it->item->w, it->item->h);
2162 evas_object_move(view, it_x, it_y);
2163 evas_object_show(view);
2164 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2165 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2169 _item_block_position(Item_Block *itb,
2175 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2176 Eina_Bool vis = EINA_FALSE;
2178 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2179 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2180 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2182 EINA_LIST_FOREACH(itb->items, l, it)
2184 if (it->generation < it->wd->generation) continue;
2185 else if (it->wd->reorder_it == it) continue;
2188 it->item->w = itb->w;
2189 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2190 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2192 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2193 cvx, cvy, cvw, cvh));
2196 if ((itb->realized) && (!it->realized))
2198 if (vis) _item_realize(it, in, EINA_FALSE);
2204 if (it->wd->reorder_mode)
2205 y += _get_space_for_reorder_item(it);
2206 git = it->item->group_item;
2209 if (git->item->scrl_y < oy)
2210 git->item->scrl_y = oy;
2211 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2212 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2213 git->item->want_realize = EINA_TRUE;
2215 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2217 if (!it->item->move_effect_enabled)
2219 it->item->move_effect_enabled = EINA_TRUE;
2220 it->wd->reorder_move_animator =
2222 _reorder_move_animator_cb, it);
2225 if (!it->item->move_effect_enabled)
2227 if (it->item->mode_view)
2228 _item_position(it, it->item->mode_view, it->item->scrl_x,
2231 _item_position(it, VIEW(it), it->item->scrl_x,
2233 it->item->old_scrl_y = it->item->scrl_y;
2238 if (!it->dragging) _elm_genlist_item_unrealize(it, EINA_FALSE);
2245 if (vis) it->item->want_realize = EINA_TRUE;
2249 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2250 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2254 _group_items_recalc(void *data)
2256 Widget_Data *wd = data;
2260 evas_event_freeze(evas_object_evas_get(wd->obj));
2261 EINA_LIST_FOREACH(wd->group_items, l, git)
2263 if (git->item->want_realize)
2266 _item_realize(git, 0, EINA_FALSE);
2267 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2268 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2269 evas_object_show(VIEW(git));
2270 evas_object_raise(VIEW(git));
2272 else if (!git->item->want_realize && git->realized)
2275 _elm_genlist_item_unrealize(git, EINA_FALSE);
2278 evas_event_thaw(evas_object_evas_get(wd->obj));
2279 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2283 _must_recalc_idler(void *data)
2285 Widget_Data *wd = data;
2286 if (wd->calc_job) ecore_job_del(wd->calc_job);
2287 wd->calc_job = ecore_job_add(_calc_job, wd);
2288 wd->must_recalc_idler = NULL;
2289 return ECORE_CALLBACK_CANCEL;
2293 _calc_job(void *data)
2295 Widget_Data *wd = data;
2296 Item_Block *itb, *chb = NULL;
2297 Evas_Coord minw = -1, minh = 0, y = 0, ow;
2299 Eina_Bool minw_change = EINA_FALSE;
2300 Eina_Bool did_must_recalc = EINA_FALSE;
2303 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2307 evas_event_freeze(evas_object_evas_get(wd->obj));
2308 EINA_INLIST_FOREACH(wd->blocks, itb)
2310 Eina_Bool showme = EINA_FALSE;
2313 showme = itb->showme;
2314 itb->showme = EINA_FALSE;
2317 if (itb->realized) _item_block_unrealize(itb);
2319 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2321 if (itb->must_recalc)
2325 EINA_LIST_FOREACH(itb->items, l, it)
2326 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2327 itb->changed = EINA_TRUE;
2328 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2329 itb->must_recalc = EINA_FALSE;
2331 if (itb->realized) _item_block_unrealize(itb);
2332 showme = _item_block_recalc(itb, in, EINA_FALSE);
2338 if (minw == -1) minw = itb->minw;
2339 else if ((!itb->must_recalc) && (minw < itb->minw))
2342 minw_change = EINA_TRUE;
2348 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2350 wd->show_item->item->showme = EINA_FALSE;
2352 elm_smart_scroller_region_bring_in(wd->scr,
2354 wd->show_item->item->block->x,
2356 wd->show_item->item->block->y,
2357 wd->show_item->item->block->w,
2358 wd->show_item->item->h);
2360 elm_smart_scroller_child_region_show(wd->scr,
2362 wd->show_item->item->block->x,
2364 wd->show_item->item->block->y,
2365 wd->show_item->item->block->w,
2366 wd->show_item->item->h);
2367 wd->show_item = NULL;
2372 EINA_INLIST_FOREACH(wd->blocks, itb)
2378 if ((chb) && (EINA_INLIST_GET(chb)->next))
2380 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2382 if (itb->realized) _item_block_unrealize(itb);
2385 wd->realminw = minw;
2386 if (minw < wd->w) minw = wd->w;
2387 if ((minw != wd->minw) || (minh != wd->minh))
2391 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2392 _sizing_eval(wd->obj);
2393 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2398 it = wd->anchor_item;
2399 it_y = wd->anchor_y;
2400 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2401 it->item->block->y + it->y + it_y);
2402 wd->anchor_item = it;
2403 wd->anchor_y = it_y;
2406 if (did_must_recalc)
2408 if (!wd->must_recalc_idler)
2409 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2411 wd->calc_job = NULL;
2412 evas_object_smart_changed(wd->pan_smart);
2413 evas_event_thaw(evas_object_evas_get(wd->obj));
2414 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2418 _update_job(void *data)
2420 Widget_Data *wd = data;
2424 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2426 wd->update_job = NULL;
2429 evas_event_freeze(evas_object_evas_get(wd->obj));
2430 EINA_INLIST_FOREACH(wd->blocks, itb)
2432 Evas_Coord itminw, itminh;
2439 _item_block_position(itb, num);
2443 recalc = EINA_FALSE;
2444 EINA_LIST_FOREACH(itb->items, l2, it)
2446 if (it->item->updateme)
2448 itminw = it->item->minw;
2449 itminh = it->item->minh;
2451 it->item->updateme = EINA_FALSE;
2454 _elm_genlist_item_unrealize(it, EINA_FALSE);
2455 _item_realize(it, num, EINA_FALSE);
2456 position = EINA_TRUE;
2460 _item_realize(it, num, EINA_TRUE);
2461 _elm_genlist_item_unrealize(it, EINA_TRUE);
2463 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2468 itb->updateme = EINA_FALSE;
2471 position = EINA_TRUE;
2472 itb->changed = EINA_TRUE;
2473 _item_block_recalc(itb, num0, EINA_FALSE);
2474 _item_block_position(itb, num0);
2479 if (wd->calc_job) ecore_job_del(wd->calc_job);
2480 wd->calc_job = ecore_job_add(_calc_job, wd);
2482 evas_event_thaw(evas_object_evas_get(wd->obj));
2483 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2487 _pan_set(Evas_Object *obj,
2491 Pan *sd = evas_object_smart_data_get(obj);
2495 // Evas_Coord ow, oh;
2496 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2497 // ow = sd->wd->minw - ow;
2498 // if (ow < 0) ow = 0;
2499 // oh = sd->wd->minh - oh;
2500 // if (oh < 0) oh = 0;
2501 // if (x < 0) x = 0;
2502 // if (y < 0) y = 0;
2503 // if (x > ow) x = ow;
2504 // if (y > oh) y = oh;
2505 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2509 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2511 if ((itb->y + itb->h) > y)
2516 EINA_LIST_FOREACH(itb->items, l2, it)
2518 if ((itb->y + it->y) >= y)
2520 sd->wd->anchor_item = it;
2521 sd->wd->anchor_y = -(itb->y + it->y - y);
2528 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2532 _pan_get(Evas_Object *obj,
2536 Pan *sd = evas_object_smart_data_get(obj);
2539 if (x) *x = sd->wd->pan_x;
2540 if (y) *y = sd->wd->pan_y;
2544 _pan_max_get(Evas_Object *obj,
2548 Pan *sd = evas_object_smart_data_get(obj);
2552 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2553 ow = sd->wd->minw - ow;
2555 oh = sd->wd->minh - oh;
2562 _pan_min_get(Evas_Object *obj __UNUSED__,
2571 _pan_child_size_get(Evas_Object *obj,
2575 Pan *sd = evas_object_smart_data_get(obj);
2578 if (w) *w = sd->wd->minw;
2579 if (h) *h = sd->wd->minh;
2583 _pan_add(Evas_Object *obj)
2586 Evas_Object_Smart_Clipped_Data *cd;
2589 cd = evas_object_smart_data_get(obj);
2592 sd->__clipped_data = *cd;
2594 evas_object_smart_data_set(obj, sd);
2598 _pan_del(Evas_Object *obj)
2600 Pan *sd = evas_object_smart_data_get(obj);
2605 ecore_job_del(sd->resize_job);
2606 sd->resize_job = NULL;
2612 _pan_resize_job(void *data)
2616 _sizing_eval(sd->wd->obj);
2617 sd->resize_job = NULL;
2621 _pan_resize(Evas_Object *obj,
2625 Pan *sd = evas_object_smart_data_get(obj);
2629 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2630 if ((ow == w) && (oh == h)) return;
2631 if ((sd->wd->height_for_width) && (ow != w))
2634 if (sd->resize_job) ecore_job_del(sd->resize_job);
2635 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2637 sd->wd->pan_resized = EINA_TRUE;
2638 evas_object_smart_changed(obj);
2639 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2640 sd->wd->calc_job = NULL;
2642 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2643 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2648 _pan_calculate(Evas_Object *obj)
2650 Pan *sd = evas_object_smart_data_get(obj);
2652 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2658 evas_event_freeze(evas_object_evas_get(obj));
2660 if (sd->wd->pan_resized)
2663 sd->wd->pan_resized = EINA_FALSE;
2666 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2667 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2668 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2670 git->item->want_realize = EINA_FALSE;
2672 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2674 itb->w = sd->wd->minw;
2675 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2676 itb->y - sd->wd->pan_y + oy,
2678 cvx, cvy, cvw, cvh))
2680 if ((!itb->realized) || (itb->changed))
2681 _item_block_realize(itb);
2682 _item_block_position(itb, in);
2686 if (itb->realized) _item_block_unrealize(itb);
2690 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2691 _group_items_recalc(sd->wd);
2692 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2694 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2695 sd->wd->reorder_pan_move = EINA_TRUE;
2696 else sd->wd->reorder_pan_move = EINA_FALSE;
2697 evas_object_raise(sd->wd->VIEW(reorder_it));
2698 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2699 sd->wd->start_time = ecore_loop_time_get();
2701 _item_auto_scroll(sd->wd);
2702 evas_event_thaw(evas_object_evas_get(obj));
2703 evas_event_thaw_eval(evas_object_evas_get(obj));
2707 _pan_move(Evas_Object *obj,
2708 Evas_Coord x __UNUSED__,
2709 Evas_Coord y __UNUSED__)
2711 Pan *sd = evas_object_smart_data_get(obj);
2714 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2715 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2719 _hold_on(void *data __UNUSED__,
2721 void *event_info __UNUSED__)
2723 Widget_Data *wd = elm_widget_data_get(obj);
2725 elm_smart_scroller_hold_set(wd->scr, 1);
2729 _hold_off(void *data __UNUSED__,
2731 void *event_info __UNUSED__)
2733 Widget_Data *wd = elm_widget_data_get(obj);
2735 elm_smart_scroller_hold_set(wd->scr, 0);
2739 _freeze_on(void *data __UNUSED__,
2741 void *event_info __UNUSED__)
2743 Widget_Data *wd = elm_widget_data_get(obj);
2745 elm_smart_scroller_freeze_set(wd->scr, 1);
2749 _freeze_off(void *data __UNUSED__,
2751 void *event_info __UNUSED__)
2753 Widget_Data *wd = elm_widget_data_get(obj);
2755 elm_smart_scroller_freeze_set(wd->scr, 0);
2759 _scr_anim_start(void *data,
2760 Evas_Object *obj __UNUSED__,
2761 void *event_info __UNUSED__)
2763 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
2767 _scr_anim_stop(void *data,
2768 Evas_Object *obj __UNUSED__,
2769 void *event_info __UNUSED__)
2771 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
2775 _scr_drag_start(void *data,
2776 Evas_Object *obj __UNUSED__,
2777 void *event_info __UNUSED__)
2779 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
2783 _scr_drag_stop(void *data,
2784 Evas_Object *obj __UNUSED__,
2785 void *event_info __UNUSED__)
2787 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
2791 _edge_left(void *data,
2792 Evas_Object *scr __UNUSED__,
2793 void *event_info __UNUSED__)
2795 Evas_Object *obj = data;
2796 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2800 _edge_right(void *data,
2801 Evas_Object *scr __UNUSED__,
2802 void *event_info __UNUSED__)
2804 Evas_Object *obj = data;
2805 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2809 _edge_top(void *data,
2810 Evas_Object *scr __UNUSED__,
2811 void *event_info __UNUSED__)
2813 Evas_Object *obj = data;
2814 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2818 _edge_bottom(void *data,
2819 Evas_Object *scr __UNUSED__,
2820 void *event_info __UNUSED__)
2822 Evas_Object *obj = data;
2823 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2827 _mode_item_realize(Elm_Gen_Item *it)
2831 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
2833 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2834 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
2835 edje_object_scale_set(it->item->mode_view,
2836 elm_widget_scale_get(WIDGET(it)) *
2837 _elm_config->scale);
2838 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
2839 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
2841 strncpy(buf, "item", sizeof(buf));
2842 if (it->wd->compress)
2843 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
2845 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
2846 strncat(buf, "/", sizeof(buf) - strlen(buf));
2847 strncat(buf, it->wd->mode_item_style, sizeof(buf) - strlen(buf));
2849 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
2850 elm_widget_style_get(WIDGET(it)));
2851 edje_object_mirrored_set(it->item->mode_view,
2852 elm_widget_mirrored_get(WIDGET(it)));
2854 /* signal callback add */
2855 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
2857 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
2859 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
2862 /* text_get, content_get, state_get */
2863 /* FIXME: If you see that assert, please notify us and we
2864 will clean our mess */
2865 assert(eina_list_count(it->item->mode_content_objs) == 0);
2867 _item_label_realize(it, it->item->mode_view, &it->item->mode_labels, NULL);
2868 it->item->mode_content_objs =
2869 _item_content_realize(it, it->item->mode_view,
2870 &it->item->mode_contents, NULL);
2871 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
2873 edje_object_part_swallow(it->item->mode_view,
2874 edje_object_data_get(it->item->mode_view, "mode_part"),
2877 it->want_unrealize = EINA_FALSE;
2878 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2879 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2883 _mode_item_unrealize(Elm_Gen_Item *it)
2885 Widget_Data *wd = it->wd;
2886 Evas_Object *content;
2887 if (!it->item->mode_view) return;
2889 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2890 elm_widget_stringlist_free(it->item->mode_labels);
2891 it->item->mode_labels = NULL;
2892 elm_widget_stringlist_free(it->item->mode_contents);
2893 it->item->mode_contents = NULL;
2894 elm_widget_stringlist_free(it->item->mode_states);
2896 EINA_LIST_FREE(it->item->mode_content_objs, content)
2897 evas_object_del(content);
2899 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
2900 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
2901 evas_object_del(it->item->mode_view);
2902 it->item->mode_view = NULL;
2904 if (wd->mode_item == it)
2905 wd->mode_item = NULL;
2906 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2907 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2911 _item_mode_set(Elm_Gen_Item *it)
2914 Widget_Data *wd = it->wd;
2919 it->item->nocache = EINA_TRUE;
2921 if (wd->scr_hold_timer)
2923 ecore_timer_del(wd->scr_hold_timer);
2924 wd->scr_hold_timer = NULL;
2926 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
2927 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
2929 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2930 _mode_item_realize(it);
2931 if (it->item->group_item)
2932 evas_object_raise(it->item->VIEW(group_item));
2933 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
2934 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2935 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2937 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
2938 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2942 _item_mode_unset(Widget_Data *wd)
2945 if (!wd->mode_item) return;
2946 char buf[1024], buf2[1024];
2950 it->item->nocache = EINA_TRUE;
2952 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
2953 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
2955 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2956 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
2958 wd->mode_item = NULL;
2962 _item_auto_scroll(Widget_Data *wd)
2967 Evas_Coord ox, oy, ow, oh;
2969 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
2971 evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
2972 if (wd->expanded_item->item->scrl_y > (oh + oy) / 2)
2974 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
2975 elm_genlist_item_bring_in(it);
2977 wd->auto_scroll_enabled = EINA_FALSE;
2982 elm_genlist_add(Evas_Object *parent)
2987 Evas_Coord minw, minh;
2988 static Evas_Smart *smart = NULL;
2992 static Evas_Smart_Class sc;
2994 evas_object_smart_clipped_smart_set(&_pan_sc);
2996 sc.name = "elm_genlist_pan";
2997 sc.version = EVAS_SMART_CLASS_VERSION;
3000 sc.resize = _pan_resize;
3001 sc.move = _pan_move;
3002 sc.calculate = _pan_calculate;
3003 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3006 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3008 ELM_SET_WIDTYPE(widtype, "genlist");
3010 elm_widget_type_set(obj, "genlist");
3011 elm_widget_sub_object_add(parent, obj);
3012 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3013 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3014 elm_widget_data_set(obj, wd);
3015 elm_widget_del_hook_set(obj, _del_hook);
3016 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3017 elm_widget_theme_hook_set(obj, _theme_hook);
3018 elm_widget_can_focus_set(obj, EINA_TRUE);
3019 elm_widget_event_hook_set(obj, _event_hook);
3020 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3021 elm_widget_translate_hook_set(obj, _translate_hook);
3024 wd->scr = elm_smart_scroller_add(e);
3025 elm_smart_scroller_widget_set(wd->scr, obj);
3026 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3027 elm_widget_style_get(obj));
3028 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3029 _elm_config->thumbscroll_bounce_enable);
3030 elm_widget_resize_object_set(obj, wd->scr);
3032 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3033 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3034 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3035 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3036 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3037 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3038 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3039 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3042 wd->mode = ELM_LIST_SCROLL;
3043 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3044 wd->item_cache_max = wd->max_items_per_block * 2;
3045 wd->longpress_timeout = _elm_config->longpress_timeout;
3047 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3048 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3049 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3050 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3052 wd->pan_smart = evas_object_smart_add(e, smart);
3053 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3056 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3057 _pan_set, _pan_get, _pan_max_get,
3058 _pan_min_get, _pan_child_size_get);
3060 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3062 evas_object_size_hint_min_set(obj, minw, minh);
3064 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3066 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3072 _item_select(Elm_Gen_Item *it)
3074 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3077 it->selected = EINA_TRUE;
3078 it->wd->selected = eina_list_append(it->wd->selected, it);
3080 else if (!it->wd->always_select) return;
3082 evas_object_ref(WIDGET(it));
3085 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3086 if (it->generation == it->wd->generation)
3087 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3090 evas_object_unref(WIDGET(it));
3091 if ((it->wd->clear_me) && (!it->wd->walking))
3092 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3095 if ((!it->walking) && (it->generation < it->wd->generation))
3097 if (!it->relcount) it->del_cb(it);
3100 it->wd->last_selected_item = it;
3104 static Evas_Object *
3105 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3107 return edje_object_part_swallow_get(VIEW(it), part);
3111 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3113 edje_object_part_swallow(VIEW(it), part, content);
3116 static Evas_Object *
3117 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3121 obj = edje_object_part_swallow_get(VIEW(it), part);
3122 if (!obj) return NULL;
3123 edje_object_part_unswallow(VIEW(it), obj);
3128 _item_label_hook(Elm_Gen_Item *it, const char *part)
3130 if (!it->itc->func.text_get) return NULL;
3131 return edje_object_part_text_get(VIEW(it), part);
3135 _elm_genlist_item_new(Widget_Data *wd,
3136 const Elm_Gen_Item_Class *itc,
3138 Elm_Gen_Item *parent,
3140 const void *func_data)
3144 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3145 if (!it) return NULL;
3147 it->generation = wd->generation;
3149 it->base.data = data;
3150 it->parent = parent;
3151 it->func.func = func;
3152 it->func.data = func_data;
3153 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3154 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3155 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3157 it->sel_cb = (Ecore_Cb)_item_select;
3159 elm_widget_item_text_get_hook_set(it, _item_label_hook);
3163 static Elm_Gen_Item *
3164 _item_new(Widget_Data *wd,
3165 const Elm_Genlist_Item_Class *itc,
3167 Elm_Gen_Item *parent,
3168 Elm_Genlist_Item_Flags flags,
3170 const void *func_data)
3174 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3175 if (!it) return NULL;
3176 it->item = ELM_NEW(Elm_Gen_Item_Type);
3177 it->item->flags = flags;
3178 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3179 it->item->expanded_depth = 0;
3180 elm_widget_item_del_cb_set(it, _item_del_hook);
3181 ELM_GEN_ITEM_SETUP(it);
3184 if (it->parent->group)
3185 it->item->group_item = parent;
3186 else if (it->parent->item->group_item)
3187 it->item->group_item = it->parent->item->group_item;
3193 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3197 itb = calloc(1, sizeof(Item_Block));
3198 if (!itb) return NULL;
3201 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3203 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3208 _item_block_add(Widget_Data *wd,
3211 Item_Block *itb = NULL;
3218 itb = calloc(1, sizeof(Item_Block));
3219 if (!itb) return EINA_FALSE;
3221 if (!it->item->rel->item->block)
3224 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3225 itb->items = eina_list_append(itb->items, it);
3229 if (it->item->before)
3231 wd->blocks = eina_inlist_prepend_relative
3232 (wd->blocks, EINA_INLIST_GET(itb),
3233 EINA_INLIST_GET(it->item->rel->item->block));
3235 eina_list_prepend_relative(itb->items, it, it->item->rel);
3239 wd->blocks = eina_inlist_append_relative
3240 (wd->blocks, EINA_INLIST_GET(itb),
3241 EINA_INLIST_GET(it->item->rel->item->block));
3243 eina_list_append_relative(itb->items, it, it->item->rel);
3249 if (it->item->before)
3253 itb = (Item_Block *)(wd->blocks);
3254 if (itb->count >= wd->max_items_per_block)
3256 itb = _item_block_new(wd, EINA_TRUE);
3257 if (!itb) return EINA_FALSE;
3262 itb = _item_block_new(wd, EINA_TRUE);
3263 if (!itb) return EINA_FALSE;
3265 itb->items = eina_list_prepend(itb->items, it);
3271 itb = (Item_Block *)(wd->blocks->last);
3272 if (itb->count >= wd->max_items_per_block)
3274 itb = _item_block_new(wd, EINA_FALSE);
3275 if (!itb) return EINA_FALSE;
3280 itb = _item_block_new(wd, EINA_FALSE);
3281 if (!itb) return EINA_FALSE;
3283 itb->items = eina_list_append(itb->items, it);
3289 if (it->item->rel->item->queued)
3291 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3292 on sorted insertion order, so the queue is not always ordered like the item list.
3293 This lead to issue where we depend on an item that is not yet created. As a quick
3294 work around, we reschedule the calc of the item and stop reordering the list to
3295 prevent any nasty issue to show up here.
3297 wd->queue = eina_list_append(wd->queue, it);
3298 wd->requeued = EINA_TRUE;
3299 it->item->queued = EINA_TRUE;
3302 itb = it->item->rel->item->block;
3303 if (!itb) goto newblock;
3304 if (it->item->before)
3305 itb->items = eina_list_prepend_relative(itb->items, it, it->item->rel);
3307 itb->items = eina_list_append_relative(itb->items, it, it->item->rel);
3310 itb->changed = EINA_TRUE;
3311 it->item->block = itb;
3312 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3313 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3316 it->item->rel->relcount--;
3317 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3318 _item_del(it->item->rel);
3319 it->item->rel = NULL;
3321 if (itb->count > itb->wd->max_items_per_block)
3326 Eina_Bool done = EINA_FALSE;
3328 newc = itb->count / 2;
3330 if (EINA_INLIST_GET(itb)->prev)
3332 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3334 if (itbp->count + newc < wd->max_items_per_block / 2)
3336 /* moving items to previous block */
3337 while ((itb->count > newc) && (itb->items))
3339 it2 = eina_list_data_get(itb->items);
3340 itb->items = eina_list_remove_list(itb->items, itb->items);
3343 itbp->items = eina_list_append(itbp->items, it2);
3344 it2->item->block = itbp;
3352 if (!done && EINA_INLIST_GET(itb)->next)
3354 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3356 if (itbn->count + newc < wd->max_items_per_block / 2)
3358 /* moving items to next block */
3359 while ((itb->count > newc) && (itb->items))
3363 l = eina_list_last(itb->items);
3364 it2 = eina_list_data_get(l);
3365 itb->items = eina_list_remove_list(itb->items, l);
3368 itbn->items = eina_list_prepend(itbn->items, it2);
3369 it2->item->block = itbn;
3379 /* moving items to new block */
3380 itb2 = calloc(1, sizeof(Item_Block));
3381 if (!itb2) return EINA_FALSE;
3384 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3385 EINA_INLIST_GET(itb));
3386 itb2->changed = EINA_TRUE;
3387 while ((itb->count > newc) && (itb->items))
3391 l = eina_list_last(itb->items);
3393 itb->items = eina_list_remove_list(itb->items, l);
3396 itb2->items = eina_list_prepend(itb2->items, it2);
3397 it2->item->block = itb2;
3407 _queue_process(Widget_Data *wd)
3410 Eina_Bool showme = EINA_FALSE;
3413 t0 = ecore_loop_time_get();
3414 //evas_event_freeze(evas_object_evas_get(wd->obj));
3415 for (n = 0; (wd->queue) && (n < 128); n++)
3419 it = eina_list_data_get(wd->queue);
3420 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3421 it->item->queued = EINA_FALSE;
3422 if (!_item_block_add(wd, it)) continue;
3424 _item_block_realize(it->item->block);
3425 t = ecore_time_get();
3426 if (it->item->block->changed)
3428 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3429 it->item->block->changed = 0;
3431 if (showme) it->item->block->showme = EINA_TRUE;
3432 if (eina_inlist_count(wd->blocks) > 1)
3434 if ((t - t0) > (ecore_animator_frametime_get())) break;
3437 //evas_event_thaw(evas_object_evas_get(wd->obj));
3438 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3443 _idle_process(void *data, Eina_Bool *wakeup)
3445 Widget_Data *wd = data;
3448 //static double q_start = 0.0;
3449 //if (q_start == 0.0) q_start = ecore_time_get();
3451 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
3455 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
3457 return ECORE_CALLBACK_CANCEL;
3459 return ECORE_CALLBACK_RENEW;
3463 _item_idle_enterer(void *data)
3465 Widget_Data *wd = data;
3466 Eina_Bool wakeup = EINA_FALSE;
3467 Eina_Bool ok = _idle_process(data, &wakeup);
3472 if (wd->calc_job) ecore_job_del(wd->calc_job);
3473 wd->calc_job = ecore_job_add(_calc_job, wd);
3475 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
3480 _item_queue(Widget_Data *wd,
3484 if (it->item->queued) return;
3485 it->item->queued = EINA_TRUE;
3486 if (cb && !wd->requeued)
3487 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
3489 wd->queue = eina_list_append(wd->queue, it);
3490 // FIXME: why does a freeze then thaw here cause some genlist
3491 // elm_genlist_item_append() to be much much slower?
3492 // evas_event_freeze(evas_object_evas_get(wd->obj));
3493 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
3495 if (wd->queue_idle_enterer)
3497 ecore_idle_enterer_del(wd->queue_idle_enterer);
3498 wd->queue_idle_enterer = NULL;
3502 // evas_event_thaw(evas_object_evas_get(wd->obj));
3503 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3504 if (!wd->queue_idle_enterer)
3505 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
3509 _elm_genlist_item_compare_data(const void *data, const void *data1)
3511 const Elm_Gen_Item *it = data;
3512 const Elm_Gen_Item *item1 = data1;
3514 return it->wd->item_compare_data_cb(it->base.data, item1->base.data);
3518 _elm_genlist_item_compare(const void *data, const void *data1)
3520 const Elm_Gen_Item *it, *item1;
3521 it = ELM_GEN_ITEM_FROM_INLIST(data);
3522 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
3523 return it->wd->item_compare_cb(it, item1);
3527 _elm_genlist_item_list_compare(const void *data, const void *data1)
3529 const Elm_Gen_Item *it = data;
3530 const Elm_Gen_Item *item1 = data1;
3531 return it->wd->item_compare_cb(it, item1);
3535 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
3540 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3541 _item_block_del(it);
3543 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3544 it->item->rel = after;
3545 it->item->rel->relcount++;
3546 it->item->before = EINA_FALSE;
3547 if (after->item->group_item) it->item->group_item = after->item->group_item;
3548 _item_queue(it->wd, it, NULL);
3550 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3554 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
3557 if (!before) return;
3559 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3560 _item_block_del(it);
3561 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
3562 it->item->rel = before;
3563 it->item->rel->relcount++;
3564 it->item->before = EINA_TRUE;
3565 if (before->item->group_item) it->item->group_item = before->item->group_item;
3566 _item_queue(it->wd, it, NULL);
3568 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3572 elm_genlist_item_append(Evas_Object *obj,
3573 const Elm_Genlist_Item_Class *itc,
3575 Elm_Gen_Item *parent,
3576 Elm_Genlist_Item_Flags flags,
3578 const void *func_data)
3580 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3581 Widget_Data *wd = elm_widget_data_get(obj);
3582 if (!wd) return NULL;
3583 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3585 if (!it) return NULL;
3589 wd->group_items = eina_list_append(wd->group_items, it);
3590 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
3591 it->item->rel = NULL;
3595 Elm_Gen_Item *it2 = NULL;
3596 Eina_List *ll = eina_list_last(it->parent->item->items);
3597 if (ll) it2 = ll->data;
3598 it->parent->item->items = eina_list_append(it->parent->item->items, it);
3599 if (!it2) it2 = it->parent;
3601 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3602 EINA_INLIST_GET(it2));
3603 it->item->rel = it2;
3604 it->item->rel->relcount++;
3606 it->item->before = EINA_FALSE;
3607 _item_queue(wd, it, NULL);
3612 elm_genlist_item_prepend(Evas_Object *obj,
3613 const Elm_Genlist_Item_Class *itc,
3615 Elm_Gen_Item *parent,
3616 Elm_Genlist_Item_Flags flags,
3618 const void *func_data)
3620 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3621 Widget_Data *wd = elm_widget_data_get(obj);
3622 if (!wd) return NULL;
3623 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3625 if (!it) return NULL;
3629 wd->group_items = eina_list_prepend(wd->group_items, it);
3630 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
3631 it->item->rel = NULL;
3635 Elm_Gen_Item *it2 = NULL;
3636 Eina_List *ll = it->parent->item->items;
3637 if (ll) it2 = ll->data;
3638 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
3639 if (!it2) it2 = it->parent;
3641 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3642 EINA_INLIST_GET(it2));
3643 it->item->rel = it2;
3644 it->item->rel->relcount++;
3646 it->item->before = EINA_TRUE;
3647 _item_queue(wd, it, NULL);
3652 elm_genlist_item_insert_after(Evas_Object *obj,
3653 const Elm_Genlist_Item_Class *itc,
3655 Elm_Gen_Item *parent,
3656 Elm_Gen_Item *after,
3657 Elm_Genlist_Item_Flags flags,
3659 const void *func_data)
3661 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3662 EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3663 Widget_Data *wd = elm_widget_data_get(obj);
3664 if (!wd) return NULL;
3665 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
3666 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3668 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3670 if (!it) return NULL;
3675 wd->group_items = eina_list_append_relative(wd->group_items, it,
3680 it->parent->item->items = eina_list_append_relative(it->parent->item->items, it,
3683 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3684 EINA_INLIST_GET(after));
3685 it->item->rel = after;
3686 it->item->rel->relcount++;
3687 it->item->before = EINA_FALSE;
3688 _item_queue(wd, it, NULL);
3693 elm_genlist_item_insert_before(Evas_Object *obj,
3694 const Elm_Genlist_Item_Class *itc,
3696 Elm_Gen_Item *parent,
3697 Elm_Gen_Item *before,
3698 Elm_Genlist_Item_Flags flags,
3700 const void *func_data)
3702 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3703 EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
3704 Widget_Data *wd = elm_widget_data_get(obj);
3705 if (!wd) return NULL;
3706 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
3707 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3709 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3711 if (!it) return NULL;
3714 if (it->group && before->group)
3715 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
3720 it->parent->item->items = eina_list_prepend_relative(it->parent->item->items, it,
3723 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3724 EINA_INLIST_GET(before));
3725 it->item->rel = before;
3726 it->item->rel->relcount++;
3727 it->item->before = EINA_TRUE;
3728 _item_queue(wd, it, NULL);
3733 elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
3734 const Elm_Genlist_Item_Class *itc,
3736 Elm_Gen_Item *parent,
3737 Elm_Genlist_Item_Flags flags,
3738 Eina_Compare_Cb comp,
3740 const void *func_data)
3742 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3743 Widget_Data *wd = elm_widget_data_get(obj);
3744 if (!wd) return NULL;
3745 Elm_Gen_Item *rel = NULL;
3746 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3748 if (!it) return NULL;
3750 wd->item_compare_cb = comp;
3757 l = eina_list_search_sorted_near_list(it->parent->item->items,
3758 _elm_genlist_item_list_compare, it,
3761 rel = eina_list_data_get(l);
3765 if (cmp_result >= 0)
3767 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
3768 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3769 it->item->before = EINA_FALSE;
3771 else if (cmp_result < 0)
3773 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
3774 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3775 it->item->before = EINA_TRUE;
3782 wd->state = eina_inlist_sorted_state_new();
3783 eina_inlist_sorted_state_init(wd->state, wd->items);
3784 wd->requeued = EINA_FALSE;
3788 wd->group_items = eina_list_append(wd->group_items, it);
3790 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
3791 _elm_genlist_item_compare, wd->state);
3793 if (EINA_INLIST_GET(it)->next)
3795 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3796 it->item->before = EINA_TRUE;
3798 else if (EINA_INLIST_GET(it)->prev)
3800 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3801 it->item->before = EINA_FALSE;
3807 it->item->rel = rel;
3808 it->item->rel->relcount++;
3811 _item_queue(wd, it, _elm_genlist_item_list_compare);
3817 elm_genlist_item_sorted_insert(Evas_Object *obj,
3818 const Elm_Genlist_Item_Class *itc,
3820 Elm_Gen_Item *parent,
3821 Elm_Genlist_Item_Flags flags,
3822 Eina_Compare_Cb comp,
3824 const void *func_data)
3826 Widget_Data *wd = elm_widget_data_get(obj);
3827 wd->item_compare_data_cb = comp;
3829 return elm_genlist_item_direct_sorted_insert(obj, itc, data, parent, flags,
3830 _elm_genlist_item_compare_data, func, func_data);
3834 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
3836 Eina_Inlist *next, *l;
3838 ELM_CHECK_WIDTYPE(obj, widtype);
3839 Widget_Data *wd = elm_widget_data_get(obj);
3842 if (!standby) wd->generation++;
3846 eina_inlist_sorted_state_free(wd->state);
3850 if (wd->walking > 0)
3855 evas_event_freeze(evas_object_evas_get(wd->obj));
3856 for (l = wd->items, next = l ? l->next : NULL;
3858 l = next, next = next ? next->next : NULL)
3860 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
3862 if (it->generation < wd->generation)
3864 Elm_Gen_Item *itn = NULL;
3866 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
3867 if (itn) itn->walking++; /* prevent early death of subitem */
3869 if (itn) itn->walking--;
3875 ecore_job_del(wd->calc_job);
3876 wd->calc_job = NULL;
3878 if (wd->selected) wd->selected = eina_list_free(wd->selected);
3879 if (wd->clear_cb) wd->clear_cb(wd);
3887 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
3888 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3890 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
3891 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
3892 evas_event_thaw(evas_object_evas_get(wd->obj));
3893 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3897 elm_genlist_clear(Evas_Object *obj)
3899 _elm_genlist_clear(obj, EINA_FALSE);
3903 elm_genlist_multi_select_set(Evas_Object *obj,
3906 ELM_CHECK_WIDTYPE(obj, widtype);
3907 Widget_Data *wd = elm_widget_data_get(obj);
3913 elm_genlist_multi_select_get(const Evas_Object *obj)
3915 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3916 Widget_Data *wd = elm_widget_data_get(obj);
3917 if (!wd) return EINA_FALSE;
3922 elm_genlist_selected_item_get(const Evas_Object *obj)
3924 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3925 Widget_Data *wd = elm_widget_data_get(obj);
3926 if (!wd) return NULL;
3927 if (wd->selected) return wd->selected->data;
3931 EAPI const Eina_List *
3932 elm_genlist_selected_items_get(const Evas_Object *obj)
3934 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3935 Widget_Data *wd = elm_widget_data_get(obj);
3936 if (!wd) return NULL;
3937 return wd->selected;
3941 elm_genlist_realized_items_get(const Evas_Object *obj)
3943 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3944 Widget_Data *wd = elm_widget_data_get(obj);
3945 Eina_List *list = NULL;
3947 Eina_Bool done = EINA_FALSE;
3948 if (!wd) return NULL;
3949 EINA_INLIST_FOREACH(wd->blocks, itb)
3957 EINA_LIST_FOREACH(itb->items, l, it)
3959 if (it->realized) list = eina_list_append(list, it);
3971 elm_genlist_at_xy_item_get(const Evas_Object *obj,
3976 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3977 Widget_Data *wd = elm_widget_data_get(obj);
3978 Evas_Coord ox, oy, ow, oh;
3981 if (!wd) return NULL;
3982 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
3984 EINA_INLIST_FOREACH(wd->blocks, itb)
3989 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
3990 oy + itb->y - itb->wd->pan_y,
3991 itb->w, itb->h, x, y, 1, 1))
3993 EINA_LIST_FOREACH(itb->items, l, it)
3995 Evas_Coord itx, ity;
3997 itx = ox + itb->x + it->x - itb->wd->pan_x;
3998 ity = oy + itb->y + it->y - itb->wd->pan_y;
3999 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4003 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4004 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4010 lasty = ity + it->item->h;
4015 if (y > lasty) *posret = 1;
4022 elm_genlist_first_item_get(const Evas_Object *obj)
4024 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4025 Widget_Data *wd = elm_widget_data_get(obj);
4026 if (!wd) return NULL;
4027 if (!wd->items) return NULL;
4028 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4029 while ((it) && (it->generation < wd->generation))
4030 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4035 elm_genlist_last_item_get(const Evas_Object *obj)
4037 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4038 Widget_Data *wd = elm_widget_data_get(obj);
4039 if (!wd) return NULL;
4040 if (!wd->items) return NULL;
4041 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4042 while ((it) && (it->generation < wd->generation))
4043 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4048 elm_genlist_item_next_get(const Elm_Gen_Item *it)
4050 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4053 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4054 if ((it) && (it->generation == it->wd->generation)) break;
4056 return (Elm_Gen_Item *)it;
4060 elm_genlist_item_prev_get(const Elm_Gen_Item *it)
4062 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4065 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4066 if ((it) && (it->generation == it->wd->generation)) break;
4068 return (Elm_Gen_Item *)it;
4072 elm_genlist_item_genlist_get(const Elm_Gen_Item *it)
4074 return _elm_genlist_item_widget_get(it);
4078 elm_genlist_item_parent_get(const Elm_Gen_Item *it)
4080 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4085 elm_genlist_item_subitems_clear(Elm_Gen_Item *it)
4087 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4088 Eina_List *tl = NULL, *l;
4091 EINA_LIST_FOREACH(it->item->items, l, it2)
4092 tl = eina_list_append(tl, it2);
4093 EINA_LIST_FREE(tl, it2)
4094 elm_genlist_item_del(it2);
4098 elm_genlist_item_selected_set(Elm_Gen_Item *it,
4101 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4102 Widget_Data *wd = it->wd;
4104 if ((it->generation < wd->generation) || (it->disabled)) return;
4105 selected = !!selected;
4106 if (it->selected == selected) return;
4112 while (wd->selected)
4114 if (it->unhighlight_cb) it->unhighlight_cb(wd->selected->data);
4115 it->unsel_cb(wd->selected->data);
4118 it->highlight_cb(it);
4122 if (it->unhighlight_cb) it->unhighlight_cb(it);
4127 elm_genlist_item_selected_get(const Elm_Gen_Item *it)
4129 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4130 return it->selected;
4134 elm_genlist_item_expanded_set(Elm_Gen_Item *it,
4137 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4138 if (it->item->expanded == expanded) return;
4139 it->item->expanded = expanded;
4140 it->wd->expanded_item = it;
4141 if (it->item->expanded)
4144 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
4145 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
4146 it->wd->auto_scroll_enabled = EINA_TRUE;
4151 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
4152 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
4153 it->wd->auto_scroll_enabled = EINA_FALSE;
4158 elm_genlist_item_expanded_get(const Elm_Gen_Item *it)
4160 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4161 return it->item->expanded;
4165 elm_genlist_item_expanded_depth_get(const Elm_Gen_Item *it)
4167 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, 0);
4168 return it->item->expanded_depth;
4172 elm_genlist_item_disabled_set(Elm_Gen_Item *it,
4175 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4178 if (it->disabled == disabled) return;
4179 if (it->generation < it->wd->generation) return;
4180 it->disabled = !!disabled;
4182 elm_genlist_item_selected_set(it, EINA_FALSE);
4186 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4188 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
4189 EINA_LIST_FOREACH(it->content_objs, l, obj)
4190 elm_widget_disabled_set(obj, disabled);
4195 elm_genlist_item_disabled_get(const Elm_Gen_Item *it)
4197 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4198 if (it->generation < it->wd->generation) return EINA_FALSE;
4199 return it->disabled;
4203 elm_genlist_item_display_only_set(Elm_Gen_Item *it,
4204 Eina_Bool display_only)
4206 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4207 if (it->display_only == display_only) return;
4208 if (it->generation < it->wd->generation) return;
4209 it->display_only = display_only;
4210 it->item->mincalcd = EINA_FALSE;
4211 it->item->updateme = EINA_TRUE;
4212 if (it->item->block) it->item->block->updateme = EINA_TRUE;
4213 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4214 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4218 elm_genlist_item_display_only_get(const Elm_Gen_Item *it)
4220 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4221 if (it->generation < it->wd->generation) return EINA_FALSE;
4222 return it->display_only;
4226 elm_genlist_item_show(Elm_Gen_Item *it)
4228 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4229 Evas_Coord gith = 0;
4230 if (it->generation < it->wd->generation) return;
4231 if ((it->item->queued) || (!it->item->mincalcd))
4233 it->wd->show_item = it;
4234 it->wd->bring_in = EINA_TRUE;
4235 it->item->showme = EINA_TRUE;
4238 if (it->wd->show_item)
4240 it->wd->show_item->item->showme = EINA_FALSE;
4241 it->wd->show_item = NULL;
4243 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4244 gith = it->item->group_item->item->h;
4245 elm_smart_scroller_child_region_show(it->wd->scr,
4246 it->x + it->item->block->x,
4247 it->y + it->item->block->y - gith,
4248 it->item->block->w, it->item->h);
4252 elm_genlist_item_promote(Elm_Gen_Item *it)
4254 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4255 if (it->generation < it->wd->generation) return;
4256 _item_move_before(it, elm_genlist_first_item_get(WIDGET(it)));
4260 elm_genlist_item_demote(Elm_Gen_Item *it)
4262 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4263 if (it->generation < it->wd->generation) return;
4264 _item_move_after(it, elm_genlist_last_item_get(WIDGET(it)));
4268 elm_genlist_item_bring_in(Elm_Gen_Item *it)
4270 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4271 Evas_Coord gith = 0;
4272 if (it->generation < it->wd->generation) return;
4273 if ((it->item->queued) || (!it->item->mincalcd))
4275 it->wd->show_item = it;
4276 it->wd->bring_in = EINA_TRUE;
4277 it->item->showme = EINA_TRUE;
4280 if (it->wd->show_item)
4282 it->wd->show_item->item->showme = EINA_FALSE;
4283 it->wd->show_item = NULL;
4285 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4286 gith = it->item->group_item->item->h;
4287 elm_smart_scroller_region_bring_in(it->wd->scr,
4288 it->x + it->item->block->x,
4289 it->y + it->item->block->y - gith,
4290 it->item->block->w, it->item->h);
4294 elm_genlist_item_top_show(Elm_Gen_Item *it)
4296 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4298 Evas_Coord gith = 0;
4300 if (it->generation < it->wd->generation) return;
4301 if ((it->item->queued) || (!it->item->mincalcd))
4303 it->wd->show_item = it;
4304 it->wd->bring_in = EINA_TRUE;
4305 it->item->showme = EINA_TRUE;
4308 if (it->wd->show_item)
4310 it->wd->show_item->item->showme = EINA_FALSE;
4311 it->wd->show_item = NULL;
4313 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4314 if (it->item->group_item) gith = it->item->group_item->item->h;
4315 elm_smart_scroller_child_region_show(it->wd->scr,
4316 it->x + it->item->block->x,
4317 it->y + it->item->block->y - gith,
4318 it->item->block->w, oh);
4322 elm_genlist_item_top_bring_in(Elm_Gen_Item *it)
4324 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4326 Evas_Coord gith = 0;
4328 if (it->generation < it->wd->generation) return;
4329 if ((it->item->queued) || (!it->item->mincalcd))
4331 it->wd->show_item = it;
4332 it->wd->bring_in = EINA_TRUE;
4333 it->item->showme = EINA_TRUE;
4336 if (it->wd->show_item)
4338 it->wd->show_item->item->showme = EINA_FALSE;
4339 it->wd->show_item = NULL;
4341 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4342 if (it->item->group_item) gith = it->item->group_item->item->h;
4343 elm_smart_scroller_region_bring_in(it->wd->scr,
4344 it->x + it->item->block->x,
4345 it->y + it->item->block->y - gith,
4346 it->item->block->w, oh);
4350 elm_genlist_item_middle_show(Elm_Gen_Item *it)
4352 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4355 if (it->generation < it->wd->generation) return;
4356 if ((it->item->queued) || (!it->item->mincalcd))
4358 it->wd->show_item = it;
4359 it->wd->bring_in = EINA_TRUE;
4360 it->item->showme = EINA_TRUE;
4363 if (it->wd->show_item)
4365 it->wd->show_item->item->showme = EINA_FALSE;
4366 it->wd->show_item = NULL;
4368 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4369 elm_smart_scroller_child_region_show(it->wd->scr,
4370 it->x + it->item->block->x,
4371 it->y + it->item->block->y - oh / 2 +
4372 it->item->h / 2, it->item->block->w, oh);
4376 elm_genlist_item_middle_bring_in(Elm_Gen_Item *it)
4378 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4381 if (it->generation < it->wd->generation) return;
4382 if ((it->item->queued) || (!it->item->mincalcd))
4384 it->wd->show_item = it;
4385 it->wd->bring_in = EINA_TRUE;
4386 it->item->showme = EINA_TRUE;
4389 if (it->wd->show_item)
4391 it->wd->show_item->item->showme = EINA_FALSE;
4392 it->wd->show_item = NULL;
4394 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4395 elm_smart_scroller_region_bring_in(it->wd->scr,
4396 it->x + it->item->block->x,
4397 it->y + it->item->block->y - oh / 2 + it->item->h / 2,
4398 it->item->block->w, oh);
4402 elm_genlist_item_del(Elm_Gen_Item *it)
4404 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4405 if ((it->relcount > 0) || (it->walking > 0))
4407 elm_genlist_item_subitems_clear(it);
4408 if (it->wd->show_item == it) it->wd->show_item = NULL;
4409 _elm_genlist_item_del_notserious(it);
4410 if (it->item->block)
4412 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
4413 it->item->block->changed = EINA_TRUE;
4414 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
4415 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
4419 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
4428 elm_genlist_item_data_set(Elm_Gen_Item *it,
4431 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4432 elm_widget_item_data_set(it, data);
4436 elm_genlist_item_data_get(const Elm_Gen_Item *it)
4438 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4439 return elm_widget_item_data_get(it);
4443 elm_genlist_item_icons_orphan(Elm_Gen_Item *it)
4445 elm_genlist_item_contents_orphan(it);
4449 elm_genlist_item_contents_orphan(Elm_Gen_Item *it)
4451 Evas_Object *content;
4452 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4453 EINA_LIST_FREE(it->content_objs, content)
4455 elm_widget_sub_object_del(WIDGET(it), content);
4456 evas_object_smart_member_del(content);
4457 evas_object_hide(content);
4461 EAPI const Evas_Object *
4462 elm_genlist_item_object_get(const Elm_Gen_Item *it)
4464 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4469 elm_genlist_item_update(Elm_Gen_Item *it)
4471 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4472 if (!it->item->block) return;
4473 if (it->generation < it->wd->generation) return;
4474 it->item->mincalcd = EINA_FALSE;
4475 it->item->updateme = EINA_TRUE;
4476 it->item->block->updateme = EINA_TRUE;
4477 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4478 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4482 elm_genlist_item_fields_update(Elm_Genlist_Item *it,
4484 Elm_Genlist_Item_Field_Flags itf)
4486 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4487 if (!it->item->block) return;
4488 if (it->generation < it->wd->generation) return;
4490 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_LABEL))
4491 _item_label_realize(it, it->base.view, &it->labels, parts);
4492 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
4494 it->content_objs = _item_content_unrealize(it, it->base.view,
4495 &it->contents, parts);
4496 it->content_objs = _item_content_realize(it, it->base.view,
4497 &it->contents, parts);
4499 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
4500 _item_state_realize(it, it->base.view, &it->states, parts);
4504 elm_genlist_item_item_class_update(Elm_Gen_Item *it,
4505 const Elm_Genlist_Item_Class *itc)
4507 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4508 if (!it->item->block) return;
4509 EINA_SAFETY_ON_NULL_RETURN(itc);
4510 if (it->generation < it->wd->generation) return;
4512 it->item->nocache = EINA_TRUE;
4513 elm_genlist_item_update(it);
4516 EAPI const Elm_Genlist_Item_Class *
4517 elm_genlist_item_item_class_get(const Elm_Gen_Item *it)
4519 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4520 if (it->generation < it->wd->generation) return NULL;
4524 static Evas_Object *
4525 _elm_genlist_item_label_create(void *data,
4526 Evas_Object *obj __UNUSED__,
4527 Evas_Object *tooltip,
4528 void *it __UNUSED__)
4530 Evas_Object *label = elm_label_add(tooltip);
4533 elm_object_style_set(label, "tooltip");
4534 elm_object_text_set(label, data);
4539 _elm_genlist_item_label_del_cb(void *data,
4540 Evas_Object *obj __UNUSED__,
4541 void *event_info __UNUSED__)
4543 eina_stringshare_del(data);
4547 elm_genlist_item_tooltip_text_set(Elm_Gen_Item *it,
4550 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4551 text = eina_stringshare_add(text);
4552 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
4554 _elm_genlist_item_label_del_cb);
4558 elm_genlist_item_tooltip_content_cb_set(Elm_Gen_Item *it,
4559 Elm_Tooltip_Item_Content_Cb func,
4561 Evas_Smart_Cb del_cb)
4563 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, error);
4565 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4568 if (it->tooltip.del_cb)
4569 it->tooltip.del_cb((void *)it->tooltip.data,
4572 it->tooltip.content_cb = func;
4573 it->tooltip.data = data;
4574 it->tooltip.del_cb = del_cb;
4578 elm_widget_item_tooltip_content_cb_set(it,
4579 it->tooltip.content_cb,
4580 it->tooltip.data, NULL);
4581 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4582 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
4588 if (del_cb) del_cb((void *)data, NULL, NULL);
4592 elm_genlist_item_tooltip_unset(Elm_Gen_Item *it)
4594 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4595 if ((VIEW(it)) && (it->tooltip.content_cb))
4596 elm_widget_item_tooltip_unset(it);
4598 if (it->tooltip.del_cb)
4599 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4600 it->tooltip.del_cb = NULL;
4601 it->tooltip.content_cb = NULL;
4602 it->tooltip.data = NULL;
4603 it->tooltip.free_size = EINA_FALSE;
4604 if (it->tooltip.style)
4605 elm_genlist_item_tooltip_style_set(it, NULL);
4609 elm_genlist_item_tooltip_style_set(Elm_Gen_Item *it,
4612 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4613 eina_stringshare_replace(&it->tooltip.style, style);
4614 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4618 elm_genlist_item_tooltip_style_get(const Elm_Gen_Item *it)
4620 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4621 return it->tooltip.style;
4625 elm_genlist_item_tooltip_window_mode_set(Elm_Gen_Item *it, Eina_Bool disable)
4627 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4628 it->tooltip.free_size = disable;
4629 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
4634 elm_genlist_item_tooltip_window_mode_get(const Elm_Gen_Item *it)
4636 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4637 return it->tooltip.free_size;
4641 elm_genlist_item_cursor_set(Elm_Gen_Item *it,
4644 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4645 eina_stringshare_replace(&it->mouse_cursor, cursor);
4646 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4650 elm_genlist_item_cursor_get(const Elm_Gen_Item *it)
4652 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4653 return elm_widget_item_cursor_get(it);
4657 elm_genlist_item_cursor_unset(Elm_Gen_Item *it)
4659 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4660 if (!it->mouse_cursor)
4664 elm_widget_item_cursor_unset(it);
4666 eina_stringshare_del(it->mouse_cursor);
4667 it->mouse_cursor = NULL;
4671 elm_genlist_item_cursor_style_set(Elm_Gen_Item *it,
4674 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4675 elm_widget_item_cursor_style_set(it, style);
4679 elm_genlist_item_cursor_style_get(const Elm_Gen_Item *it)
4681 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4682 return elm_widget_item_cursor_style_get(it);
4686 elm_genlist_item_cursor_engine_only_set(Elm_Gen_Item *it,
4687 Eina_Bool engine_only)
4689 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4690 elm_widget_item_cursor_engine_only_set(it, engine_only);
4694 elm_genlist_item_cursor_engine_only_get(const Elm_Gen_Item *it)
4696 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4697 return elm_widget_item_cursor_engine_only_get(it);
4701 elm_genlist_horizontal_set(Evas_Object *obj,
4704 ELM_CHECK_WIDTYPE(obj, widtype);
4705 Widget_Data *wd = elm_widget_data_get(obj);
4707 if (wd->mode == mode) return;
4713 elm_genlist_horizontal_mode_set(Evas_Object *obj,
4716 elm_genlist_horizontal_set(obj, mode);
4720 elm_genlist_horizontal_get(const Evas_Object *obj)
4722 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4723 Widget_Data *wd = elm_widget_data_get(obj);
4724 if (!wd) return ELM_LIST_LAST;
4729 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4731 return elm_genlist_horizontal_get(obj);
4735 elm_genlist_always_select_mode_set(Evas_Object *obj,
4736 Eina_Bool always_select)
4738 ELM_CHECK_WIDTYPE(obj, widtype);
4739 Widget_Data *wd = elm_widget_data_get(obj);
4741 wd->always_select = always_select;
4745 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4747 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4748 Widget_Data *wd = elm_widget_data_get(obj);
4749 if (!wd) return EINA_FALSE;
4750 return wd->always_select;
4754 elm_genlist_no_select_mode_set(Evas_Object *obj,
4755 Eina_Bool no_select)
4757 ELM_CHECK_WIDTYPE(obj, widtype);
4758 Widget_Data *wd = elm_widget_data_get(obj);
4760 wd->no_select = no_select;
4764 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4766 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4767 Widget_Data *wd = elm_widget_data_get(obj);
4768 if (!wd) return EINA_FALSE;
4769 return wd->no_select;
4773 elm_genlist_compress_mode_set(Evas_Object *obj,
4776 ELM_CHECK_WIDTYPE(obj, widtype);
4777 Widget_Data *wd = elm_widget_data_get(obj);
4779 wd->compress = compress;
4780 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
4784 elm_genlist_compress_mode_get(const Evas_Object *obj)
4786 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4787 Widget_Data *wd = elm_widget_data_get(obj);
4788 if (!wd) return EINA_FALSE;
4789 return wd->compress;
4793 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
4794 Eina_Bool height_for_width)
4796 ELM_CHECK_WIDTYPE(obj, widtype);
4797 Widget_Data *wd = elm_widget_data_get(obj);
4799 wd->height_for_width = !!height_for_width;
4800 if (wd->height_for_width)
4802 elm_genlist_homogeneous_set(obj, EINA_FALSE);
4803 elm_genlist_compress_mode_set(obj, EINA_TRUE);
4808 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
4810 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4811 Widget_Data *wd = elm_widget_data_get(obj);
4812 if (!wd) return EINA_FALSE;
4813 return wd->height_for_width;
4817 elm_genlist_bounce_set(Evas_Object *obj,
4821 ELM_CHECK_WIDTYPE(obj, widtype);
4822 Widget_Data *wd = elm_widget_data_get(obj);
4824 elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
4825 wd->h_bounce = h_bounce;
4826 wd->v_bounce = v_bounce;
4830 elm_genlist_bounce_get(const Evas_Object *obj,
4831 Eina_Bool *h_bounce,
4832 Eina_Bool *v_bounce)
4834 ELM_CHECK_WIDTYPE(obj, widtype);
4835 Widget_Data *wd = elm_widget_data_get(obj);
4837 if (h_bounce) *h_bounce = wd->h_bounce;
4838 if (v_bounce) *v_bounce = wd->v_bounce;
4842 elm_genlist_homogeneous_set(Evas_Object *obj,
4843 Eina_Bool homogeneous)
4845 ELM_CHECK_WIDTYPE(obj, widtype);
4846 Widget_Data *wd = elm_widget_data_get(obj);
4848 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
4849 wd->homogeneous = homogeneous;
4853 elm_genlist_homogeneous_get(const Evas_Object *obj)
4855 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4856 Widget_Data *wd = elm_widget_data_get(obj);
4857 if (!wd) return EINA_FALSE;
4858 return wd->homogeneous;
4862 elm_genlist_block_count_set(Evas_Object *obj,
4865 ELM_CHECK_WIDTYPE(obj, widtype);
4866 Widget_Data *wd = elm_widget_data_get(obj);
4868 wd->max_items_per_block = n;
4869 wd->item_cache_max = wd->max_items_per_block * 2;
4870 _item_cache_clean(wd);
4874 elm_genlist_block_count_get(const Evas_Object *obj)
4876 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4877 Widget_Data *wd = elm_widget_data_get(obj);
4879 return wd->max_items_per_block;
4883 elm_genlist_longpress_timeout_set(Evas_Object *obj,
4886 ELM_CHECK_WIDTYPE(obj, widtype);
4887 Widget_Data *wd = elm_widget_data_get(obj);
4889 wd->longpress_timeout = timeout;
4893 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
4895 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4896 Widget_Data *wd = elm_widget_data_get(obj);
4898 return wd->longpress_timeout;
4902 elm_genlist_scroller_policy_set(Evas_Object *obj,
4903 Elm_Scroller_Policy policy_h,
4904 Elm_Scroller_Policy policy_v)
4906 ELM_CHECK_WIDTYPE(obj, widtype);
4907 Widget_Data *wd = elm_widget_data_get(obj);
4908 if ((!wd) || (!wd->scr)) return;
4909 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4910 (policy_v >= ELM_SCROLLER_POLICY_LAST))
4912 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
4916 elm_genlist_scroller_policy_get(const Evas_Object *obj,
4917 Elm_Scroller_Policy *policy_h,
4918 Elm_Scroller_Policy *policy_v)
4920 ELM_CHECK_WIDTYPE(obj, widtype);
4921 Widget_Data *wd = elm_widget_data_get(obj);
4922 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
4923 if ((!wd) || (!wd->scr)) return;
4924 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
4925 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
4926 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
4930 elm_genlist_realized_items_update(Evas_Object *obj)
4932 ELM_CHECK_WIDTYPE(obj, widtype);
4934 Eina_List *list, *l;
4937 list = elm_genlist_realized_items_get(obj);
4938 EINA_LIST_FOREACH(list, l, it)
4939 elm_genlist_item_update(it);
4943 elm_genlist_item_mode_set(Elm_Gen_Item *it,
4944 const char *mode_type,
4947 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4948 Widget_Data *wd = it->wd;
4953 if (!mode_type) return;
4954 if ((it->generation < it->wd->generation) || (it->disabled)) return;
4956 if ((wd->mode_item == it) &&
4957 (!strcmp(mode_type, wd->mode_type)) &&
4960 if (!wd->mode_item_style) return;
4961 it->mode_set = mode_set;
4965 EINA_LIST_FOREACH(wd->selected, l, it2)
4967 elm_genlist_item_selected_set(it2, EINA_FALSE);
4971 it2 = elm_genlist_selected_item_get(wd->obj);
4972 if ((it2) && (it2->realized))
4973 elm_genlist_item_selected_set(it2, EINA_FALSE);
4976 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
4978 ((it == wd->mode_item) && (!mode_set)))
4979 _item_mode_unset(wd);
4981 eina_stringshare_replace(&wd->mode_type, mode_type);
4982 if (mode_set) _item_mode_set(it);
4987 elm_genlist_mode_item_style_get(const Evas_Object *obj)
4989 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4990 Widget_Data *wd = elm_widget_data_get(obj);
4991 if (!wd) return NULL;
4992 return wd->mode_item_style;
4996 elm_genlist_mode_item_style_set(Evas_Object *obj, const char *style)
4998 ELM_CHECK_WIDTYPE(obj, widtype);
4999 Widget_Data *wd = elm_widget_data_get(obj);
5001 if ((style == wd->mode_item_style) || (style && wd->mode_item_style &&
5002 (!strcmp(style, wd->mode_item_style))))
5004 eina_stringshare_replace(&wd->mode_item_style, style);
5005 elm_genlist_realized_items_update(obj);
5009 elm_genlist_mode_get(const Evas_Object *obj)
5011 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5012 Widget_Data *wd = elm_widget_data_get(obj);
5013 if (!wd) return NULL;
5014 return wd->mode_type;
5017 EAPI const Elm_Gen_Item *
5018 elm_genlist_mode_item_get(const Evas_Object *obj)
5020 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5021 Widget_Data *wd = elm_widget_data_get(obj);
5022 if (!wd) return NULL;
5023 return wd->mode_item;
5027 elm_genlist_reorder_mode_set(Evas_Object *obj,
5028 Eina_Bool reorder_mode)
5030 ELM_CHECK_WIDTYPE(obj, widtype);
5031 Widget_Data *wd = elm_widget_data_get(obj);
5033 wd->reorder_mode = reorder_mode;
5037 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5039 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5040 Widget_Data *wd = elm_widget_data_get(obj);
5041 if (!wd) return EINA_FALSE;
5042 return wd->reorder_mode;
5045 /* for gengrid as of now */
5047 _elm_genlist_page_relative_set(Evas_Object *obj,
5051 Evas_Coord pagesize_h;
5052 Evas_Coord pagesize_v;
5054 ELM_CHECK_WIDTYPE(obj, widtype);
5055 Widget_Data *wd = elm_widget_data_get(obj);
5058 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5059 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5063 /* for gengrid as of now */
5065 _elm_genlist_page_relative_get(const Evas_Object *obj,
5069 ELM_CHECK_WIDTYPE(obj, widtype);
5070 Widget_Data *wd = elm_widget_data_get(obj);
5073 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5076 /* for gengrid as of now */
5078 _elm_genlist_page_size_set(Evas_Object *obj,
5079 Evas_Coord h_pagesize,
5080 Evas_Coord v_pagesize)
5085 ELM_CHECK_WIDTYPE(obj, widtype);
5086 Widget_Data *wd = elm_widget_data_get(obj);
5088 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5089 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5093 /* for gengrid as of now */
5095 _elm_genlist_current_page_get(const Evas_Object *obj,
5099 ELM_CHECK_WIDTYPE(obj, widtype);
5100 Widget_Data *wd = elm_widget_data_get(obj);
5103 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5106 /* for gengrid as of now */
5108 _elm_genlist_last_page_get(const Evas_Object *obj,
5112 ELM_CHECK_WIDTYPE(obj, widtype);
5113 Widget_Data *wd = elm_widget_data_get(obj);
5116 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5119 /* for gengrid as of now */
5121 _elm_genlist_page_show(const Evas_Object *obj,
5125 ELM_CHECK_WIDTYPE(obj, widtype);
5126 Widget_Data *wd = elm_widget_data_get(obj);
5129 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5132 /* for gengrid as of now */
5134 _elm_genlist_page_bring_in(const Evas_Object *obj,
5138 ELM_CHECK_WIDTYPE(obj, widtype);
5139 Widget_Data *wd = elm_widget_data_get(obj);
5142 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5146 _elm_genlist_item_widget_get(const Elm_Gen_Item *it)
5148 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
5153 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5156 Evas_Object *content;
5158 if (!it->realized) return;
5159 if (it->wd->reorder_it == it) return;
5160 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5162 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5165 ecore_timer_del(it->long_timer);
5166 it->long_timer = NULL;
5169 elm_widget_stringlist_free(it->labels);
5171 elm_widget_stringlist_free(it->contents);
5172 it->contents = NULL;
5173 elm_widget_stringlist_free(it->states);
5176 EINA_LIST_FREE(it->content_objs, content)
5177 evas_object_del(content);
5179 it->unrealize_cb(it);
5181 it->realized = EINA_FALSE;
5182 it->want_unrealize = EINA_FALSE;
5183 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5184 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5188 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5190 elm_widget_item_pre_notify_del(it);
5191 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5192 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5194 if (it->itc->func.del)
5195 it->itc->func.del((void *)it->base.data, WIDGET(it));
5199 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5201 _elm_genlist_item_del_notserious(it);
5202 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5203 if (it->tooltip.del_cb)
5204 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5205 it->wd->walking -= it->walking;
5206 if (it->long_timer) ecore_timer_del(it->long_timer);
5208 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5210 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5211 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5214 elm_widget_item_del(it);