3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_genlist.h"
9 #define MAX_ITEMS_PER_BLOCK 32
10 #define REORDER_EFFECT_TIME 0.5
12 #define ELM_GEN_SETUP(wd) \
13 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
14 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
15 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
17 #define ELM_GEN_ITEM_SETUP(it) \
18 (it)->del_cb = (Ecore_Cb)_item_del; \
19 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
20 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
21 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
22 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
24 typedef struct _Item_Block Item_Block;
25 typedef struct _Item_Cache Item_Cache;
27 struct Elm_Gen_Item_Type
32 Evas_Coord w, h, minw, minh;
33 Elm_Gen_Item *group_item;
34 Elm_Genlist_Item_Flags flags;
35 Eina_List *mode_texts, *mode_contents, *mode_states, *mode_content_objs;
36 Ecore_Timer *swipe_timer;
37 Evas_Coord scrl_x, scrl_y, old_scrl_y;
40 Evas_Object *mode_view;
46 Eina_Bool want_realize : 1;
47 Eina_Bool expanded : 1;
48 Eina_Bool mincalcd : 1;
51 Eina_Bool updateme : 1;
52 Eina_Bool nocache : 1;
53 Eina_Bool stacking_even : 1;
54 Eina_Bool nostacking : 1;
55 Eina_Bool move_effect_enabled : 1;
66 Evas_Coord x, y, w, h, minw, minh;
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_text_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, "texts"));
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_text_realize(it, VIEW(it), &it->texts, 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_changed = 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_changed)
2657 sd->wd->pan_changed = 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);
2709 sd->wd->pan_changed = EINA_TRUE;
2710 evas_object_smart_changed(obj);
2711 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2712 sd->wd->calc_job = NULL;
2716 _hold_on(void *data __UNUSED__,
2718 void *event_info __UNUSED__)
2720 Widget_Data *wd = elm_widget_data_get(obj);
2722 elm_smart_scroller_hold_set(wd->scr, 1);
2726 _hold_off(void *data __UNUSED__,
2728 void *event_info __UNUSED__)
2730 Widget_Data *wd = elm_widget_data_get(obj);
2732 elm_smart_scroller_hold_set(wd->scr, 0);
2736 _freeze_on(void *data __UNUSED__,
2738 void *event_info __UNUSED__)
2740 Widget_Data *wd = elm_widget_data_get(obj);
2742 elm_smart_scroller_freeze_set(wd->scr, 1);
2746 _freeze_off(void *data __UNUSED__,
2748 void *event_info __UNUSED__)
2750 Widget_Data *wd = elm_widget_data_get(obj);
2752 elm_smart_scroller_freeze_set(wd->scr, 0);
2756 _scr_anim_start(void *data,
2757 Evas_Object *obj __UNUSED__,
2758 void *event_info __UNUSED__)
2760 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
2764 _scr_anim_stop(void *data,
2765 Evas_Object *obj __UNUSED__,
2766 void *event_info __UNUSED__)
2768 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
2772 _scr_drag_start(void *data,
2773 Evas_Object *obj __UNUSED__,
2774 void *event_info __UNUSED__)
2776 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
2780 _scr_drag_stop(void *data,
2781 Evas_Object *obj __UNUSED__,
2782 void *event_info __UNUSED__)
2784 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
2788 _edge_left(void *data,
2789 Evas_Object *scr __UNUSED__,
2790 void *event_info __UNUSED__)
2792 Evas_Object *obj = data;
2793 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2797 _edge_right(void *data,
2798 Evas_Object *scr __UNUSED__,
2799 void *event_info __UNUSED__)
2801 Evas_Object *obj = data;
2802 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2806 _edge_top(void *data,
2807 Evas_Object *scr __UNUSED__,
2808 void *event_info __UNUSED__)
2810 Evas_Object *obj = data;
2811 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2815 _edge_bottom(void *data,
2816 Evas_Object *scr __UNUSED__,
2817 void *event_info __UNUSED__)
2819 Evas_Object *obj = data;
2820 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2824 _mode_item_realize(Elm_Gen_Item *it)
2828 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
2830 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2831 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
2832 edje_object_scale_set(it->item->mode_view,
2833 elm_widget_scale_get(WIDGET(it)) *
2834 _elm_config->scale);
2835 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
2836 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
2838 strncpy(buf, "item", sizeof(buf));
2839 if (it->wd->compress)
2840 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
2842 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
2843 strncat(buf, "/", sizeof(buf) - strlen(buf));
2844 strncat(buf, it->wd->mode_item_style, sizeof(buf) - strlen(buf));
2846 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
2847 elm_widget_style_get(WIDGET(it)));
2848 edje_object_mirrored_set(it->item->mode_view,
2849 elm_widget_mirrored_get(WIDGET(it)));
2851 /* signal callback add */
2852 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
2854 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
2856 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
2859 /* text_get, content_get, state_get */
2860 /* FIXME: If you see that assert, please notify us and we
2861 will clean our mess */
2862 assert(eina_list_count(it->item->mode_content_objs) == 0);
2864 _item_text_realize(it, it->item->mode_view, &it->item->mode_texts, NULL);
2865 it->item->mode_content_objs =
2866 _item_content_realize(it, it->item->mode_view,
2867 &it->item->mode_contents, NULL);
2868 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
2870 edje_object_part_swallow(it->item->mode_view,
2871 edje_object_data_get(it->item->mode_view, "mode_part"),
2874 it->want_unrealize = EINA_FALSE;
2875 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2876 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2880 _mode_item_unrealize(Elm_Gen_Item *it)
2882 Widget_Data *wd = it->wd;
2883 Evas_Object *content;
2884 if (!it->item->mode_view) return;
2886 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2887 elm_widget_stringlist_free(it->item->mode_texts);
2888 it->item->mode_texts = NULL;
2889 elm_widget_stringlist_free(it->item->mode_contents);
2890 it->item->mode_contents = NULL;
2891 elm_widget_stringlist_free(it->item->mode_states);
2893 EINA_LIST_FREE(it->item->mode_content_objs, content)
2894 evas_object_del(content);
2896 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
2897 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
2898 evas_object_del(it->item->mode_view);
2899 it->item->mode_view = NULL;
2901 if (wd->mode_item == it)
2902 wd->mode_item = NULL;
2903 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2904 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2908 _item_mode_set(Elm_Gen_Item *it)
2911 Widget_Data *wd = it->wd;
2916 it->item->nocache = EINA_TRUE;
2918 if (wd->scr_hold_timer)
2920 ecore_timer_del(wd->scr_hold_timer);
2921 wd->scr_hold_timer = NULL;
2923 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
2924 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
2926 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2927 _mode_item_realize(it);
2928 if (it->item->group_item)
2929 evas_object_raise(it->item->VIEW(group_item));
2930 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
2931 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2932 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2934 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
2935 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2939 _item_mode_unset(Widget_Data *wd)
2942 if (!wd->mode_item) return;
2943 char buf[1024], buf2[1024];
2947 it->item->nocache = EINA_TRUE;
2949 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
2950 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
2952 edje_object_signal_emit(it->item->mode_view, buf, "elm");
2953 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
2955 wd->mode_item = NULL;
2959 _item_auto_scroll(Widget_Data *wd)
2964 Evas_Coord ox, oy, ow, oh;
2966 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
2968 evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
2969 if (wd->expanded_item->item->scrl_y > (oh + oy) / 2)
2971 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
2972 elm_genlist_item_bring_in(it);
2974 wd->auto_scroll_enabled = EINA_FALSE;
2979 elm_genlist_add(Evas_Object *parent)
2984 Evas_Coord minw, minh;
2985 static Evas_Smart *smart = NULL;
2989 static Evas_Smart_Class sc;
2991 evas_object_smart_clipped_smart_set(&_pan_sc);
2993 sc.name = "elm_genlist_pan";
2994 sc.version = EVAS_SMART_CLASS_VERSION;
2997 sc.resize = _pan_resize;
2998 sc.move = _pan_move;
2999 sc.calculate = _pan_calculate;
3000 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3003 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3005 ELM_SET_WIDTYPE(widtype, "genlist");
3007 elm_widget_type_set(obj, "genlist");
3008 elm_widget_sub_object_add(parent, obj);
3009 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3010 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3011 elm_widget_data_set(obj, wd);
3012 elm_widget_del_hook_set(obj, _del_hook);
3013 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3014 elm_widget_theme_hook_set(obj, _theme_hook);
3015 elm_widget_can_focus_set(obj, EINA_TRUE);
3016 elm_widget_event_hook_set(obj, _event_hook);
3017 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3018 elm_widget_translate_hook_set(obj, _translate_hook);
3021 wd->scr = elm_smart_scroller_add(e);
3022 elm_smart_scroller_widget_set(wd->scr, obj);
3023 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3024 elm_widget_style_get(obj));
3025 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3026 _elm_config->thumbscroll_bounce_enable);
3027 elm_widget_resize_object_set(obj, wd->scr);
3029 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3030 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3031 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3032 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3033 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3034 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3035 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3036 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3039 wd->mode = ELM_LIST_SCROLL;
3040 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3041 wd->item_cache_max = wd->max_items_per_block * 2;
3042 wd->longpress_timeout = _elm_config->longpress_timeout;
3044 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3045 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3046 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3047 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3049 wd->pan_smart = evas_object_smart_add(e, smart);
3050 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3053 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3054 _pan_set, _pan_get, _pan_max_get,
3055 _pan_min_get, _pan_child_size_get);
3057 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3059 evas_object_size_hint_min_set(obj, minw, minh);
3061 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3063 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3069 _item_select(Elm_Gen_Item *it)
3071 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3074 it->selected = EINA_TRUE;
3075 it->wd->selected = eina_list_append(it->wd->selected, it);
3077 else if (!it->wd->always_select) return;
3079 evas_object_ref(WIDGET(it));
3082 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3083 if (it->generation == it->wd->generation)
3084 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3087 evas_object_unref(WIDGET(it));
3088 if ((it->wd->clear_me) && (!it->wd->walking))
3089 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3092 if ((!it->walking) && (it->generation < it->wd->generation))
3094 if (!it->relcount) it->del_cb(it);
3097 it->wd->last_selected_item = it;
3101 static Evas_Object *
3102 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3104 return edje_object_part_swallow_get(VIEW(it), part);
3108 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3110 edje_object_part_swallow(VIEW(it), part, content);
3113 static Evas_Object *
3114 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3118 obj = edje_object_part_swallow_get(VIEW(it), part);
3119 if (!obj) return NULL;
3120 edje_object_part_unswallow(VIEW(it), obj);
3125 _item_text_hook(Elm_Gen_Item *it, const char *part)
3127 if (!it->itc->func.text_get) return NULL;
3128 return edje_object_part_text_get(VIEW(it), part);
3132 _elm_genlist_item_new(Widget_Data *wd,
3133 const Elm_Gen_Item_Class *itc,
3135 Elm_Gen_Item *parent,
3137 const void *func_data)
3141 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3142 if (!it) return NULL;
3144 it->generation = wd->generation;
3146 it->base.data = data;
3147 it->parent = parent;
3148 it->func.func = func;
3149 it->func.data = func_data;
3150 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3151 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3152 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3154 it->sel_cb = (Ecore_Cb)_item_select;
3156 elm_widget_item_text_get_hook_set(it, _item_text_hook);
3160 static Elm_Gen_Item *
3161 _item_new(Widget_Data *wd,
3162 const Elm_Genlist_Item_Class *itc,
3164 Elm_Gen_Item *parent,
3165 Elm_Genlist_Item_Flags flags,
3167 const void *func_data)
3169 Elm_Gen_Item *it, *it2;
3172 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3173 if (!it) return NULL;
3174 it->item = ELM_NEW(Elm_Gen_Item_Type);
3175 it->item->flags = flags;
3176 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3177 it->item->expanded_depth = 0;
3178 elm_widget_item_del_cb_set(it, _item_del_hook);
3179 ELM_GEN_ITEM_SETUP(it);
3182 if (it->parent->group)
3183 it->item->group_item = parent;
3184 else if (it->parent->item->group_item)
3185 it->item->group_item = it->parent->item->group_item;
3187 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3189 if (!it2->parent->group) depth += 1;
3191 it->item->expanded_depth = depth;
3196 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3200 itb = calloc(1, sizeof(Item_Block));
3201 if (!itb) return NULL;
3204 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3206 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3211 _item_block_add(Widget_Data *wd,
3214 Item_Block *itb = NULL;
3221 itb = calloc(1, sizeof(Item_Block));
3222 if (!itb) return EINA_FALSE;
3224 if (!it->item->rel->item->block)
3227 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3228 itb->items = eina_list_append(itb->items, it);
3232 if (it->item->before)
3234 wd->blocks = eina_inlist_prepend_relative
3235 (wd->blocks, EINA_INLIST_GET(itb),
3236 EINA_INLIST_GET(it->item->rel->item->block));
3238 eina_list_prepend_relative(itb->items, it, it->item->rel);
3242 wd->blocks = eina_inlist_append_relative
3243 (wd->blocks, EINA_INLIST_GET(itb),
3244 EINA_INLIST_GET(it->item->rel->item->block));
3246 eina_list_append_relative(itb->items, it, it->item->rel);
3252 if (it->item->before)
3256 itb = (Item_Block *)(wd->blocks);
3257 if (itb->count >= wd->max_items_per_block)
3259 itb = _item_block_new(wd, EINA_TRUE);
3260 if (!itb) return EINA_FALSE;
3265 itb = _item_block_new(wd, EINA_TRUE);
3266 if (!itb) return EINA_FALSE;
3268 itb->items = eina_list_prepend(itb->items, it);
3274 itb = (Item_Block *)(wd->blocks->last);
3275 if (itb->count >= wd->max_items_per_block)
3277 itb = _item_block_new(wd, EINA_FALSE);
3278 if (!itb) return EINA_FALSE;
3283 itb = _item_block_new(wd, EINA_FALSE);
3284 if (!itb) return EINA_FALSE;
3286 itb->items = eina_list_append(itb->items, it);
3292 if (it->item->rel->item->queued)
3294 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3295 on sorted insertion order, so the queue is not always ordered like the item list.
3296 This lead to issue where we depend on an item that is not yet created. As a quick
3297 work around, we reschedule the calc of the item and stop reordering the list to
3298 prevent any nasty issue to show up here.
3300 wd->queue = eina_list_append(wd->queue, it);
3301 wd->requeued = EINA_TRUE;
3302 it->item->queued = EINA_TRUE;
3305 itb = it->item->rel->item->block;
3306 if (!itb) goto newblock;
3307 if (it->item->before)
3308 itb->items = eina_list_prepend_relative(itb->items, it, it->item->rel);
3310 itb->items = eina_list_append_relative(itb->items, it, it->item->rel);
3313 itb->changed = EINA_TRUE;
3314 it->item->block = itb;
3315 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3316 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3319 it->item->rel->relcount--;
3320 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3321 _item_del(it->item->rel);
3322 it->item->rel = NULL;
3324 if (itb->count > itb->wd->max_items_per_block)
3329 Eina_Bool done = EINA_FALSE;
3331 newc = itb->count / 2;
3333 if (EINA_INLIST_GET(itb)->prev)
3335 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3337 if (itbp->count + newc < wd->max_items_per_block / 2)
3339 /* moving items to previous block */
3340 while ((itb->count > newc) && (itb->items))
3342 it2 = eina_list_data_get(itb->items);
3343 itb->items = eina_list_remove_list(itb->items, itb->items);
3346 itbp->items = eina_list_append(itbp->items, it2);
3347 it2->item->block = itbp;
3355 if (!done && EINA_INLIST_GET(itb)->next)
3357 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3359 if (itbn->count + newc < wd->max_items_per_block / 2)
3361 /* moving items to next block */
3362 while ((itb->count > newc) && (itb->items))
3366 l = eina_list_last(itb->items);
3367 it2 = eina_list_data_get(l);
3368 itb->items = eina_list_remove_list(itb->items, l);
3371 itbn->items = eina_list_prepend(itbn->items, it2);
3372 it2->item->block = itbn;
3382 /* moving items to new block */
3383 itb2 = calloc(1, sizeof(Item_Block));
3384 if (!itb2) return EINA_FALSE;
3387 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3388 EINA_INLIST_GET(itb));
3389 itb2->changed = EINA_TRUE;
3390 while ((itb->count > newc) && (itb->items))
3394 l = eina_list_last(itb->items);
3396 itb->items = eina_list_remove_list(itb->items, l);
3399 itb2->items = eina_list_prepend(itb2->items, it2);
3400 it2->item->block = itb2;
3410 _queue_process(Widget_Data *wd)
3413 Eina_Bool showme = EINA_FALSE;
3416 t0 = ecore_loop_time_get();
3417 //evas_event_freeze(evas_object_evas_get(wd->obj));
3418 for (n = 0; (wd->queue) && (n < 128); n++)
3422 it = eina_list_data_get(wd->queue);
3423 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3424 it->item->queued = EINA_FALSE;
3425 if (!_item_block_add(wd, it)) continue;
3427 _item_block_realize(it->item->block);
3428 t = ecore_time_get();
3429 if (it->item->block->changed)
3431 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3432 it->item->block->changed = 0;
3435 if (wd->calc_job) ecore_job_del(wd->calc_job);
3436 wd->calc_job = NULL;
3438 wd->pan_changed = EINA_FALSE;
3441 if (showme) it->item->block->showme = EINA_TRUE;
3442 if (eina_inlist_count(wd->blocks) > 1)
3444 if ((t - t0) > (ecore_animator_frametime_get())) break;
3447 //evas_event_thaw(evas_object_evas_get(wd->obj));
3448 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3453 _idle_process(void *data, Eina_Bool *wakeup)
3455 Widget_Data *wd = data;
3458 //static double q_start = 0.0;
3459 //if (q_start == 0.0) q_start = ecore_time_get();
3461 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
3465 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
3467 return ECORE_CALLBACK_CANCEL;
3469 return ECORE_CALLBACK_RENEW;
3473 _item_idle_enterer(void *data)
3475 Widget_Data *wd = data;
3476 Eina_Bool wakeup = EINA_FALSE;
3477 Eina_Bool ok = _idle_process(data, &wakeup);
3482 if (wd->calc_job) ecore_job_del(wd->calc_job);
3483 wd->calc_job = ecore_job_add(_calc_job, wd);
3485 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
3490 _item_queue(Widget_Data *wd,
3494 if (it->item->queued) return;
3495 it->item->queued = EINA_TRUE;
3496 if (cb && !wd->requeued)
3497 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
3499 wd->queue = eina_list_append(wd->queue, it);
3500 // FIXME: why does a freeze then thaw here cause some genlist
3501 // elm_genlist_item_append() to be much much slower?
3502 // evas_event_freeze(evas_object_evas_get(wd->obj));
3503 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
3505 if (wd->queue_idle_enterer)
3507 ecore_idle_enterer_del(wd->queue_idle_enterer);
3508 wd->queue_idle_enterer = NULL;
3512 // evas_event_thaw(evas_object_evas_get(wd->obj));
3513 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3514 if (!wd->queue_idle_enterer)
3515 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
3519 _elm_genlist_item_compare_data(const void *data, const void *data1)
3521 const Elm_Gen_Item *it = data;
3522 const Elm_Gen_Item *item1 = data1;
3524 return it->wd->item_compare_data_cb(it->base.data, item1->base.data);
3528 _elm_genlist_item_compare(const void *data, const void *data1)
3530 const Elm_Gen_Item *it, *item1;
3531 it = ELM_GEN_ITEM_FROM_INLIST(data);
3532 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
3533 return it->wd->item_compare_cb(it, item1);
3537 _elm_genlist_item_list_compare(const void *data, const void *data1)
3539 const Elm_Gen_Item *it = data;
3540 const Elm_Gen_Item *item1 = data1;
3541 return it->wd->item_compare_cb(it, item1);
3545 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
3550 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3551 _item_block_del(it);
3553 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3554 it->item->rel = after;
3555 it->item->rel->relcount++;
3556 it->item->before = EINA_FALSE;
3557 if (after->item->group_item) it->item->group_item = after->item->group_item;
3558 _item_queue(it->wd, it, NULL);
3560 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3564 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
3567 if (!before) return;
3569 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3570 _item_block_del(it);
3571 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
3572 it->item->rel = before;
3573 it->item->rel->relcount++;
3574 it->item->before = EINA_TRUE;
3575 if (before->item->group_item) it->item->group_item = before->item->group_item;
3576 _item_queue(it->wd, it, NULL);
3578 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3582 elm_genlist_item_append(Evas_Object *obj,
3583 const Elm_Genlist_Item_Class *itc,
3585 Elm_Gen_Item *parent,
3586 Elm_Genlist_Item_Flags flags,
3588 const void *func_data)
3590 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3591 Widget_Data *wd = elm_widget_data_get(obj);
3592 if (!wd) return NULL;
3593 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3595 if (!it) return NULL;
3599 wd->group_items = eina_list_append(wd->group_items, it);
3600 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
3601 it->item->rel = NULL;
3605 Elm_Gen_Item *it2 = NULL;
3606 Eina_List *ll = eina_list_last(it->parent->item->items);
3607 if (ll) it2 = ll->data;
3608 it->parent->item->items = eina_list_append(it->parent->item->items, it);
3609 if (!it2) it2 = it->parent;
3611 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3612 EINA_INLIST_GET(it2));
3613 it->item->rel = it2;
3614 it->item->rel->relcount++;
3616 it->item->before = EINA_FALSE;
3617 _item_queue(wd, it, NULL);
3622 elm_genlist_item_prepend(Evas_Object *obj,
3623 const Elm_Genlist_Item_Class *itc,
3625 Elm_Gen_Item *parent,
3626 Elm_Genlist_Item_Flags flags,
3628 const void *func_data)
3630 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3631 Widget_Data *wd = elm_widget_data_get(obj);
3632 if (!wd) return NULL;
3633 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3635 if (!it) return NULL;
3639 wd->group_items = eina_list_prepend(wd->group_items, it);
3640 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
3641 it->item->rel = NULL;
3645 Elm_Gen_Item *it2 = NULL;
3646 Eina_List *ll = it->parent->item->items;
3647 if (ll) it2 = ll->data;
3648 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
3649 if (!it2) it2 = it->parent;
3651 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3652 EINA_INLIST_GET(it2));
3653 it->item->rel = it2;
3654 it->item->rel->relcount++;
3656 it->item->before = EINA_TRUE;
3657 _item_queue(wd, it, NULL);
3662 elm_genlist_item_insert_after(Evas_Object *obj,
3663 const Elm_Genlist_Item_Class *itc,
3665 Elm_Gen_Item *parent,
3666 Elm_Gen_Item *after,
3667 Elm_Genlist_Item_Flags flags,
3669 const void *func_data)
3671 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3672 EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3673 Widget_Data *wd = elm_widget_data_get(obj);
3674 if (!wd) return NULL;
3675 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
3676 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3678 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3680 if (!it) return NULL;
3685 wd->group_items = eina_list_append_relative(wd->group_items, it,
3690 it->parent->item->items = eina_list_append_relative(it->parent->item->items, it,
3693 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3694 EINA_INLIST_GET(after));
3695 it->item->rel = after;
3696 it->item->rel->relcount++;
3697 it->item->before = EINA_FALSE;
3698 _item_queue(wd, it, NULL);
3703 elm_genlist_item_insert_before(Evas_Object *obj,
3704 const Elm_Genlist_Item_Class *itc,
3706 Elm_Gen_Item *parent,
3707 Elm_Gen_Item *before,
3708 Elm_Genlist_Item_Flags flags,
3710 const void *func_data)
3712 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3713 EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
3714 Widget_Data *wd = elm_widget_data_get(obj);
3715 if (!wd) return NULL;
3716 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
3717 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3719 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3721 if (!it) return NULL;
3724 if (it->group && before->group)
3725 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
3730 it->parent->item->items = eina_list_prepend_relative(it->parent->item->items, it,
3733 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3734 EINA_INLIST_GET(before));
3735 it->item->rel = before;
3736 it->item->rel->relcount++;
3737 it->item->before = EINA_TRUE;
3738 _item_queue(wd, it, NULL);
3743 elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
3744 const Elm_Genlist_Item_Class *itc,
3746 Elm_Gen_Item *parent,
3747 Elm_Genlist_Item_Flags flags,
3748 Eina_Compare_Cb comp,
3750 const void *func_data)
3752 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3753 Widget_Data *wd = elm_widget_data_get(obj);
3754 if (!wd) return NULL;
3755 Elm_Gen_Item *rel = NULL;
3756 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3758 if (!it) return NULL;
3760 wd->item_compare_cb = comp;
3767 l = eina_list_search_sorted_near_list(it->parent->item->items,
3768 _elm_genlist_item_list_compare, it,
3771 rel = eina_list_data_get(l);
3775 if (cmp_result >= 0)
3777 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
3778 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3779 it->item->before = EINA_FALSE;
3781 else if (cmp_result < 0)
3783 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
3784 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3785 it->item->before = EINA_TRUE;
3792 wd->state = eina_inlist_sorted_state_new();
3793 eina_inlist_sorted_state_init(wd->state, wd->items);
3794 wd->requeued = EINA_FALSE;
3798 wd->group_items = eina_list_append(wd->group_items, it);
3800 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
3801 _elm_genlist_item_compare, wd->state);
3803 if (EINA_INLIST_GET(it)->next)
3805 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3806 it->item->before = EINA_TRUE;
3808 else if (EINA_INLIST_GET(it)->prev)
3810 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3811 it->item->before = EINA_FALSE;
3817 it->item->rel = rel;
3818 it->item->rel->relcount++;
3821 _item_queue(wd, it, _elm_genlist_item_list_compare);
3827 elm_genlist_item_sorted_insert(Evas_Object *obj,
3828 const Elm_Genlist_Item_Class *itc,
3830 Elm_Gen_Item *parent,
3831 Elm_Genlist_Item_Flags flags,
3832 Eina_Compare_Cb comp,
3834 const void *func_data)
3836 Widget_Data *wd = elm_widget_data_get(obj);
3837 wd->item_compare_data_cb = comp;
3839 return elm_genlist_item_direct_sorted_insert(obj, itc, data, parent, flags,
3840 _elm_genlist_item_compare_data, func, func_data);
3844 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
3846 Eina_Inlist *next, *l;
3848 ELM_CHECK_WIDTYPE(obj, widtype);
3849 Widget_Data *wd = elm_widget_data_get(obj);
3852 if (!standby) wd->generation++;
3856 eina_inlist_sorted_state_free(wd->state);
3860 if (wd->walking > 0)
3865 evas_event_freeze(evas_object_evas_get(wd->obj));
3866 for (l = wd->items, next = l ? l->next : NULL;
3868 l = next, next = next ? next->next : NULL)
3870 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
3872 if (it->generation < wd->generation)
3874 Elm_Gen_Item *itn = NULL;
3876 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
3877 if (itn) itn->walking++; /* prevent early death of subitem */
3879 if (itn) itn->walking--;
3883 wd->pan_changed = EINA_TRUE;
3886 ecore_job_del(wd->calc_job);
3887 wd->calc_job = NULL;
3889 if (wd->selected) wd->selected = eina_list_free(wd->selected);
3890 if (wd->clear_cb) wd->clear_cb(wd);
3898 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
3899 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3901 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
3902 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
3903 evas_event_thaw(evas_object_evas_get(wd->obj));
3904 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3908 elm_genlist_clear(Evas_Object *obj)
3910 _elm_genlist_clear(obj, EINA_FALSE);
3914 elm_genlist_multi_select_set(Evas_Object *obj,
3917 ELM_CHECK_WIDTYPE(obj, widtype);
3918 Widget_Data *wd = elm_widget_data_get(obj);
3924 elm_genlist_multi_select_get(const Evas_Object *obj)
3926 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3927 Widget_Data *wd = elm_widget_data_get(obj);
3928 if (!wd) return EINA_FALSE;
3933 elm_genlist_selected_item_get(const Evas_Object *obj)
3935 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3936 Widget_Data *wd = elm_widget_data_get(obj);
3937 if (!wd) return NULL;
3938 if (wd->selected) return wd->selected->data;
3942 EAPI const Eina_List *
3943 elm_genlist_selected_items_get(const Evas_Object *obj)
3945 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3946 Widget_Data *wd = elm_widget_data_get(obj);
3947 if (!wd) return NULL;
3948 return wd->selected;
3952 elm_genlist_realized_items_get(const Evas_Object *obj)
3954 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3955 Widget_Data *wd = elm_widget_data_get(obj);
3956 Eina_List *list = NULL;
3958 Eina_Bool done = EINA_FALSE;
3959 if (!wd) return NULL;
3960 EINA_INLIST_FOREACH(wd->blocks, itb)
3968 EINA_LIST_FOREACH(itb->items, l, it)
3970 if (it->realized) list = eina_list_append(list, it);
3982 elm_genlist_at_xy_item_get(const Evas_Object *obj,
3987 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3988 Widget_Data *wd = elm_widget_data_get(obj);
3989 Evas_Coord ox, oy, ow, oh;
3992 if (!wd) return NULL;
3993 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
3995 EINA_INLIST_FOREACH(wd->blocks, itb)
4000 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4001 oy + itb->y - itb->wd->pan_y,
4002 itb->w, itb->h, x, y, 1, 1))
4004 EINA_LIST_FOREACH(itb->items, l, it)
4006 Evas_Coord itx, ity;
4008 itx = ox + itb->x + it->x - itb->wd->pan_x;
4009 ity = oy + itb->y + it->y - itb->wd->pan_y;
4010 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4014 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4015 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4021 lasty = ity + it->item->h;
4026 if (y > lasty) *posret = 1;
4033 elm_genlist_first_item_get(const Evas_Object *obj)
4035 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4036 Widget_Data *wd = elm_widget_data_get(obj);
4037 if (!wd) return NULL;
4038 if (!wd->items) return NULL;
4039 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4040 while ((it) && (it->generation < wd->generation))
4041 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4046 elm_genlist_last_item_get(const Evas_Object *obj)
4048 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4049 Widget_Data *wd = elm_widget_data_get(obj);
4050 if (!wd) return NULL;
4051 if (!wd->items) return NULL;
4052 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4053 while ((it) && (it->generation < wd->generation))
4054 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4059 elm_genlist_item_next_get(const Elm_Gen_Item *it)
4061 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4064 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4065 if ((it) && (it->generation == it->wd->generation)) break;
4067 return (Elm_Gen_Item *)it;
4071 elm_genlist_item_prev_get(const Elm_Gen_Item *it)
4073 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4076 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4077 if ((it) && (it->generation == it->wd->generation)) break;
4079 return (Elm_Gen_Item *)it;
4083 elm_genlist_item_genlist_get(const Elm_Gen_Item *it)
4085 return _elm_genlist_item_widget_get(it);
4089 elm_genlist_item_parent_get(const Elm_Gen_Item *it)
4091 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4096 elm_genlist_item_subitems_clear(Elm_Gen_Item *it)
4098 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4099 Eina_List *tl = NULL, *l;
4102 EINA_LIST_FOREACH(it->item->items, l, it2)
4103 tl = eina_list_append(tl, it2);
4104 EINA_LIST_FREE(tl, it2)
4105 elm_genlist_item_del(it2);
4109 elm_genlist_item_selected_set(Elm_Gen_Item *it,
4112 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4113 Widget_Data *wd = it->wd;
4115 if ((it->generation < wd->generation) || (it->disabled)) return;
4116 selected = !!selected;
4117 if (it->selected == selected) return;
4123 while (wd->selected)
4125 if (it->unhighlight_cb) it->unhighlight_cb(wd->selected->data);
4126 it->unsel_cb(wd->selected->data);
4129 it->highlight_cb(it);
4133 if (it->unhighlight_cb) it->unhighlight_cb(it);
4138 elm_genlist_item_selected_get(const Elm_Gen_Item *it)
4140 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4141 return it->selected;
4145 elm_genlist_item_expanded_set(Elm_Gen_Item *it,
4148 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4149 if (it->item->expanded == expanded) return;
4150 it->item->expanded = expanded;
4151 it->wd->expanded_item = it;
4152 if (it->item->expanded)
4155 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
4156 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
4157 it->wd->auto_scroll_enabled = EINA_TRUE;
4162 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
4163 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
4164 it->wd->auto_scroll_enabled = EINA_FALSE;
4169 elm_genlist_item_expanded_get(const Elm_Gen_Item *it)
4171 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4172 return it->item->expanded;
4176 elm_genlist_item_expanded_depth_get(const Elm_Gen_Item *it)
4178 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, 0);
4179 return it->item->expanded_depth;
4183 elm_genlist_item_disabled_set(Elm_Gen_Item *it,
4186 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4189 if (it->disabled == disabled) return;
4190 if (it->generation < it->wd->generation) return;
4191 it->disabled = !!disabled;
4193 elm_genlist_item_selected_set(it, EINA_FALSE);
4197 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4199 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
4200 EINA_LIST_FOREACH(it->content_objs, l, obj)
4201 elm_widget_disabled_set(obj, disabled);
4206 elm_genlist_item_disabled_get(const Elm_Gen_Item *it)
4208 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4209 if (it->generation < it->wd->generation) return EINA_FALSE;
4210 return it->disabled;
4214 elm_genlist_item_display_only_set(Elm_Gen_Item *it,
4215 Eina_Bool display_only)
4217 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4218 if (it->display_only == display_only) return;
4219 if (it->generation < it->wd->generation) return;
4220 it->display_only = display_only;
4221 it->item->mincalcd = EINA_FALSE;
4222 it->item->updateme = EINA_TRUE;
4223 if (it->item->block) it->item->block->updateme = EINA_TRUE;
4224 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4225 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4229 elm_genlist_item_display_only_get(const Elm_Gen_Item *it)
4231 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4232 if (it->generation < it->wd->generation) return EINA_FALSE;
4233 return it->display_only;
4237 elm_genlist_item_show(Elm_Gen_Item *it)
4239 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4240 Evas_Coord gith = 0;
4241 if (it->generation < it->wd->generation) return;
4242 if ((it->item->queued) || (!it->item->mincalcd))
4244 it->wd->show_item = it;
4245 it->wd->bring_in = EINA_FALSE;
4246 it->item->showme = EINA_TRUE;
4249 if (it->wd->show_item)
4251 it->wd->show_item->item->showme = EINA_FALSE;
4252 it->wd->show_item = NULL;
4254 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4255 gith = it->item->group_item->item->h;
4256 elm_smart_scroller_child_region_show(it->wd->scr,
4257 it->x + it->item->block->x,
4258 it->y + it->item->block->y - gith,
4259 it->item->block->w, it->item->h);
4263 elm_genlist_item_promote(Elm_Gen_Item *it)
4265 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4266 if (it->generation < it->wd->generation) return;
4267 _item_move_before(it, elm_genlist_first_item_get(WIDGET(it)));
4271 elm_genlist_item_demote(Elm_Gen_Item *it)
4273 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4274 if (it->generation < it->wd->generation) return;
4275 _item_move_after(it, elm_genlist_last_item_get(WIDGET(it)));
4279 elm_genlist_item_bring_in(Elm_Gen_Item *it)
4281 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4282 Evas_Coord gith = 0;
4283 if (it->generation < it->wd->generation) return;
4284 if ((it->item->queued) || (!it->item->mincalcd))
4286 it->wd->show_item = it;
4287 it->wd->bring_in = EINA_TRUE;
4288 it->item->showme = EINA_TRUE;
4291 if (it->wd->show_item)
4293 it->wd->show_item->item->showme = EINA_FALSE;
4294 it->wd->show_item = NULL;
4296 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4297 gith = it->item->group_item->item->h;
4298 elm_smart_scroller_region_bring_in(it->wd->scr,
4299 it->x + it->item->block->x,
4300 it->y + it->item->block->y - gith,
4301 it->item->block->w, it->item->h);
4305 elm_genlist_item_top_show(Elm_Gen_Item *it)
4307 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4309 Evas_Coord gith = 0;
4311 if (it->generation < it->wd->generation) return;
4312 if ((it->item->queued) || (!it->item->mincalcd))
4314 it->wd->show_item = it;
4315 it->wd->bring_in = EINA_FALSE;
4316 it->item->showme = EINA_TRUE;
4319 if (it->wd->show_item)
4321 it->wd->show_item->item->showme = EINA_FALSE;
4322 it->wd->show_item = NULL;
4324 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4325 if (it->item->group_item) gith = it->item->group_item->item->h;
4326 elm_smart_scroller_child_region_show(it->wd->scr,
4327 it->x + it->item->block->x,
4328 it->y + it->item->block->y - gith,
4329 it->item->block->w, oh);
4333 elm_genlist_item_top_bring_in(Elm_Gen_Item *it)
4335 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4337 Evas_Coord gith = 0;
4339 if (it->generation < it->wd->generation) return;
4340 if ((it->item->queued) || (!it->item->mincalcd))
4342 it->wd->show_item = it;
4343 it->wd->bring_in = EINA_TRUE;
4344 it->item->showme = EINA_TRUE;
4347 if (it->wd->show_item)
4349 it->wd->show_item->item->showme = EINA_FALSE;
4350 it->wd->show_item = NULL;
4352 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4353 if (it->item->group_item) gith = it->item->group_item->item->h;
4354 elm_smart_scroller_region_bring_in(it->wd->scr,
4355 it->x + it->item->block->x,
4356 it->y + it->item->block->y - gith,
4357 it->item->block->w, oh);
4361 elm_genlist_item_middle_show(Elm_Gen_Item *it)
4363 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4366 if (it->generation < it->wd->generation) return;
4367 if ((it->item->queued) || (!it->item->mincalcd))
4369 it->wd->show_item = it;
4370 it->wd->bring_in = EINA_FALSE;
4371 it->item->showme = EINA_TRUE;
4374 if (it->wd->show_item)
4376 it->wd->show_item->item->showme = EINA_FALSE;
4377 it->wd->show_item = NULL;
4379 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4380 elm_smart_scroller_child_region_show(it->wd->scr,
4381 it->x + it->item->block->x,
4382 it->y + it->item->block->y - oh / 2 +
4383 it->item->h / 2, it->item->block->w, oh);
4387 elm_genlist_item_middle_bring_in(Elm_Gen_Item *it)
4389 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4392 if (it->generation < it->wd->generation) return;
4393 if ((it->item->queued) || (!it->item->mincalcd))
4395 it->wd->show_item = it;
4396 it->wd->bring_in = EINA_TRUE;
4397 it->item->showme = EINA_TRUE;
4400 if (it->wd->show_item)
4402 it->wd->show_item->item->showme = EINA_FALSE;
4403 it->wd->show_item = NULL;
4405 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4406 elm_smart_scroller_region_bring_in(it->wd->scr,
4407 it->x + it->item->block->x,
4408 it->y + it->item->block->y - oh / 2 + it->item->h / 2,
4409 it->item->block->w, oh);
4413 elm_genlist_item_del(Elm_Gen_Item *it)
4415 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4416 if ((it->relcount > 0) || (it->walking > 0))
4418 elm_genlist_item_subitems_clear(it);
4419 if (it->wd->show_item == it) it->wd->show_item = NULL;
4420 _elm_genlist_item_del_notserious(it);
4421 if (it->item->block)
4423 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
4424 it->item->block->changed = EINA_TRUE;
4425 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
4426 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
4430 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
4439 elm_genlist_item_data_set(Elm_Gen_Item *it,
4442 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4443 elm_widget_item_data_set(it, data);
4447 elm_genlist_item_data_get(const Elm_Gen_Item *it)
4449 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4450 return elm_widget_item_data_get(it);
4454 elm_genlist_item_icons_orphan(Elm_Gen_Item *it)
4456 elm_genlist_item_contents_orphan(it);
4460 elm_genlist_item_contents_orphan(Elm_Gen_Item *it)
4462 Evas_Object *content;
4463 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4464 EINA_LIST_FREE(it->content_objs, content)
4466 elm_widget_sub_object_del(WIDGET(it), content);
4467 evas_object_smart_member_del(content);
4468 evas_object_hide(content);
4472 EAPI const Evas_Object *
4473 elm_genlist_item_object_get(const Elm_Gen_Item *it)
4475 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4480 elm_genlist_item_update(Elm_Gen_Item *it)
4482 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4483 if (!it->item->block) return;
4484 if (it->generation < it->wd->generation) return;
4485 it->item->mincalcd = EINA_FALSE;
4486 it->item->updateme = EINA_TRUE;
4487 it->item->block->updateme = EINA_TRUE;
4488 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4489 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4493 elm_genlist_item_fields_update(Elm_Genlist_Item *it,
4495 Elm_Genlist_Item_Field_Flags itf)
4497 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4498 if (!it->item->block) return;
4499 if (it->generation < it->wd->generation) return;
4501 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_LABEL))
4502 _item_text_realize(it, it->base.view, &it->texts, parts);
4503 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
4505 it->content_objs = _item_content_unrealize(it, it->base.view,
4506 &it->contents, parts);
4507 it->content_objs = _item_content_realize(it, it->base.view,
4508 &it->contents, parts);
4510 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
4511 _item_state_realize(it, it->base.view, &it->states, parts);
4515 elm_genlist_item_item_class_update(Elm_Gen_Item *it,
4516 const Elm_Genlist_Item_Class *itc)
4518 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4519 if (!it->item->block) return;
4520 EINA_SAFETY_ON_NULL_RETURN(itc);
4521 if (it->generation < it->wd->generation) return;
4523 it->item->nocache = EINA_TRUE;
4524 elm_genlist_item_update(it);
4527 EAPI const Elm_Genlist_Item_Class *
4528 elm_genlist_item_item_class_get(const Elm_Gen_Item *it)
4530 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4531 if (it->generation < it->wd->generation) return NULL;
4535 static Evas_Object *
4536 _elm_genlist_item_label_create(void *data,
4537 Evas_Object *obj __UNUSED__,
4538 Evas_Object *tooltip,
4539 void *it __UNUSED__)
4541 Evas_Object *label = elm_label_add(tooltip);
4544 elm_object_style_set(label, "tooltip");
4545 elm_object_text_set(label, data);
4550 _elm_genlist_item_label_del_cb(void *data,
4551 Evas_Object *obj __UNUSED__,
4552 void *event_info __UNUSED__)
4554 eina_stringshare_del(data);
4558 elm_genlist_item_tooltip_text_set(Elm_Gen_Item *it,
4561 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4562 text = eina_stringshare_add(text);
4563 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
4565 _elm_genlist_item_label_del_cb);
4569 elm_genlist_item_tooltip_content_cb_set(Elm_Gen_Item *it,
4570 Elm_Tooltip_Item_Content_Cb func,
4572 Evas_Smart_Cb del_cb)
4574 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, error);
4576 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4579 if (it->tooltip.del_cb)
4580 it->tooltip.del_cb((void *)it->tooltip.data,
4583 it->tooltip.content_cb = func;
4584 it->tooltip.data = data;
4585 it->tooltip.del_cb = del_cb;
4589 elm_widget_item_tooltip_content_cb_set(it,
4590 it->tooltip.content_cb,
4591 it->tooltip.data, NULL);
4592 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4593 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
4599 if (del_cb) del_cb((void *)data, NULL, NULL);
4603 elm_genlist_item_tooltip_unset(Elm_Gen_Item *it)
4605 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4606 if ((VIEW(it)) && (it->tooltip.content_cb))
4607 elm_widget_item_tooltip_unset(it);
4609 if (it->tooltip.del_cb)
4610 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4611 it->tooltip.del_cb = NULL;
4612 it->tooltip.content_cb = NULL;
4613 it->tooltip.data = NULL;
4614 it->tooltip.free_size = EINA_FALSE;
4615 if (it->tooltip.style)
4616 elm_genlist_item_tooltip_style_set(it, NULL);
4620 elm_genlist_item_tooltip_style_set(Elm_Gen_Item *it,
4623 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4624 eina_stringshare_replace(&it->tooltip.style, style);
4625 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4629 elm_genlist_item_tooltip_style_get(const Elm_Gen_Item *it)
4631 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4632 return it->tooltip.style;
4636 elm_genlist_item_tooltip_window_mode_set(Elm_Gen_Item *it, Eina_Bool disable)
4638 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4639 it->tooltip.free_size = disable;
4640 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
4645 elm_genlist_item_tooltip_window_mode_get(const Elm_Gen_Item *it)
4647 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4648 return it->tooltip.free_size;
4652 elm_genlist_item_cursor_set(Elm_Gen_Item *it,
4655 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4656 eina_stringshare_replace(&it->mouse_cursor, cursor);
4657 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4661 elm_genlist_item_cursor_get(const Elm_Gen_Item *it)
4663 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4664 return elm_widget_item_cursor_get(it);
4668 elm_genlist_item_cursor_unset(Elm_Gen_Item *it)
4670 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4671 if (!it->mouse_cursor)
4675 elm_widget_item_cursor_unset(it);
4677 eina_stringshare_del(it->mouse_cursor);
4678 it->mouse_cursor = NULL;
4682 elm_genlist_item_cursor_style_set(Elm_Gen_Item *it,
4685 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4686 elm_widget_item_cursor_style_set(it, style);
4690 elm_genlist_item_cursor_style_get(const Elm_Gen_Item *it)
4692 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4693 return elm_widget_item_cursor_style_get(it);
4697 elm_genlist_item_cursor_engine_only_set(Elm_Gen_Item *it,
4698 Eina_Bool engine_only)
4700 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4701 elm_widget_item_cursor_engine_only_set(it, engine_only);
4705 elm_genlist_item_cursor_engine_only_get(const Elm_Gen_Item *it)
4707 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4708 return elm_widget_item_cursor_engine_only_get(it);
4712 elm_genlist_horizontal_set(Evas_Object *obj,
4715 ELM_CHECK_WIDTYPE(obj, widtype);
4716 Widget_Data *wd = elm_widget_data_get(obj);
4718 if (wd->mode == mode) return;
4724 elm_genlist_horizontal_mode_set(Evas_Object *obj,
4727 elm_genlist_horizontal_set(obj, mode);
4731 elm_genlist_horizontal_get(const Evas_Object *obj)
4733 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4734 Widget_Data *wd = elm_widget_data_get(obj);
4735 if (!wd) return ELM_LIST_LAST;
4740 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4742 return elm_genlist_horizontal_get(obj);
4746 elm_genlist_always_select_mode_set(Evas_Object *obj,
4747 Eina_Bool always_select)
4749 ELM_CHECK_WIDTYPE(obj, widtype);
4750 Widget_Data *wd = elm_widget_data_get(obj);
4752 wd->always_select = always_select;
4756 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4758 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4759 Widget_Data *wd = elm_widget_data_get(obj);
4760 if (!wd) return EINA_FALSE;
4761 return wd->always_select;
4765 elm_genlist_no_select_mode_set(Evas_Object *obj,
4766 Eina_Bool no_select)
4768 ELM_CHECK_WIDTYPE(obj, widtype);
4769 Widget_Data *wd = elm_widget_data_get(obj);
4771 wd->no_select = no_select;
4775 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4777 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4778 Widget_Data *wd = elm_widget_data_get(obj);
4779 if (!wd) return EINA_FALSE;
4780 return wd->no_select;
4784 elm_genlist_compress_mode_set(Evas_Object *obj,
4787 ELM_CHECK_WIDTYPE(obj, widtype);
4788 Widget_Data *wd = elm_widget_data_get(obj);
4790 wd->compress = compress;
4791 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
4795 elm_genlist_compress_mode_get(const Evas_Object *obj)
4797 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4798 Widget_Data *wd = elm_widget_data_get(obj);
4799 if (!wd) return EINA_FALSE;
4800 return wd->compress;
4804 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
4805 Eina_Bool height_for_width)
4807 ELM_CHECK_WIDTYPE(obj, widtype);
4808 Widget_Data *wd = elm_widget_data_get(obj);
4810 wd->height_for_width = !!height_for_width;
4811 if (wd->height_for_width)
4813 elm_genlist_homogeneous_set(obj, EINA_FALSE);
4814 elm_genlist_compress_mode_set(obj, EINA_TRUE);
4819 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
4821 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4822 Widget_Data *wd = elm_widget_data_get(obj);
4823 if (!wd) return EINA_FALSE;
4824 return wd->height_for_width;
4828 elm_genlist_bounce_set(Evas_Object *obj,
4832 ELM_CHECK_WIDTYPE(obj, widtype);
4833 Widget_Data *wd = elm_widget_data_get(obj);
4835 elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
4836 wd->h_bounce = h_bounce;
4837 wd->v_bounce = v_bounce;
4841 elm_genlist_bounce_get(const Evas_Object *obj,
4842 Eina_Bool *h_bounce,
4843 Eina_Bool *v_bounce)
4845 ELM_CHECK_WIDTYPE(obj, widtype);
4846 Widget_Data *wd = elm_widget_data_get(obj);
4848 if (h_bounce) *h_bounce = wd->h_bounce;
4849 if (v_bounce) *v_bounce = wd->v_bounce;
4853 elm_genlist_homogeneous_set(Evas_Object *obj,
4854 Eina_Bool homogeneous)
4856 ELM_CHECK_WIDTYPE(obj, widtype);
4857 Widget_Data *wd = elm_widget_data_get(obj);
4859 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
4860 wd->homogeneous = homogeneous;
4864 elm_genlist_homogeneous_get(const Evas_Object *obj)
4866 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4867 Widget_Data *wd = elm_widget_data_get(obj);
4868 if (!wd) return EINA_FALSE;
4869 return wd->homogeneous;
4873 elm_genlist_block_count_set(Evas_Object *obj,
4876 ELM_CHECK_WIDTYPE(obj, widtype);
4877 Widget_Data *wd = elm_widget_data_get(obj);
4879 wd->max_items_per_block = n;
4880 wd->item_cache_max = wd->max_items_per_block * 2;
4881 _item_cache_clean(wd);
4885 elm_genlist_block_count_get(const Evas_Object *obj)
4887 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4888 Widget_Data *wd = elm_widget_data_get(obj);
4890 return wd->max_items_per_block;
4894 elm_genlist_longpress_timeout_set(Evas_Object *obj,
4897 ELM_CHECK_WIDTYPE(obj, widtype);
4898 Widget_Data *wd = elm_widget_data_get(obj);
4900 wd->longpress_timeout = timeout;
4904 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
4906 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4907 Widget_Data *wd = elm_widget_data_get(obj);
4909 return wd->longpress_timeout;
4913 elm_genlist_scroller_policy_set(Evas_Object *obj,
4914 Elm_Scroller_Policy policy_h,
4915 Elm_Scroller_Policy policy_v)
4917 ELM_CHECK_WIDTYPE(obj, widtype);
4918 Widget_Data *wd = elm_widget_data_get(obj);
4919 if ((!wd) || (!wd->scr)) return;
4920 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4921 (policy_v >= ELM_SCROLLER_POLICY_LAST))
4923 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
4927 elm_genlist_scroller_policy_get(const Evas_Object *obj,
4928 Elm_Scroller_Policy *policy_h,
4929 Elm_Scroller_Policy *policy_v)
4931 ELM_CHECK_WIDTYPE(obj, widtype);
4932 Widget_Data *wd = elm_widget_data_get(obj);
4933 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
4934 if ((!wd) || (!wd->scr)) return;
4935 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
4936 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
4937 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
4941 elm_genlist_realized_items_update(Evas_Object *obj)
4943 ELM_CHECK_WIDTYPE(obj, widtype);
4945 Eina_List *list, *l;
4948 list = elm_genlist_realized_items_get(obj);
4949 EINA_LIST_FOREACH(list, l, it)
4950 elm_genlist_item_update(it);
4954 elm_genlist_item_mode_set(Elm_Gen_Item *it,
4955 const char *mode_type,
4958 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4959 Widget_Data *wd = it->wd;
4964 if (!mode_type) return;
4965 if ((it->generation < it->wd->generation) || (it->disabled)) return;
4967 if ((wd->mode_item == it) &&
4968 (!strcmp(mode_type, wd->mode_type)) &&
4971 if (!wd->mode_item_style) return;
4972 it->mode_set = mode_set;
4976 EINA_LIST_FOREACH(wd->selected, l, it2)
4978 elm_genlist_item_selected_set(it2, EINA_FALSE);
4982 it2 = elm_genlist_selected_item_get(wd->obj);
4983 if ((it2) && (it2->realized))
4984 elm_genlist_item_selected_set(it2, EINA_FALSE);
4987 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
4989 ((it == wd->mode_item) && (!mode_set)))
4990 _item_mode_unset(wd);
4992 eina_stringshare_replace(&wd->mode_type, mode_type);
4993 if (mode_set) _item_mode_set(it);
4998 elm_genlist_mode_item_style_get(const Evas_Object *obj)
5000 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5001 Widget_Data *wd = elm_widget_data_get(obj);
5002 if (!wd) return NULL;
5003 return wd->mode_item_style;
5007 elm_genlist_mode_item_style_set(Evas_Object *obj, const char *style)
5009 ELM_CHECK_WIDTYPE(obj, widtype);
5010 Widget_Data *wd = elm_widget_data_get(obj);
5012 if ((style == wd->mode_item_style) || (style && wd->mode_item_style &&
5013 (!strcmp(style, wd->mode_item_style))))
5015 eina_stringshare_replace(&wd->mode_item_style, style);
5016 elm_genlist_realized_items_update(obj);
5020 elm_genlist_mode_get(const Evas_Object *obj)
5022 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5023 Widget_Data *wd = elm_widget_data_get(obj);
5024 if (!wd) return NULL;
5025 return wd->mode_type;
5028 EAPI const Elm_Gen_Item *
5029 elm_genlist_mode_item_get(const Evas_Object *obj)
5031 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5032 Widget_Data *wd = elm_widget_data_get(obj);
5033 if (!wd) return NULL;
5034 return wd->mode_item;
5038 elm_genlist_reorder_mode_set(Evas_Object *obj,
5039 Eina_Bool reorder_mode)
5041 ELM_CHECK_WIDTYPE(obj, widtype);
5042 Widget_Data *wd = elm_widget_data_get(obj);
5044 wd->reorder_mode = reorder_mode;
5048 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5050 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5051 Widget_Data *wd = elm_widget_data_get(obj);
5052 if (!wd) return EINA_FALSE;
5053 return wd->reorder_mode;
5056 /* for gengrid as of now */
5058 _elm_genlist_page_relative_set(Evas_Object *obj,
5062 Evas_Coord pagesize_h;
5063 Evas_Coord pagesize_v;
5065 ELM_CHECK_WIDTYPE(obj, widtype);
5066 Widget_Data *wd = elm_widget_data_get(obj);
5069 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5070 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5074 /* for gengrid as of now */
5076 _elm_genlist_page_relative_get(const Evas_Object *obj,
5080 ELM_CHECK_WIDTYPE(obj, widtype);
5081 Widget_Data *wd = elm_widget_data_get(obj);
5084 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5087 /* for gengrid as of now */
5089 _elm_genlist_page_size_set(Evas_Object *obj,
5090 Evas_Coord h_pagesize,
5091 Evas_Coord v_pagesize)
5096 ELM_CHECK_WIDTYPE(obj, widtype);
5097 Widget_Data *wd = elm_widget_data_get(obj);
5099 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5100 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5104 /* for gengrid as of now */
5106 _elm_genlist_current_page_get(const Evas_Object *obj,
5110 ELM_CHECK_WIDTYPE(obj, widtype);
5111 Widget_Data *wd = elm_widget_data_get(obj);
5114 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5117 /* for gengrid as of now */
5119 _elm_genlist_last_page_get(const Evas_Object *obj,
5123 ELM_CHECK_WIDTYPE(obj, widtype);
5124 Widget_Data *wd = elm_widget_data_get(obj);
5127 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5130 /* for gengrid as of now */
5132 _elm_genlist_page_show(const Evas_Object *obj,
5136 ELM_CHECK_WIDTYPE(obj, widtype);
5137 Widget_Data *wd = elm_widget_data_get(obj);
5140 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5143 /* for gengrid as of now */
5145 _elm_genlist_page_bring_in(const Evas_Object *obj,
5149 ELM_CHECK_WIDTYPE(obj, widtype);
5150 Widget_Data *wd = elm_widget_data_get(obj);
5153 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5157 _elm_genlist_item_widget_get(const Elm_Gen_Item *it)
5159 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
5164 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5167 Evas_Object *content;
5169 if (!it->realized) return;
5170 if (it->wd->reorder_it == it) return;
5171 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5173 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5176 ecore_timer_del(it->long_timer);
5177 it->long_timer = NULL;
5180 elm_widget_stringlist_free(it->texts);
5182 elm_widget_stringlist_free(it->contents);
5183 it->contents = NULL;
5184 elm_widget_stringlist_free(it->states);
5187 EINA_LIST_FREE(it->content_objs, content)
5188 evas_object_del(content);
5190 it->unrealize_cb(it);
5192 it->realized = EINA_FALSE;
5193 it->want_unrealize = EINA_FALSE;
5194 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5195 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5199 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5201 elm_widget_item_pre_notify_del(it);
5202 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5203 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5205 if (it->itc->func.del)
5206 it->itc->func.del((void *)it->base.data, WIDGET(it));
5210 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5212 _elm_genlist_item_del_notserious(it);
5213 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5214 if (it->tooltip.del_cb)
5215 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5216 it->wd->walking -= it->walking;
5217 if (it->long_timer) ecore_timer_del(it->long_timer);
5219 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5221 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5222 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5225 elm_widget_item_del(it);