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,
1760 const char *treesize;
1763 Item_Cache *itc = NULL;
1765 if (it->generation < it->wd->generation) return;
1766 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1769 if (it->item->order_num_in != in)
1771 it->item->order_num_in = in;
1772 _elm_genlist_item_odd_even_update(it);
1773 _elm_genlist_item_state_update(it, NULL);
1775 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1776 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1779 it->item->order_num_in = in;
1781 if (it->item->nocache)
1782 it->item->nocache = EINA_FALSE;
1784 itc = _item_cache_find(it);
1787 VIEW(it) = itc->base_view;
1788 itc->base_view = NULL;
1789 it->spacer = itc->spacer;
1794 const char *stacking_even;
1795 const char *stacking;
1797 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1798 edje_object_scale_set(VIEW(it),
1799 elm_widget_scale_get(WIDGET(it)) *
1800 _elm_config->scale);
1801 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
1802 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1804 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
1805 strncpy(buf, "tree", sizeof(buf));
1806 else strncpy(buf, "item", sizeof(buf));
1807 if (it->wd->compress)
1808 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1810 strncat(buf, "/", sizeof(buf) - strlen(buf));
1811 strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1813 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
1814 elm_widget_style_get(WIDGET(it)));
1816 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1817 if (!stacking_even) stacking_even = "above";
1818 it->item->stacking_even = !!strcmp("above", stacking_even);
1820 stacking = edje_object_data_get(VIEW(it), "stacking");
1821 if (!stacking) stacking = "yes";
1822 it->item->nostacking = !!strcmp("yes", stacking);
1824 edje_object_mirrored_set(VIEW(it),
1825 elm_widget_mirrored_get(WIDGET(it)));
1827 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1828 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1829 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1832 _elm_genlist_item_odd_even_update(it);
1834 treesize = edje_object_data_get(VIEW(it), "treesize");
1835 if (treesize) tsize = atoi(treesize);
1836 evas_object_size_hint_min_set(it->spacer,
1837 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
1838 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1841 edje_object_signal_callback_add(VIEW(it),
1842 "elm,action,expand,toggle",
1843 "elm", _signal_expand_toggle, it);
1844 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
1845 "elm", _signal_expand, it);
1846 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
1847 "elm", _signal_contract, it);
1848 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
1850 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
1852 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1854 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
1856 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
1858 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
1861 _elm_genlist_item_state_update(it, itc);
1864 if ((calc) && (it->wd->homogeneous) &&
1865 ((it->wd->item_width) ||
1866 ((it->wd->item_width) && (it->wd->group_item_width))))
1868 /* homogenous genlist shortcut */
1869 if (!it->item->mincalcd)
1873 it->item->w = it->item->minw = it->wd->group_item_width;
1874 it->item->h = it->item->minh = it->wd->group_item_height;
1878 it->item->w = it->item->minw = it->wd->item_width;
1879 it->item->h = it->item->minh = it->wd->item_height;
1881 it->item->mincalcd = EINA_TRUE;
1886 /* FIXME: If you see that assert, please notify us and we
1887 will clean our mess */
1888 assert(eina_list_count(it->content_objs) == 0);
1890 _item_label_realize(it, VIEW(it), &it->labels, NULL);
1891 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
1892 _item_state_realize(it, VIEW(it), &it->states, NULL);
1894 if (!it->item->mincalcd)
1896 Evas_Coord mw = -1, mh = -1;
1898 if (!it->display_only)
1899 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1900 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
1901 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
1903 if (!it->display_only)
1904 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1905 it->item->w = it->item->minw = mw;
1906 it->item->h = it->item->minh = mh;
1907 it->item->mincalcd = EINA_TRUE;
1909 if ((!it->wd->group_item_width) && (it->group))
1911 it->wd->group_item_width = mw;
1912 it->wd->group_item_height = mh;
1914 else if ((!it->wd->item_width) && (it->item->flags == ELM_GENLIST_ITEM_NONE))
1916 it->wd->item_width = mw;
1917 it->wd->item_height = mh;
1920 if (!calc) evas_object_show(VIEW(it));
1923 if (it->tooltip.content_cb)
1925 elm_widget_item_tooltip_content_cb_set(it,
1926 it->tooltip.content_cb,
1927 it->tooltip.data, NULL);
1928 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1929 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1932 if (it->mouse_cursor)
1933 elm_widget_item_cursor_set(it, it->mouse_cursor);
1935 it->realized = EINA_TRUE;
1936 it->want_unrealize = EINA_FALSE;
1938 if (itc) _item_cache_free(itc);
1939 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1940 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1942 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1943 edje_object_message_signal_process(VIEW(it));
1947 _item_unrealize_cb(Elm_Gen_Item *it)
1949 if (it->item->nocache)
1951 evas_object_del(VIEW(it));
1953 evas_object_del(it->spacer);
1958 edje_object_mirrored_set(VIEW(it),
1959 elm_widget_mirrored_get(WIDGET(it)));
1960 edje_object_scale_set(VIEW(it),
1961 elm_widget_scale_get(WIDGET(it))
1962 * _elm_config->scale);
1963 _item_cache_add(it);
1966 _mode_item_unrealize(it);
1968 it->realized = EINA_FALSE;
1969 it->want_unrealize = EINA_FALSE;
1973 _item_block_recalc(Item_Block *itb,
1979 Evas_Coord minw = 0, minh = 0;
1980 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
1983 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
1985 EINA_LIST_FOREACH(itb->items, l, it)
1987 if (it->generation < it->wd->generation) continue;
1988 showme |= it->item->showme;
1993 if (!it->item->mincalcd) changed = EINA_TRUE;
1996 _item_realize(it, in, EINA_TRUE);
1997 _elm_genlist_item_unrealize(it, EINA_TRUE);
2002 _item_realize(it, in, EINA_TRUE);
2003 _elm_genlist_item_unrealize(it, EINA_TRUE);
2007 _item_realize(it, in, EINA_FALSE);
2008 minh += it->item->minh;
2009 if (minw < it->item->minw) minw = it->item->minw;
2017 itb->changed = EINA_FALSE;
2018 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2019 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2024 _item_block_realize(Item_Block *itb)
2026 if (itb->realized) return;
2027 itb->realized = EINA_TRUE;
2028 itb->want_unrealize = EINA_FALSE;
2032 _item_block_unrealize(Item_Block *itb)
2036 Eina_Bool dragging = EINA_FALSE;
2038 if (!itb->realized) return;
2039 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2040 EINA_LIST_FOREACH(itb->items, l, it)
2046 dragging = EINA_TRUE;
2047 it->want_unrealize = EINA_TRUE;
2050 _elm_genlist_item_unrealize(it, EINA_FALSE);
2055 itb->realized = EINA_FALSE;
2056 itb->want_unrealize = EINA_TRUE;
2059 itb->want_unrealize = EINA_FALSE;
2060 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2061 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2065 _get_space_for_reorder_item(Elm_Gen_Item *it)
2067 Evas_Coord rox, roy, row, roh, oy, oh;
2068 Eina_Bool top = EINA_FALSE;
2069 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2070 if (!reorder_it) return 0;
2072 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2073 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2075 if ((it->wd->reorder_start_y < it->item->block->y) &&
2076 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2078 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2079 if (it->item->block->count == 1)
2080 it->wd->reorder_rel = it;
2082 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2083 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2085 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2088 it->item->block->reorder_offset = 0;
2090 it->item->scrl_y += it->item->block->reorder_offset;
2092 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2093 rox, roy + (roh / 2), row, 1));
2096 it->wd->reorder_rel = it;
2097 it->item->scrl_y += it->wd->reorder_it->item->h;
2098 return it->wd->reorder_it->item->h;
2105 _reorder_move_animator_cb(void *data)
2107 Elm_Gen_Item *it = data;
2108 Eina_Bool down = EINA_FALSE;
2110 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2112 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2114 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2117 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2118 if (diff > it->item->h) y = diff / 2;
2120 if (it->item->old_scrl_y < it->item->scrl_y)
2122 it->item->old_scrl_y += y;
2125 else if (it->item->old_scrl_y > it->item->scrl_y)
2127 it->item->old_scrl_y -= y;
2130 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2131 _group_items_recalc(it->wd);
2133 if ((it->wd->reorder_pan_move) ||
2134 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2135 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2137 it->item->old_scrl_y = it->item->scrl_y;
2138 it->item->move_effect_enabled = EINA_FALSE;
2139 it->wd->reorder_move_animator = NULL;
2140 return ECORE_CALLBACK_CANCEL;
2142 return ECORE_CALLBACK_RENEW;
2146 _item_position(Elm_Gen_Item *it,
2154 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2155 evas_object_resize(view, it->item->w, it->item->h);
2156 evas_object_move(view, it_x, it_y);
2157 evas_object_show(view);
2158 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2159 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2163 _item_block_position(Item_Block *itb,
2169 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2170 Eina_Bool vis = EINA_FALSE;
2172 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2173 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2174 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2176 EINA_LIST_FOREACH(itb->items, l, it)
2178 if (it->generation < it->wd->generation) continue;
2179 else if (it->wd->reorder_it == it) continue;
2182 it->item->w = itb->w;
2183 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2184 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2186 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2187 cvx, cvy, cvw, cvh));
2190 if ((itb->realized) && (!it->realized))
2192 if (vis) _item_realize(it, in, EINA_FALSE);
2198 if (it->wd->reorder_mode)
2199 y += _get_space_for_reorder_item(it);
2200 git = it->item->group_item;
2203 if (git->item->scrl_y < oy)
2204 git->item->scrl_y = oy;
2205 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2206 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2207 git->item->want_realize = EINA_TRUE;
2209 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2211 if (!it->item->move_effect_enabled)
2213 it->item->move_effect_enabled = EINA_TRUE;
2214 it->wd->reorder_move_animator =
2216 _reorder_move_animator_cb, it);
2219 if (!it->item->move_effect_enabled)
2221 if (it->item->mode_view)
2222 _item_position(it, it->item->mode_view, it->item->scrl_x,
2225 _item_position(it, VIEW(it), it->item->scrl_x,
2227 it->item->old_scrl_y = it->item->scrl_y;
2232 if (!it->dragging) _elm_genlist_item_unrealize(it, EINA_FALSE);
2239 if (vis) it->item->want_realize = EINA_TRUE;
2243 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2244 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2248 _group_items_recalc(void *data)
2250 Widget_Data *wd = data;
2254 evas_event_freeze(evas_object_evas_get(wd->obj));
2255 EINA_LIST_FOREACH(wd->group_items, l, git)
2257 if (git->item->want_realize)
2260 _item_realize(git, 0, EINA_FALSE);
2261 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2262 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2263 evas_object_show(VIEW(git));
2264 evas_object_raise(VIEW(git));
2266 else if (!git->item->want_realize && git->realized)
2269 _elm_genlist_item_unrealize(git, EINA_FALSE);
2272 evas_event_thaw(evas_object_evas_get(wd->obj));
2273 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2277 _must_recalc_idler(void *data)
2279 Widget_Data *wd = data;
2280 if (wd->calc_job) ecore_job_del(wd->calc_job);
2281 wd->calc_job = ecore_job_add(_calc_job, wd);
2282 wd->must_recalc_idler = NULL;
2283 return ECORE_CALLBACK_CANCEL;
2287 _calc_job(void *data)
2289 Widget_Data *wd = data;
2290 Item_Block *itb, *chb = NULL;
2291 Evas_Coord minw = -1, minh = 0, y = 0, ow;
2293 Eina_Bool minw_change = EINA_FALSE;
2294 Eina_Bool did_must_recalc = EINA_FALSE;
2297 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2301 evas_event_freeze(evas_object_evas_get(wd->obj));
2302 EINA_INLIST_FOREACH(wd->blocks, itb)
2304 Eina_Bool showme = EINA_FALSE;
2307 showme = itb->showme;
2308 itb->showme = EINA_FALSE;
2311 if (itb->realized) _item_block_unrealize(itb);
2313 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2315 if (itb->must_recalc)
2319 EINA_LIST_FOREACH(itb->items, l, it)
2320 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2321 itb->changed = EINA_TRUE;
2322 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2323 itb->must_recalc = EINA_FALSE;
2325 if (itb->realized) _item_block_unrealize(itb);
2326 showme = _item_block_recalc(itb, in, EINA_FALSE);
2332 if (minw == -1) minw = itb->minw;
2333 else if ((!itb->must_recalc) && (minw < itb->minw))
2336 minw_change = EINA_TRUE;
2342 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2344 wd->show_item->item->showme = EINA_FALSE;
2346 elm_smart_scroller_region_bring_in(wd->scr,
2348 wd->show_item->item->block->x,
2350 wd->show_item->item->block->y,
2351 wd->show_item->item->block->w,
2352 wd->show_item->item->h);
2354 elm_smart_scroller_child_region_show(wd->scr,
2356 wd->show_item->item->block->x,
2358 wd->show_item->item->block->y,
2359 wd->show_item->item->block->w,
2360 wd->show_item->item->h);
2361 wd->show_item = NULL;
2366 EINA_INLIST_FOREACH(wd->blocks, itb)
2372 if ((chb) && (EINA_INLIST_GET(chb)->next))
2374 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2376 if (itb->realized) _item_block_unrealize(itb);
2379 wd->realminw = minw;
2380 if (minw < wd->w) minw = wd->w;
2381 if ((minw != wd->minw) || (minh != wd->minh))
2385 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2386 _sizing_eval(wd->obj);
2387 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2392 it = wd->anchor_item;
2393 it_y = wd->anchor_y;
2394 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2395 it->item->block->y + it->y + it_y);
2396 wd->anchor_item = it;
2397 wd->anchor_y = it_y;
2400 if (did_must_recalc)
2402 if (!wd->must_recalc_idler)
2403 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2405 wd->calc_job = NULL;
2406 evas_object_smart_changed(wd->pan_smart);
2407 evas_event_thaw(evas_object_evas_get(wd->obj));
2408 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2412 _update_job(void *data)
2414 Widget_Data *wd = data;
2418 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2420 wd->update_job = NULL;
2423 evas_event_freeze(evas_object_evas_get(wd->obj));
2424 EINA_INLIST_FOREACH(wd->blocks, itb)
2426 Evas_Coord itminw, itminh;
2433 _item_block_position(itb, num);
2437 recalc = EINA_FALSE;
2438 EINA_LIST_FOREACH(itb->items, l2, it)
2440 if (it->item->updateme)
2442 itminw = it->item->minw;
2443 itminh = it->item->minh;
2445 it->item->updateme = EINA_FALSE;
2448 _elm_genlist_item_unrealize(it, EINA_FALSE);
2449 _item_realize(it, num, EINA_FALSE);
2450 position = EINA_TRUE;
2454 _item_realize(it, num, EINA_TRUE);
2455 _elm_genlist_item_unrealize(it, EINA_TRUE);
2457 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2462 itb->updateme = EINA_FALSE;
2465 position = EINA_TRUE;
2466 itb->changed = EINA_TRUE;
2467 _item_block_recalc(itb, num0, EINA_FALSE);
2468 _item_block_position(itb, num0);
2473 if (wd->calc_job) ecore_job_del(wd->calc_job);
2474 wd->calc_job = ecore_job_add(_calc_job, wd);
2476 evas_event_thaw(evas_object_evas_get(wd->obj));
2477 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2481 _pan_set(Evas_Object *obj,
2485 Pan *sd = evas_object_smart_data_get(obj);
2489 // Evas_Coord ow, oh;
2490 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2491 // ow = sd->wd->minw - ow;
2492 // if (ow < 0) ow = 0;
2493 // oh = sd->wd->minh - oh;
2494 // if (oh < 0) oh = 0;
2495 // if (x < 0) x = 0;
2496 // if (y < 0) y = 0;
2497 // if (x > ow) x = ow;
2498 // if (y > oh) y = oh;
2499 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2503 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2505 if ((itb->y + itb->h) > y)
2510 EINA_LIST_FOREACH(itb->items, l2, it)
2512 if ((itb->y + it->y) >= y)
2514 sd->wd->anchor_item = it;
2515 sd->wd->anchor_y = -(itb->y + it->y - y);
2522 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2526 _pan_get(Evas_Object *obj,
2530 Pan *sd = evas_object_smart_data_get(obj);
2533 if (x) *x = sd->wd->pan_x;
2534 if (y) *y = sd->wd->pan_y;
2538 _pan_max_get(Evas_Object *obj,
2542 Pan *sd = evas_object_smart_data_get(obj);
2546 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2547 ow = sd->wd->minw - ow;
2549 oh = sd->wd->minh - oh;
2556 _pan_min_get(Evas_Object *obj __UNUSED__,
2565 _pan_child_size_get(Evas_Object *obj,
2569 Pan *sd = evas_object_smart_data_get(obj);
2572 if (w) *w = sd->wd->minw;
2573 if (h) *h = sd->wd->minh;
2577 _pan_add(Evas_Object *obj)
2580 Evas_Object_Smart_Clipped_Data *cd;
2583 cd = evas_object_smart_data_get(obj);
2586 sd->__clipped_data = *cd;
2588 evas_object_smart_data_set(obj, sd);
2592 _pan_del(Evas_Object *obj)
2594 Pan *sd = evas_object_smart_data_get(obj);
2599 ecore_job_del(sd->resize_job);
2600 sd->resize_job = NULL;
2606 _pan_resize_job(void *data)
2610 _sizing_eval(sd->wd->obj);
2611 sd->resize_job = NULL;
2615 _pan_resize(Evas_Object *obj,
2619 Pan *sd = evas_object_smart_data_get(obj);
2623 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2624 if ((ow == w) && (oh == h)) return;
2625 if ((sd->wd->height_for_width) && (ow != w))
2628 if (sd->resize_job) ecore_job_del(sd->resize_job);
2629 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2631 sd->wd->pan_resized = EINA_TRUE;
2632 evas_object_smart_changed(obj);
2633 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2634 sd->wd->calc_job = NULL;
2636 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2637 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2642 _pan_calculate(Evas_Object *obj)
2644 Pan *sd = evas_object_smart_data_get(obj);
2646 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2652 evas_event_freeze(evas_object_evas_get(obj));
2654 if (sd->wd->pan_resized)
2657 sd->wd->pan_resized = EINA_FALSE;
2660 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2661 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2662 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2664 git->item->want_realize = EINA_FALSE;
2666 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2668 itb->w = sd->wd->minw;
2669 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2670 itb->y - sd->wd->pan_y + oy,
2672 cvx, cvy, cvw, cvh))
2674 if ((!itb->realized) || (itb->changed))
2675 _item_block_realize(itb);
2676 _item_block_position(itb, in);
2680 if (itb->realized) _item_block_unrealize(itb);
2684 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2685 _group_items_recalc(sd->wd);
2686 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2688 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2689 sd->wd->reorder_pan_move = EINA_TRUE;
2690 else sd->wd->reorder_pan_move = EINA_FALSE;
2691 evas_object_raise(sd->wd->VIEW(reorder_it));
2692 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2693 sd->wd->start_time = ecore_loop_time_get();
2695 _item_auto_scroll(sd->wd);
2696 evas_event_thaw(evas_object_evas_get(obj));
2697 evas_event_thaw_eval(evas_object_evas_get(obj));
2701 _pan_move(Evas_Object *obj,
2702 Evas_Coord x __UNUSED__,
2703 Evas_Coord y __UNUSED__)
2705 Pan *sd = evas_object_smart_data_get(obj);
2708 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2709 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2713 _hold_on(void *data __UNUSED__,
2715 void *event_info __UNUSED__)
2717 Widget_Data *wd = elm_widget_data_get(obj);
2719 elm_smart_scroller_hold_set(wd->scr, 1);
2723 _hold_off(void *data __UNUSED__,
2725 void *event_info __UNUSED__)
2727 Widget_Data *wd = elm_widget_data_get(obj);
2729 elm_smart_scroller_hold_set(wd->scr, 0);
2733 _freeze_on(void *data __UNUSED__,
2735 void *event_info __UNUSED__)
2737 Widget_Data *wd = elm_widget_data_get(obj);
2739 elm_smart_scroller_freeze_set(wd->scr, 1);
2743 _freeze_off(void *data __UNUSED__,
2745 void *event_info __UNUSED__)
2747 Widget_Data *wd = elm_widget_data_get(obj);
2749 elm_smart_scroller_freeze_set(wd->scr, 0);
2753 _scr_anim_start(void *data,
2754 Evas_Object *obj __UNUSED__,
2755 void *event_info __UNUSED__)
2757 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
2761 _scr_anim_stop(void *data,
2762 Evas_Object *obj __UNUSED__,
2763 void *event_info __UNUSED__)
2765 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
2769 _scr_drag_start(void *data,
2770 Evas_Object *obj __UNUSED__,
2771 void *event_info __UNUSED__)
2773 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
2777 _scr_drag_stop(void *data,
2778 Evas_Object *obj __UNUSED__,
2779 void *event_info __UNUSED__)
2781 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
2785 _edge_left(void *data,
2786 Evas_Object *scr __UNUSED__,
2787 void *event_info __UNUSED__)
2789 Evas_Object *obj = data;
2790 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2794 _edge_right(void *data,
2795 Evas_Object *scr __UNUSED__,
2796 void *event_info __UNUSED__)
2798 Evas_Object *obj = data;
2799 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2803 _edge_top(void *data,
2804 Evas_Object *scr __UNUSED__,
2805 void *event_info __UNUSED__)
2807 Evas_Object *obj = data;
2808 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2812 _edge_bottom(void *data,
2813 Evas_Object *scr __UNUSED__,
2814 void *event_info __UNUSED__)
2816 Evas_Object *obj = data;
2817 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2821 _mode_item_realize(Elm_Gen_Item *it)
2825 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
2827 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2828 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
2829 edje_object_scale_set(it->item->mode_view,
2830 elm_widget_scale_get(WIDGET(it)) *
2831 _elm_config->scale);
2832 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
2833 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
2835 strncpy(buf, "item", sizeof(buf));
2836 if (it->wd->compress)
2837 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
2839 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
2840 strncat(buf, "/", sizeof(buf) - strlen(buf));
2841 strncat(buf, it->wd->mode_item_style, sizeof(buf) - strlen(buf));
2843 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
2844 elm_widget_style_get(WIDGET(it)));
2845 edje_object_mirrored_set(it->item->mode_view,
2846 elm_widget_mirrored_get(WIDGET(it)));
2848 /* signal callback add */
2849 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
2851 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
2853 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
2856 /* text_get, content_get, state_get */
2857 /* FIXME: If you see that assert, please notify us and we
2858 will clean our mess */
2859 assert(eina_list_count(it->item->mode_content_objs) == 0);
2861 _item_label_realize(it, it->item->mode_view, &it->item->mode_labels, NULL);
2862 it->item->mode_content_objs =
2863 _item_content_realize(it, it->item->mode_view,
2864 &it->item->mode_contents, NULL);
2865 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
2867 edje_object_part_swallow(it->item->mode_view,
2868 edje_object_data_get(it->item->mode_view, "mode_part"),
2871 it->want_unrealize = EINA_FALSE;
2872 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2873 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2877 _mode_item_unrealize(Elm_Gen_Item *it)
2879 Widget_Data *wd = it->wd;
2880 Evas_Object *content;
2881 if (!it->item->mode_view) return;
2883 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2884 elm_widget_stringlist_free(it->item->mode_labels);
2885 it->item->mode_labels = NULL;
2886 elm_widget_stringlist_free(it->item->mode_contents);
2887 it->item->mode_contents = NULL;
2888 elm_widget_stringlist_free(it->item->mode_states);
2890 EINA_LIST_FREE(it->item->mode_content_objs, content)
2891 evas_object_del(content);
2893 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
2894 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
2895 evas_object_del(it->item->mode_view);
2896 it->item->mode_view = NULL;
2898 if (wd->mode_item == it)
2899 wd->mode_item = NULL;
2900 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2901 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2905 _item_mode_set(Elm_Gen_Item *it)
2908 Widget_Data *wd = it->wd;
2913 it->item->nocache = EINA_TRUE;
2915 if (wd->scr_hold_timer)
2917 ecore_timer_del(wd->scr_hold_timer);
2918 wd->scr_hold_timer = NULL;
2920 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
2921 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
2923 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2924 _mode_item_realize(it);
2925 if (it->item->group_item)
2926 evas_object_raise(it->item->VIEW(group_item));
2927 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
2928 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2929 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2931 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
2932 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2936 _item_mode_unset(Widget_Data *wd)
2939 if (!wd->mode_item) return;
2940 char buf[1024], buf2[1024];
2944 it->item->nocache = EINA_TRUE;
2946 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
2947 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
2949 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2950 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
2952 wd->mode_item = NULL;
2956 _item_auto_scroll(Widget_Data *wd)
2961 Evas_Coord ox, oy, ow, oh;
2963 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
2965 evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
2966 if (wd->expanded_item->item->scrl_y > (oh + oy) / 2)
2968 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
2969 elm_genlist_item_bring_in(it);
2971 wd->auto_scroll_enabled = EINA_FALSE;
2976 elm_genlist_add(Evas_Object *parent)
2981 Evas_Coord minw, minh;
2982 static Evas_Smart *smart = NULL;
2986 static Evas_Smart_Class sc;
2988 evas_object_smart_clipped_smart_set(&_pan_sc);
2990 sc.name = "elm_genlist_pan";
2991 sc.version = EVAS_SMART_CLASS_VERSION;
2994 sc.resize = _pan_resize;
2995 sc.move = _pan_move;
2996 sc.calculate = _pan_calculate;
2997 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3000 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3002 ELM_SET_WIDTYPE(widtype, "genlist");
3004 elm_widget_type_set(obj, "genlist");
3005 elm_widget_sub_object_add(parent, obj);
3006 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3007 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3008 elm_widget_data_set(obj, wd);
3009 elm_widget_del_hook_set(obj, _del_hook);
3010 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3011 elm_widget_theme_hook_set(obj, _theme_hook);
3012 elm_widget_can_focus_set(obj, EINA_TRUE);
3013 elm_widget_event_hook_set(obj, _event_hook);
3014 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3015 elm_widget_translate_hook_set(obj, _translate_hook);
3018 wd->scr = elm_smart_scroller_add(e);
3019 elm_smart_scroller_widget_set(wd->scr, obj);
3020 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3021 elm_widget_style_get(obj));
3022 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3023 _elm_config->thumbscroll_bounce_enable);
3024 elm_widget_resize_object_set(obj, wd->scr);
3026 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3027 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3028 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3029 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3030 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3031 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3032 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3033 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3036 wd->mode = ELM_LIST_SCROLL;
3037 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3038 wd->item_cache_max = wd->max_items_per_block * 2;
3039 wd->longpress_timeout = _elm_config->longpress_timeout;
3041 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3042 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3043 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3044 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3046 wd->pan_smart = evas_object_smart_add(e, smart);
3047 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3050 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3051 _pan_set, _pan_get, _pan_max_get,
3052 _pan_min_get, _pan_child_size_get);
3054 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3056 evas_object_size_hint_min_set(obj, minw, minh);
3058 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3060 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3066 _item_select(Elm_Gen_Item *it)
3068 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3071 it->selected = EINA_TRUE;
3072 it->wd->selected = eina_list_append(it->wd->selected, it);
3074 else if (!it->wd->always_select) return;
3076 evas_object_ref(WIDGET(it));
3079 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3080 if (it->generation == it->wd->generation)
3081 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3084 evas_object_unref(WIDGET(it));
3085 if ((it->wd->clear_me) && (!it->wd->walking))
3086 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3089 if ((!it->walking) && (it->generation < it->wd->generation))
3091 if (!it->relcount) it->del_cb(it);
3094 it->wd->last_selected_item = it;
3098 static Evas_Object *
3099 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3101 return edje_object_part_swallow_get(VIEW(it), part);
3105 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3107 edje_object_part_swallow(VIEW(it), part, content);
3110 static Evas_Object *
3111 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3115 obj = edje_object_part_swallow_get(VIEW(it), part);
3116 if (!obj) return NULL;
3117 edje_object_part_unswallow(VIEW(it), obj);
3122 _item_label_hook(Elm_Gen_Item *it, const char *part)
3124 if (!it->itc->func.text_get) return NULL;
3125 return edje_object_part_text_get(VIEW(it), part);
3129 _elm_genlist_item_new(Widget_Data *wd,
3130 const Elm_Gen_Item_Class *itc,
3132 Elm_Gen_Item *parent,
3134 const void *func_data)
3138 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3139 if (!it) return NULL;
3141 it->generation = wd->generation;
3143 it->base.data = data;
3144 it->parent = parent;
3145 it->func.func = func;
3146 it->func.data = func_data;
3147 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3148 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3149 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3151 it->sel_cb = (Ecore_Cb)_item_select;
3153 elm_widget_item_text_get_hook_set(it, _item_label_hook);
3157 static Elm_Gen_Item *
3158 _item_new(Widget_Data *wd,
3159 const Elm_Genlist_Item_Class *itc,
3161 Elm_Gen_Item *parent,
3162 Elm_Genlist_Item_Flags flags,
3164 const void *func_data)
3166 Elm_Gen_Item *it, *it2;
3169 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3170 if (!it) return NULL;
3171 it->item = ELM_NEW(Elm_Gen_Item_Type);
3172 it->item->flags = flags;
3173 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3174 it->item->expanded_depth = 0;
3175 elm_widget_item_del_cb_set(it, _item_del_hook);
3176 ELM_GEN_ITEM_SETUP(it);
3179 if (it->parent->group)
3180 it->item->group_item = parent;
3181 else if (it->parent->item->group_item)
3182 it->item->group_item = it->parent->item->group_item;
3184 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3186 if (!it2->parent->group) depth += 1;
3188 it->item->expanded_depth = depth;
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);