3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
7 #include "elm_gen_common.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 #define ELM_GENLIST_CHECK_ITC_VER(itc) \
29 ERR("Genlist_Item_Class(itc) is NULL"); \
32 if (itc->version != ELM_GENLIST_ITEM_CLASS_VERSION) \
34 ERR("Genlist_Item_Class version mismatched! required = (%d), current = (%d)", itc->version, ELM_GENLIST_ITEM_CLASS_VERSION); \
40 typedef struct _Item_Block Item_Block;
41 typedef struct _Item_Cache Item_Cache;
43 struct Elm_Gen_Item_Type
48 Evas_Coord w, h, minw, minh;
49 Elm_Gen_Item *group_item;
50 Elm_Genlist_Item_Flags flags;
51 Eina_List *mode_texts, *mode_contents, *mode_states, *mode_content_objs;
52 Eina_List *edit_texts, *edit_contents, *edit_states, *edit_content_objs;
53 Ecore_Timer *swipe_timer;
54 Evas_Coord scrl_x, scrl_y, old_scrl_y;
57 Evas_Object *mode_view;
63 Eina_Bool want_realize : 1;
64 Eina_Bool expanded : 1;
65 Eina_Bool mincalcd : 1;
68 Eina_Bool updateme : 1;
69 Eina_Bool nocache : 1;
70 Eina_Bool stacking_even : 1;
71 Eina_Bool nostacking : 1;
72 Eina_Bool move_effect_enabled : 1;
73 Eina_Bool edit_mode_item_realized : 1;
84 Evas_Coord x, y, w, h, minw, minh;
86 int item_position_stamp;
88 Eina_Bool position_update : 1;
89 Eina_Bool want_unrealize : 1;
90 Eina_Bool realized : 1;
91 Eina_Bool changed : 1;
92 Eina_Bool updateme : 1;
94 Eina_Bool must_recalc : 1;
101 Evas_Object *base_view, *spacer;
103 const char *item_style; // it->itc->item_style
104 Eina_Bool tree : 1; // it->group
105 Eina_Bool compress : 1; // it->wd->compress
107 Eina_Bool selected : 1; // it->selected
108 Eina_Bool disabled : 1; // it->disabled
109 Eina_Bool expanded : 1; // it->item->expanded
112 static const char *widtype = NULL;
113 static void _item_cache_zero(Widget_Data *wd);
114 static void _del_hook(Evas_Object *obj);
115 static void _mirrored_set(Evas_Object *obj,
117 static void _theme_hook(Evas_Object *obj);
118 static void _show_region_hook(void *data,
120 static void _sizing_eval(Evas_Object *obj);
121 static void _item_realize(Elm_Gen_Item *it,
124 static void _item_unrealize_cb(Elm_Gen_Item *it);
125 static void _item_block_unrealize(Item_Block *itb);
126 static void _calc_job(void *data);
127 static void _on_focus_hook(void *data,
129 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
130 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
131 static Eina_Bool _item_single_select_up(Widget_Data *wd);
132 static Eina_Bool _item_single_select_down(Widget_Data *wd);
133 static Eina_Bool _event_hook(Evas_Object *obj,
135 Evas_Callback_Type type,
137 static void _signal_emit_hook(Evas_Object *obj,
138 const char *emission,
140 static Eina_Bool _deselect_all_items(Widget_Data *wd);
141 static void _pan_calculate(Evas_Object *obj);
142 static void _pan_max_get(Evas_Object *obj,
145 static void _item_position(Elm_Gen_Item *it,
149 static void _mode_item_realize(Elm_Gen_Item *it);
150 static void _mode_item_unrealize(Elm_Gen_Item *it);
151 static void _item_mode_set(Elm_Gen_Item *it);
152 static void _item_mode_unset(Widget_Data *wd);
153 static void _edit_mode_item_position(Elm_Gen_Item *it, int itx, int ity);
154 static void _edit_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on);
155 static void _edit_mode_item_unrealize(Elm_Gen_Item *it);
156 static void _group_items_recalc(void *data);
157 static void _item_move_after(Elm_Gen_Item *it,
158 Elm_Gen_Item *after);
159 static void _item_move_before(Elm_Gen_Item *it,
160 Elm_Gen_Item *before);
161 static void _item_auto_scroll(Widget_Data *wd);
162 static void _elm_genlist_clear(Evas_Object *obj,
164 static void _pan_child_size_get(Evas_Object *obj,
168 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
170 static const char SIG_ACTIVATED[] = "activated";
171 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
172 static const char SIG_SELECTED[] = "selected";
173 static const char SIG_UNSELECTED[] = "unselected";
174 static const char SIG_EXPANDED[] = "expanded";
175 static const char SIG_CONTRACTED[] = "contracted";
176 static const char SIG_EXPAND_REQUEST[] = "expand,request";
177 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
178 static const char SIG_REALIZED[] = "realized";
179 static const char SIG_UNREALIZED[] = "unrealized";
180 static const char SIG_DRAG_START_UP[] = "drag,start,up";
181 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
182 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
183 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
184 static const char SIG_DRAG_STOP[] = "drag,stop";
185 static const char SIG_DRAG[] = "drag";
186 static const char SIG_LONGPRESSED[] = "longpressed";
187 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
188 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
189 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
190 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
191 static const char SIG_EDGE_TOP[] = "edge,top";
192 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
193 static const char SIG_EDGE_LEFT[] = "edge,left";
194 static const char SIG_EDGE_RIGHT[] = "edge,right";
195 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
196 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
197 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
198 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
199 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
200 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
201 static const char SIG_SWIPE[] = "swipe";
202 static const char SIG_MOVED[] = "moved";
203 static const char SIG_INDEX_UPDATE[] = "index,update";
205 static const Evas_Smart_Cb_Description _signals[] = {
206 {SIG_CLICKED_DOUBLE, ""},
209 {SIG_UNSELECTED, ""},
211 {SIG_CONTRACTED, ""},
212 {SIG_EXPAND_REQUEST, ""},
213 {SIG_CONTRACT_REQUEST, ""},
215 {SIG_UNREALIZED, ""},
216 {SIG_DRAG_START_UP, ""},
217 {SIG_DRAG_START_DOWN, ""},
218 {SIG_DRAG_START_LEFT, ""},
219 {SIG_DRAG_START_RIGHT, ""},
222 {SIG_LONGPRESSED, ""},
223 {SIG_SCROLL_ANIM_START, ""},
224 {SIG_SCROLL_ANIM_STOP, ""},
225 {SIG_SCROLL_DRAG_START, ""},
226 {SIG_SCROLL_DRAG_STOP, ""},
228 {SIG_EDGE_BOTTOM, ""},
230 {SIG_EDGE_RIGHT, ""},
231 {SIG_MULTI_SWIPE_LEFT, ""},
232 {SIG_MULTI_SWIPE_RIGHT, ""},
233 {SIG_MULTI_SWIPE_UP, ""},
234 {SIG_MULTI_SWIPE_DOWN, ""},
235 {SIG_MULTI_PINCH_OUT, ""},
236 {SIG_MULTI_PINCH_IN, ""},
243 #undef ELM_CHECK_WIDTYPE
244 #define ELM_CHECK_WIDTYPE(obj, widtype) \
245 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
246 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
247 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
248 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
249 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
251 static const char *_gengrid = NULL;
252 static const char *_genlist = NULL;
254 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
256 elm_genlist_type_check(const Evas_Object *obj,
259 const char *provided, *expected = "(unknown)";
260 static int abort_on_warn = -1;
261 provided = elm_widget_type_get(obj);
262 if (!_genlist) _genlist = eina_stringshare_add("genlist");
263 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
264 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
266 if ((!provided) || (!provided[0]))
268 provided = evas_object_type_get(obj);
269 if ((!provided) || (!provided[0]))
270 provided = "(unknown)";
272 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
273 if (abort_on_warn == -1)
275 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
276 else abort_on_warn = 0;
278 if (abort_on_warn == 1) abort();
283 _event_hook(Evas_Object *obj,
284 Evas_Object *src __UNUSED__,
285 Evas_Callback_Type type,
288 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
289 Evas_Event_Key_Down *ev = event_info;
290 Widget_Data *wd = elm_widget_data_get(obj);
291 Evas_Coord pan_max_x = 0, pan_max_y = 0;
292 if (!wd) return EINA_FALSE;
293 if (!wd->items) return EINA_FALSE;
294 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
295 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
297 Elm_Object_Item *it = NULL;
300 Evas_Coord step_x = 0;
301 Evas_Coord step_y = 0;
304 Evas_Coord page_x = 0;
305 Evas_Coord page_y = 0;
307 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
308 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
309 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
310 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
312 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
316 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
320 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
322 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
323 (_item_multi_select_up(wd)))
324 || (_item_single_select_up(wd)))
326 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
332 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
334 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
335 (_item_multi_select_down(wd)))
336 || (_item_single_select_down(wd)))
338 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
344 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
346 it = elm_genlist_first_item_get(obj);
347 elm_genlist_item_bring_in(it);
348 elm_genlist_item_selected_set(it, EINA_TRUE);
349 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
352 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
354 it = elm_genlist_last_item_get(obj);
355 elm_genlist_item_bring_in(it);
356 elm_genlist_item_selected_set(it, EINA_TRUE);
357 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
360 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
363 y -= -(page_y * v_h) / 100;
367 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
370 y += -(page_y * v_h) / 100;
374 else if (!strcmp(ev->keyname, "Escape"))
376 if (!_deselect_all_items(wd)) return EINA_FALSE;
377 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
380 else if (((!strcmp(ev->keyname, "Return")) ||
381 (!strcmp(ev->keyname, "KP_Enter")) ||
382 (!strcmp(ev->keyname, "space")))
383 && (!wd->multi) && (wd->selected))
385 it = elm_genlist_selected_item_get(obj);
386 elm_genlist_item_expanded_set(it,
387 !elm_genlist_item_expanded_get(it));
388 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
390 else return EINA_FALSE;
392 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
393 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
395 if (x > pan_max_x) x = pan_max_x;
397 if (y > pan_max_y) y = pan_max_y;
398 elm_smart_scroller_child_pos_set(wd->scr, x, y);
403 _deselect_all_items(Widget_Data *wd)
405 if (!wd->selected) return EINA_FALSE;
407 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
413 _item_multi_select_up(Widget_Data *wd)
415 if (!wd->selected) return EINA_FALSE;
416 if (!wd->multi) return EINA_FALSE;
418 Elm_Object_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
419 if (!prev) return EINA_TRUE;
421 if (elm_genlist_item_selected_get(prev))
423 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
424 wd->last_selected_item = prev;
425 elm_genlist_item_show(wd->last_selected_item);
429 elm_genlist_item_selected_set(prev, EINA_TRUE);
430 elm_genlist_item_show(prev);
436 _item_multi_select_down(Widget_Data *wd)
438 if (!wd->selected) return EINA_FALSE;
439 if (!wd->multi) return EINA_FALSE;
441 Elm_Object_Item *next;
442 next = elm_genlist_item_next_get(wd->last_selected_item);
443 if (!next) return EINA_TRUE;
445 if (elm_genlist_item_selected_get(next))
447 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
448 wd->last_selected_item = next;
449 elm_genlist_item_show(wd->last_selected_item);
453 elm_genlist_item_selected_set(next, EINA_TRUE);
454 elm_genlist_item_show(next);
460 _item_single_select_up(Widget_Data *wd)
465 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
466 while ((prev) && (prev->generation < wd->generation))
467 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
469 else prev = (Elm_Gen_Item *) elm_genlist_item_prev_get(wd->last_selected_item);
471 if (!prev) return EINA_FALSE;
473 _deselect_all_items(wd);
475 elm_genlist_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE);
476 elm_genlist_item_show((Elm_Object_Item *) prev);
481 _item_single_select_down(Widget_Data *wd)
486 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
487 while ((next) && (next->generation < wd->generation))
488 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
490 else next = (Elm_Gen_Item *) elm_genlist_item_next_get(wd->last_selected_item);
492 if (!next) return EINA_FALSE;
494 _deselect_all_items(wd);
496 elm_genlist_item_selected_set((Elm_Object_Item *) next, EINA_TRUE);
497 elm_genlist_item_show((Elm_Object_Item *) next);
502 _on_focus_hook(void *data __UNUSED__,
505 Widget_Data *wd = elm_widget_data_get(obj);
507 if (elm_widget_focus_get(obj))
509 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
510 evas_object_focus_set(wd->obj, EINA_TRUE);
511 if ((wd->selected) && (!wd->last_selected_item))
512 wd->last_selected_item = eina_list_data_get(wd->selected);
516 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
517 evas_object_focus_set(wd->obj, EINA_FALSE);
522 _del_hook(Evas_Object *obj)
524 Widget_Data *wd = elm_widget_data_get(obj);
526 _item_cache_zero(wd);
527 if (wd->calc_job) ecore_job_del(wd->calc_job);
528 if (wd->update_job) ecore_job_del(wd->update_job);
529 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
530 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
531 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
532 if (wd->mode_type) eina_stringshare_del(wd->mode_type);
533 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
538 _del_pre_hook(Evas_Object *obj)
540 Widget_Data *wd = elm_widget_data_get(obj);
542 if (wd->edit_mode) elm_genlist_edit_mode_set(wd->obj, EINA_FALSE);
543 elm_genlist_clear(obj);
544 evas_object_del(wd->pan_smart);
545 wd->pan_smart = NULL;
549 _mirrored_set(Evas_Object *obj,
552 Widget_Data *wd = elm_widget_data_get(obj);
554 _item_cache_zero(wd);
555 elm_smart_scroller_mirrored_set(wd->scr, rtl);
559 _theme_hook(Evas_Object *obj)
561 Widget_Data *wd = elm_widget_data_get(obj);
564 evas_event_freeze(evas_object_evas_get(wd->obj));
565 _item_cache_zero(wd);
566 _elm_widget_mirrored_reload(obj);
567 _mirrored_set(obj, elm_widget_mirrored_get(obj));
568 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
569 elm_widget_style_get(obj));
570 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
571 wd->item_width = wd->item_height = 0;
572 wd->group_item_width = wd->group_item_height = 0;
573 wd->minw = wd->minh = wd->realminw = 0;
574 EINA_INLIST_FOREACH(wd->blocks, itb)
579 if (itb->realized) _item_block_unrealize(itb);
580 EINA_LIST_FOREACH(itb->items, l, it)
581 it->item->mincalcd = EINA_FALSE;
583 itb->changed = EINA_TRUE;
585 if (wd->calc_job) ecore_job_del(wd->calc_job);
586 wd->calc_job = ecore_job_add(_calc_job, wd);
588 evas_event_thaw(evas_object_evas_get(wd->obj));
589 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
593 _show_region_hook(void *data,
596 Widget_Data *wd = elm_widget_data_get(data);
597 Evas_Coord x, y, w, h;
599 elm_widget_show_region_get(obj, &x, &y, &w, &h);
600 //x & y are screen coordinates, Add with pan coordinates
603 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
607 _translate_hook(Evas_Object *obj)
609 evas_object_smart_callback_call(obj, "language,changed", NULL);
613 _sizing_eval(Evas_Object *obj)
615 Widget_Data *wd = elm_widget_data_get(obj);
616 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
618 evas_object_size_hint_min_get(wd->scr, &minw, &minh);
619 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
621 if (wd->height_for_width)
625 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
626 if ((vw != 0) && (vw != wd->prev_viewport_w))
630 wd->prev_viewport_w = vw;
631 EINA_INLIST_FOREACH(wd->blocks, itb)
633 itb->must_recalc = EINA_TRUE;
635 if (wd->calc_job) ecore_job_del(wd->calc_job);
636 wd->calc_job = ecore_job_add(_calc_job, wd);
639 if (wd->mode == ELM_LIST_LIMIT)
645 elm_smart_scroller_child_viewport_size_get(wd->scr, &vmw, &vmh);
646 edje_object_size_min_calc
647 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
654 edje_object_size_min_calc
655 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
659 evas_object_size_hint_min_set(obj, minw, minh);
660 evas_object_size_hint_max_set(obj, maxw, maxh);
664 _signal_emit_hook(Evas_Object *obj,
665 const char *emission,
668 Widget_Data *wd = elm_widget_data_get(obj);
669 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
674 _item_highlight(Elm_Gen_Item *it)
676 const char *selectraise;
677 if ((it->wd->no_select) || (it->generation < it->wd->generation) ||
678 (it->highlighted) || elm_widget_item_disabled_get(it) ||
679 (it->display_only) || (it->item->mode_view))
681 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
682 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,selected", "elm");
683 selectraise = edje_object_data_get(VIEW(it), "selectraise");
684 if ((selectraise) && (!strcmp(selectraise, "on")))
686 if (it->edit_obj) evas_object_raise(it->edit_obj);
687 else evas_object_raise(VIEW(it));
688 if ((it->item->group_item) && (it->item->group_item->realized))
689 evas_object_raise(it->item->VIEW(group_item));
691 it->highlighted = EINA_TRUE;
695 _item_unhighlight(Elm_Gen_Item *it)
697 if ((it->generation < it->wd->generation) || (!it->highlighted)) return;
698 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
699 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,unselected", "elm");
700 if (!it->item->nostacking)
702 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
704 if (it->edit_obj) evas_object_lower(it->edit_obj);
705 else evas_object_lower(VIEW(it));
709 if (it->edit_obj) evas_object_raise(it->edit_obj);
710 else evas_object_raise(VIEW(it));
713 it->highlighted = EINA_FALSE;
717 _item_block_position_update(Eina_Inlist *list, int idx)
721 EINA_INLIST_FOREACH(list, tmp)
723 tmp->position = idx++;
724 tmp->position_update = EINA_TRUE;
729 _item_position_update(Eina_List *list, int idx)
734 EINA_LIST_FOREACH(list, l, it)
736 it->position = idx++;
737 it->position_update = EINA_TRUE;
742 _item_block_del(Elm_Gen_Item *it)
745 Item_Block *itb = it->item->block;
747 itb->items = eina_list_remove(itb->items, it);
749 itb->changed = EINA_TRUE;
750 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
751 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
754 il = EINA_INLIST_GET(itb);
755 Item_Block *itbn = (Item_Block *)(il->next);
757 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
760 _item_block_position_update(il->next, itb->position);
761 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
764 if (itbn) itbn->changed = EINA_TRUE;
768 if (itb->count < itb->wd->max_items_per_block/2)
770 il = EINA_INLIST_GET(itb);
771 Item_Block *itbp = (Item_Block *)(il->prev);
772 Item_Block *itbn = (Item_Block *)(il->next);
773 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
777 EINA_LIST_FREE(itb->items, it2)
779 it2->item->block = itbp;
780 itbp->items = eina_list_append(itbp->items, it2);
782 itbp->changed = EINA_TRUE;
784 _item_block_position_update(EINA_INLIST_GET(itb)->next,
786 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
787 EINA_INLIST_GET(itb));
790 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
794 Eina_List *last = eina_list_last(itb->items);
795 Elm_Gen_Item *it2 = last->data;
797 it2->item->block = itbn;
798 itb->items = eina_list_remove_list(itb->items, last);
799 itbn->items = eina_list_prepend(itbn->items, it2);
801 itbn->changed = EINA_TRUE;
803 _item_block_position_update(EINA_INLIST_GET(itb)->next,
806 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
814 _item_del(Elm_Gen_Item *it)
816 Evas_Object *obj = WIDGET(it);
818 evas_event_freeze(evas_object_evas_get(obj));
819 elm_genlist_item_subitems_clear((Elm_Object_Item *) it);
820 if (it->wd->show_item == it) it->wd->show_item = NULL;
821 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
822 if (it->item->edit_mode_item_realized) _edit_mode_item_unrealize(it);
823 if (it->item->block) _item_block_del(it);
824 if (it->item->queued)
825 it->wd->queue = eina_list_remove(it->wd->queue, it);
826 if (it->wd->anchor_item == it)
828 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
829 if (!it->wd->anchor_item)
830 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
832 if (it->wd->expanded_item == it) it->wd->expanded_item = NULL;
834 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
835 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
836 _elm_genlist_item_del_serious(it);
837 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
838 evas_event_thaw(evas_object_evas_get(obj));
839 evas_event_thaw_eval(evas_object_evas_get(obj));
843 _clear_cb(Widget_Data *wd)
845 wd->anchor_item = NULL;
848 Item_Block *itb = (Item_Block *)(wd->blocks);
850 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
851 if (itb->items) eina_list_free(itb->items);
854 if (wd->queue_idle_enterer)
856 ecore_idle_enterer_del(wd->queue_idle_enterer);
857 wd->queue_idle_enterer = NULL;
859 if (wd->must_recalc_idler)
861 ecore_idler_del(wd->must_recalc_idler);
862 wd->must_recalc_idler = NULL;
864 if (wd->queue) wd->queue = eina_list_free(wd->queue);
865 if (wd->reorder_move_animator)
867 ecore_animator_del(wd->reorder_move_animator);
868 wd->reorder_move_animator = NULL;
870 wd->show_item = NULL;
871 wd->reorder_old_pan_y = 0;
875 _item_unselect(Elm_Gen_Item *it)
877 if ((it->generation < it->wd->generation) || (!it->selected)) return;
878 it->selected = EINA_FALSE;
879 it->wd->selected = eina_list_remove(it->wd->selected, it);
880 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
884 _mouse_move(void *data,
885 Evas *evas __UNUSED__,
889 Elm_Gen_Item *it = data;
890 Evas_Event_Mouse_Move *ev = event_info;
891 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
892 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
894 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
896 if (!it->wd->on_hold)
898 it->wd->on_hold = EINA_TRUE;
899 if ((!it->wd->wasselected) && (!it->flipped))
901 _item_unhighlight(it);
906 if (it->wd->multitouched)
908 it->wd->cur_x = ev->cur.canvas.x;
909 it->wd->cur_y = ev->cur.canvas.y;
912 if ((it->dragging) && (it->down))
914 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
917 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
918 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
919 if (abs((it->wd->history[it->wd->movements].x -
920 it->wd->history[0].x)) > 40)
921 it->wd->swipe = EINA_TRUE;
927 ecore_timer_del(it->long_timer);
928 it->long_timer = NULL;
930 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
933 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
937 ecore_timer_del(it->long_timer);
938 it->long_timer = NULL;
940 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
942 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
943 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
945 if (!it->wd->reorder_start_y)
946 it->wd->reorder_start_y = it->item->block->y + it->y;
950 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
951 y_pos = oy + oh - it->wd->reorder_it->item->h;
956 _item_position(it, it->edit_obj, it->item->scrl_x, y_pos);
958 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
960 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
961 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
965 if (!it->display_only)
966 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
967 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
968 x = ev->cur.canvas.x - x;
969 y = ev->cur.canvas.y - y;
972 if (adx < 0) adx = -dx;
975 if (ady < 0) ady = -dy;
978 if ((adx > minw) || (ady > minh))
980 it->dragging = EINA_TRUE;
983 ecore_timer_del(it->long_timer);
984 it->long_timer = NULL;
986 if (!it->wd->wasselected)
988 _item_unhighlight(it);
994 evas_object_smart_callback_call(WIDGET(it),
995 SIG_DRAG_START_UP, it);
999 evas_object_smart_callback_call(WIDGET(it),
1000 SIG_DRAG_START_LEFT, it);
1002 evas_object_smart_callback_call(WIDGET(it),
1003 SIG_DRAG_START_RIGHT, it);
1009 evas_object_smart_callback_call(WIDGET(it),
1010 SIG_DRAG_START_DOWN, it);
1014 evas_object_smart_callback_call(WIDGET(it),
1015 SIG_DRAG_START_LEFT, it);
1017 evas_object_smart_callback_call(WIDGET(it),
1018 SIG_DRAG_START_RIGHT, it);
1025 _long_press(void *data)
1027 Elm_Gen_Item *it = data, *it_tmp;
1028 Eina_List *list, *l;
1030 it->long_timer = NULL;
1031 if (elm_widget_item_disabled_get(it) || (it->dragging) || (it->display_only))
1032 return ECORE_CALLBACK_CANCEL;
1033 it->wd->longpressed = EINA_TRUE;
1034 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1035 if ((it->wd->reorder_mode) && (!it->group))
1037 it->wd->reorder_it = it;
1038 it->wd->reorder_start_y = 0;
1040 evas_object_raise(it->edit_obj);
1042 evas_object_raise(VIEW(it));
1044 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1045 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1047 list = elm_genlist_realized_items_get(it->wd->obj);
1048 EINA_LIST_FOREACH(list, l, it_tmp)
1050 if (it != it_tmp) _item_unselect(it_tmp);
1052 if (elm_genlist_item_expanded_get((Elm_Object_Item *) it))
1054 elm_genlist_item_expanded_set((Elm_Object_Item *) it, EINA_FALSE);
1055 return ECORE_CALLBACK_RENEW;
1058 if (!it->wd->edit_mode)
1059 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1061 return ECORE_CALLBACK_CANCEL;
1065 _swipe(Elm_Gen_Item *it)
1070 if ((it->display_only) || elm_widget_item_disabled_get(it)) return;
1071 it->wd->swipe = EINA_FALSE;
1072 for (i = 0; i < it->wd->movements; i++)
1074 sum += it->wd->history[i].x;
1075 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1078 sum /= it->wd->movements;
1079 if (abs(sum - it->wd->history[0].x) <= 10) return;
1080 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1084 _swipe_cancel(void *data)
1086 Elm_Gen_Item *it = data;
1088 if (!it) return ECORE_CALLBACK_CANCEL;
1089 it->wd->swipe = EINA_FALSE;
1090 it->wd->movements = 0;
1091 return ECORE_CALLBACK_RENEW;
1095 _multi_cancel(void *data)
1097 Widget_Data *wd = data;
1099 if (!wd) return ECORE_CALLBACK_CANCEL;
1100 wd->multi_timeout = EINA_TRUE;
1101 return ECORE_CALLBACK_RENEW;
1105 _multi_touch_gesture_eval(void *data)
1107 Elm_Gen_Item *it = data;
1109 it->wd->multitouched = EINA_FALSE;
1110 if (it->wd->multi_timer)
1112 ecore_timer_del(it->wd->multi_timer);
1113 it->wd->multi_timer = NULL;
1115 if (it->wd->multi_timeout)
1117 it->wd->multi_timeout = EINA_FALSE;
1121 Evas_Coord minw = 0, minh = 0;
1122 Evas_Coord off_x, off_y, off_mx, off_my;
1124 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1125 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1126 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1127 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1128 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1130 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1132 if ((off_x + off_mx) > (off_y + off_my))
1134 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1135 evas_object_smart_callback_call(WIDGET(it),
1136 SIG_MULTI_SWIPE_RIGHT, it);
1137 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1138 evas_object_smart_callback_call(WIDGET(it),
1139 SIG_MULTI_SWIPE_LEFT, it);
1140 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1141 evas_object_smart_callback_call(WIDGET(it),
1142 SIG_MULTI_PINCH_OUT, it);
1144 evas_object_smart_callback_call(WIDGET(it),
1145 SIG_MULTI_PINCH_IN, it);
1149 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1150 evas_object_smart_callback_call(WIDGET(it),
1151 SIG_MULTI_SWIPE_DOWN, it);
1152 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1153 evas_object_smart_callback_call(WIDGET(it),
1154 SIG_MULTI_SWIPE_UP, it);
1155 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1156 evas_object_smart_callback_call(WIDGET(it),
1157 SIG_MULTI_PINCH_OUT, it);
1159 evas_object_smart_callback_call(WIDGET(it),
1160 SIG_MULTI_PINCH_IN, it);
1163 it->wd->multi_timeout = EINA_FALSE;
1167 _multi_down(void *data,
1168 Evas *evas __UNUSED__,
1169 Evas_Object *obj __UNUSED__,
1172 Elm_Gen_Item *it = data;
1173 Evas_Event_Multi_Down *ev = event_info;
1175 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1176 it->wd->multi_device = ev->device;
1177 it->wd->multi_down = EINA_TRUE;
1178 it->wd->multitouched = EINA_TRUE;
1179 it->wd->prev_mx = ev->canvas.x;
1180 it->wd->prev_my = ev->canvas.y;
1181 if (!it->wd->wasselected)
1183 _item_unhighlight(it);
1186 it->wd->wasselected = EINA_FALSE;
1187 it->wd->longpressed = EINA_FALSE;
1190 ecore_timer_del(it->long_timer);
1191 it->long_timer = NULL;
1195 it->dragging = EINA_FALSE;
1196 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1198 if (it->item->swipe_timer)
1200 ecore_timer_del(it->item->swipe_timer);
1201 it->item->swipe_timer = NULL;
1203 if (it->wd->on_hold)
1205 it->wd->swipe = EINA_FALSE;
1206 it->wd->movements = 0;
1207 it->wd->on_hold = EINA_FALSE;
1212 _multi_up(void *data,
1213 Evas *evas __UNUSED__,
1214 Evas_Object *obj __UNUSED__,
1217 Elm_Gen_Item *it = data;
1218 Evas_Event_Multi_Up *ev = event_info;
1220 if (it->wd->multi_device != ev->device) return;
1221 it->wd->multi_device = 0;
1222 it->wd->multi_down = EINA_FALSE;
1223 if (it->wd->mouse_down) return;
1224 _multi_touch_gesture_eval(data);
1228 _multi_move(void *data,
1229 Evas *evas __UNUSED__,
1230 Evas_Object *obj __UNUSED__,
1233 Elm_Gen_Item *it = data;
1234 Evas_Event_Multi_Move *ev = event_info;
1236 if (it->wd->multi_device != ev->device) return;
1237 it->wd->cur_mx = ev->cur.canvas.x;
1238 it->wd->cur_my = ev->cur.canvas.y;
1242 _mouse_down(void *data,
1243 Evas *evas __UNUSED__,
1247 Elm_Gen_Item *it = data;
1248 Evas_Event_Mouse_Down *ev = event_info;
1251 if (ev->button != 1) return;
1252 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1254 it->wd->on_hold = EINA_TRUE;
1257 it->down = EINA_TRUE;
1258 it->dragging = EINA_FALSE;
1259 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1260 it->dx = ev->canvas.x - x;
1261 it->dy = ev->canvas.y - y;
1262 it->wd->mouse_down = EINA_TRUE;
1263 if (!it->wd->multitouched)
1265 it->wd->prev_x = ev->canvas.x;
1266 it->wd->prev_y = ev->canvas.y;
1267 it->wd->multi_timeout = EINA_FALSE;
1268 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1269 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1271 it->wd->longpressed = EINA_FALSE;
1272 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1273 else it->wd->on_hold = EINA_FALSE;
1274 if (it->wd->on_hold) return;
1275 it->wd->wasselected = it->selected;
1276 _item_highlight(it);
1277 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1278 if ((!elm_widget_item_disabled_get(it)) && (!it->display_only))
1280 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1281 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1283 if (it->long_timer) ecore_timer_del(it->long_timer);
1284 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1285 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1287 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1290 it->long_timer = NULL;
1291 it->wd->swipe = EINA_FALSE;
1292 it->wd->movements = 0;
1296 _mouse_up(void *data,
1297 Evas *evas __UNUSED__,
1298 Evas_Object *obj __UNUSED__,
1301 Elm_Gen_Item *it = data;
1302 Evas_Event_Mouse_Up *ev = event_info;
1303 Eina_Bool dragged = EINA_FALSE;
1305 if (ev->button != 1) return;
1306 it->down = EINA_FALSE;
1307 it->wd->mouse_down = EINA_FALSE;
1308 if (it->wd->multitouched)
1310 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1311 if (it->wd->multi_down) return;
1312 _multi_touch_gesture_eval(data);
1315 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1316 else it->wd->on_hold = EINA_FALSE;
1319 ecore_timer_del(it->long_timer);
1320 it->long_timer = NULL;
1324 it->dragging = EINA_FALSE;
1325 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1328 if (it->item->swipe_timer)
1330 ecore_timer_del(it->item->swipe_timer);
1331 it->item->swipe_timer = NULL;
1333 if (it->wd->multi_timer)
1335 ecore_timer_del(it->wd->multi_timer);
1336 it->wd->multi_timer = NULL;
1337 it->wd->multi_timeout = EINA_FALSE;
1339 if (it->wd->on_hold)
1341 if (it->wd->swipe) _swipe(data);
1342 it->wd->longpressed = EINA_FALSE;
1343 it->wd->on_hold = EINA_FALSE;
1346 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1348 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1350 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1352 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1353 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1355 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1359 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1360 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1362 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1363 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1364 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1365 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1367 if (it->wd->longpressed)
1369 it->wd->longpressed = EINA_FALSE;
1370 if ((!it->wd->wasselected) && (!it->flipped))
1372 _item_unhighlight(it);
1375 it->wd->wasselected = EINA_FALSE;
1380 if (it->want_unrealize)
1382 _elm_genlist_item_unrealize(it, EINA_FALSE);
1383 if (it->item->block->want_unrealize)
1384 _item_block_unrealize(it->item->block);
1387 if (elm_widget_item_disabled_get(it) || (dragged) || (it->display_only))
1389 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1394 _item_highlight(it);
1399 _item_unhighlight(it);
1407 Widget_Data *wd = it->wd;
1410 while (wd->selected)
1412 _item_unhighlight(wd->selected->data);
1413 _item_unselect(wd->selected->data);
1419 const Eina_List *l, *l_next;
1422 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1425 _item_unhighlight(it2);
1426 _item_unselect(it2);
1428 //_item_highlight(it);
1431 _item_highlight(it);
1437 _signal_expand_toggle(void *data,
1438 Evas_Object *obj __UNUSED__,
1439 const char *emission __UNUSED__,
1440 const char *source __UNUSED__)
1442 Elm_Gen_Item *it = data;
1444 if (it->item->expanded)
1445 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1447 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1451 _signal_expand(void *data,
1452 Evas_Object *obj __UNUSED__,
1453 const char *emission __UNUSED__,
1454 const char *source __UNUSED__)
1456 Elm_Gen_Item *it = data;
1458 if (!it->item->expanded)
1459 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1463 _signal_contract(void *data,
1464 Evas_Object *obj __UNUSED__,
1465 const char *emission __UNUSED__,
1466 const char *source __UNUSED__)
1468 Elm_Gen_Item *it = data;
1470 if (it->item->expanded)
1471 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1475 _scr_hold_timer_cb(void *data)
1477 if (!data) return ECORE_CALLBACK_CANCEL;
1478 Widget_Data *wd = data;
1479 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1480 wd->scr_hold_timer = NULL;
1481 return ECORE_CALLBACK_CANCEL;
1485 _mode_finished_signal_cb(void *data,
1487 const char *emission __UNUSED__,
1488 const char *source __UNUSED__)
1492 Elm_Gen_Item *it = data;
1493 if ((it->generation < it->wd->generation) || (!it->realized) || (!it->item->mode_view)) return;
1495 Evas *te = evas_object_evas_get(obj);
1497 evas_event_freeze(te);
1498 it->item->nocache = EINA_FALSE;
1499 _mode_item_unrealize(it);
1500 if (it->item->group_item)
1501 evas_object_raise(it->item->VIEW(group_item));
1502 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->mode_type);
1503 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1504 evas_event_thaw(te);
1505 evas_event_thaw_eval(te);
1509 _item_cache_clean(Widget_Data *wd)
1511 evas_event_freeze(evas_object_evas_get(wd->obj));
1512 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1516 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1517 wd->item_cache = eina_inlist_remove(wd->item_cache,
1518 wd->item_cache->last);
1519 wd->item_cache_count--;
1520 if (itc->spacer) evas_object_del(itc->spacer);
1521 if (itc->base_view) evas_object_del(itc->base_view);
1522 eina_stringshare_del(itc->item_style);
1525 evas_event_thaw(evas_object_evas_get(wd->obj));
1526 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1530 _item_cache_zero(Widget_Data *wd)
1532 int pmax = wd->item_cache_max;
1533 wd->item_cache_max = 0;
1534 _item_cache_clean(wd);
1535 wd->item_cache_max = pmax;
1539 _item_cache_add(Elm_Gen_Item *it)
1543 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1544 if (it->wd->item_cache_max <= 0)
1546 evas_object_del(VIEW(it));
1548 evas_object_del(it->spacer);
1550 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1551 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1555 it->wd->item_cache_count++;
1556 itc = calloc(1, sizeof(Item_Cache));
1559 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1560 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1563 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1564 EINA_INLIST_GET(itc));
1565 itc->spacer = it->spacer;
1567 itc->base_view = VIEW(it);
1569 edje_object_signal_emit(itc->base_view, "elm,state,unselected", "elm");
1570 evas_object_hide(itc->base_view);
1571 evas_object_move(itc->base_view, -9999, -9999);
1572 itc->item_style = eina_stringshare_add(it->itc->item_style);
1573 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) itc->tree = 1;
1574 itc->compress = (it->wd->compress);
1575 itc->selected = it->selected;
1576 itc->disabled = elm_widget_item_disabled_get(it);
1577 itc->expanded = it->item->expanded;
1580 ecore_timer_del(it->long_timer);
1581 it->long_timer = NULL;
1583 if (it->item->swipe_timer)
1585 ecore_timer_del(it->item->swipe_timer);
1586 it->item->swipe_timer = NULL;
1588 // FIXME: other callbacks?
1589 edje_object_signal_callback_del_full(itc->base_view,
1590 "elm,action,expand,toggle",
1591 "elm", _signal_expand_toggle, it);
1592 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1594 _signal_expand, it);
1595 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1596 "elm", _signal_contract, it);
1597 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1599 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1601 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1603 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1605 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1607 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1609 _item_cache_clean(it->wd);
1610 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1611 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1615 _item_cache_find(Elm_Gen_Item *it)
1620 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) tree = 1;
1621 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1623 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1625 if ((itc->tree == tree) &&
1626 (itc->compress == it->wd->compress) &&
1627 (((!it->itc->item_style) && (!itc->item_style)) ||
1628 (it->itc->item_style && itc->item_style &&
1629 (!strcmp(it->itc->item_style, itc->item_style)))))
1631 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1632 EINA_INLIST_GET(itc));
1633 it->wd->item_cache_count--;
1641 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1643 if (it->position_update || it->item->block->position_update)
1645 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
1646 it->position_update = EINA_FALSE;
1651 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1653 if (!it->item->nostacking)
1655 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1657 if (it->edit_obj) evas_object_lower(it->edit_obj);
1658 else evas_object_lower(VIEW(it));
1662 if (it->edit_obj) evas_object_raise(it->edit_obj);
1663 else evas_object_raise(VIEW(it));
1667 if (it->item->order_num_in & 0x1)
1669 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1670 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,odd", "elm");
1674 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1675 if (it->edit_obj) edje_object_signal_emit(it->edit_obj, "elm,state,even", "elm");
1680 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1684 if (it->selected != itc->selected)
1687 edje_object_signal_emit(VIEW(it),
1688 "elm,state,selected", "elm");
1691 edje_object_signal_emit(it->edit_obj,
1692 "elm,state,selected", "elm");
1694 if (elm_widget_item_disabled_get(it) != itc->disabled)
1696 if (elm_widget_item_disabled_get(it))
1697 edje_object_signal_emit(VIEW(it),
1698 "elm,state,disabled", "elm");
1700 edje_object_signal_emit(it->edit_obj,
1701 "elm,state,disabled", "elm");
1703 if (it->item->expanded != itc->expanded)
1705 if (it->item->expanded)
1706 edje_object_signal_emit(VIEW(it),
1707 "elm,state,expanded", "elm");
1709 edje_object_signal_emit(it->edit_obj,
1710 "elm,state,expanded", "elm");
1717 edje_object_signal_emit(VIEW(it),
1718 "elm,state,selected", "elm");
1720 edje_object_signal_emit(it->edit_obj,
1721 "elm,state,selected", "elm");
1724 if (elm_widget_item_disabled_get(it))
1726 edje_object_signal_emit(VIEW(it),
1727 "elm,state,disabled", "elm");
1729 edje_object_signal_emit(it->edit_obj,
1730 "elm,state,disabled", "elm");
1732 if (it->item->expanded)
1734 edje_object_signal_emit(VIEW(it),
1735 "elm,state,expanded", "elm");
1737 edje_object_signal_emit(it->edit_obj,
1738 "elm,state,expanded", "elm");
1744 _item_cache_free(Item_Cache *itc)
1746 if (itc->spacer) evas_object_del(itc->spacer);
1747 if (itc->base_view) evas_object_del(itc->base_view);
1748 eina_stringshare_del(itc->item_style);
1753 _item_text_realize(Elm_Gen_Item *it,
1754 Evas_Object *target,
1758 if (it->itc->func.text_get)
1763 *source = elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
1764 EINA_LIST_FOREACH(*source, l, key)
1766 if (parts && fnmatch(parts, key, FNM_PERIOD))
1769 char *s = it->itc->func.text_get
1770 ((void *)it->base.data, WIDGET(it), key);
1774 edje_object_part_text_set(target, key, s);
1779 edje_object_part_text_set(target, key, "");
1786 _item_content_unrealize(Elm_Gen_Item *it,
1787 Evas_Object *target,
1791 Eina_List *res = it->content_objs;
1793 if (it->itc->func.content_get)
1797 Evas_Object *ic = NULL;
1799 EINA_LIST_FOREACH(*source, l, key)
1801 if (parts && fnmatch(parts, key, FNM_PERIOD))
1804 ic = edje_object_part_swallow_get(target, key);
1807 res = eina_list_remove(res, ic);
1808 edje_object_part_unswallow(target, ic);
1809 evas_object_del(ic);
1818 _item_content_realize(Elm_Gen_Item *it,
1819 Evas_Object *target,
1823 Eina_List *res = NULL;
1825 if (it->itc->func.content_get)
1829 Evas_Object *ic = NULL;
1831 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1833 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
1834 res = it->content_objs;
1836 EINA_LIST_FOREACH(*source, l, key)
1838 if (parts && fnmatch(parts, key, FNM_PERIOD))
1841 if (it->itc->func.content_get)
1842 ic = it->itc->func.content_get
1843 ((void *)it->base.data, WIDGET(it), key);
1846 res = eina_list_append(res, ic);
1847 edje_object_part_swallow(target, key, ic);
1848 evas_object_show(ic);
1849 elm_widget_sub_object_add(WIDGET(it), ic);
1850 if (elm_widget_item_disabled_get(it))
1851 elm_widget_disabled_set(ic, EINA_TRUE);
1860 _item_state_realize(Elm_Gen_Item *it,
1861 Evas_Object *target,
1865 if (it->itc->func.state_get)
1871 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
1872 EINA_LIST_FOREACH(*source, l, key)
1874 if (parts && fnmatch(parts, key, FNM_PERIOD))
1877 Eina_Bool on = it->itc->func.state_get
1878 ((void *)it->base.data, WIDGET(it), key);
1882 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1883 edje_object_signal_emit(target, buf, "elm");
1887 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1888 edje_object_signal_emit(target, buf, "elm");
1895 _item_flips_realize(Elm_Gen_Item *it,
1896 Evas_Object *target,
1899 Eina_List *res = NULL;
1901 if (it->itc->func.content_get)
1905 Evas_Object *ic = NULL;
1907 *source = elm_widget_stringlist_get(edje_object_data_get(target, "flips"));
1909 EINA_LIST_FOREACH(*source, l, key)
1911 if (it->itc->func.content_get)
1912 ic = it->itc->func.content_get
1913 ((void *)it->base.data, WIDGET(it), key);
1916 res = eina_list_append(res, ic);
1917 edje_object_part_swallow(target, key, ic);
1918 evas_object_show(ic);
1919 elm_widget_sub_object_add(WIDGET(it), ic);
1920 if (elm_widget_item_disabled_get(it))
1921 elm_widget_disabled_set(ic, EINA_TRUE);
1930 _item_realize(Elm_Gen_Item *it,
1934 const char *treesize;
1937 Item_Cache *itc = NULL;
1939 if (it->generation < it->wd->generation) return;
1940 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1943 if (it->item->order_num_in != in)
1945 it->item->order_num_in = in;
1946 _elm_genlist_item_odd_even_update(it);
1947 _elm_genlist_item_state_update(it, NULL);
1948 _elm_genlist_item_index_update(it);
1950 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1951 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1954 it->item->order_num_in = in;
1956 if (it->item->nocache)
1957 it->item->nocache = EINA_FALSE;
1959 itc = _item_cache_find(it);
1962 VIEW(it) = itc->base_view;
1963 itc->base_view = NULL;
1964 it->spacer = itc->spacer;
1969 const char *stacking_even;
1970 const char *stacking;
1972 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1973 edje_object_scale_set(VIEW(it),
1974 elm_widget_scale_get(WIDGET(it)) *
1975 _elm_config->scale);
1976 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
1977 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1979 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
1980 snprintf(buf, sizeof(buf), "tree%s/%s", it->wd->compress ? "_compress" : "", it->itc->item_style ?: "default");
1982 snprintf(buf, sizeof(buf), "item%s/%s", it->wd->compress ? "_compress" : "", it->itc->item_style ?: "default");
1984 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
1985 elm_widget_style_get(WIDGET(it)));
1987 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1988 if (!stacking_even) stacking_even = "above";
1989 it->item->stacking_even = !!strcmp("above", stacking_even);
1991 stacking = edje_object_data_get(VIEW(it), "stacking");
1992 if (!stacking) stacking = "yes";
1993 it->item->nostacking = !!strcmp("yes", stacking);
1995 edje_object_mirrored_set(VIEW(it),
1996 elm_widget_mirrored_get(WIDGET(it)));
1998 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1999 evas_object_color_set(it->spacer, 0, 0, 0, 0);
2000 elm_widget_sub_object_add(WIDGET(it), it->spacer);
2003 _elm_genlist_item_odd_even_update(it);
2005 treesize = edje_object_data_get(VIEW(it), "treesize");
2006 if (treesize) tsize = atoi(treesize);
2007 evas_object_size_hint_min_set(it->spacer,
2008 (it->item->expanded_depth * tsize) * _elm_config->scale, 1);
2009 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
2012 edje_object_signal_callback_add(VIEW(it),
2013 "elm,action,expand,toggle",
2014 "elm", _signal_expand_toggle, it);
2015 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
2016 "elm", _signal_expand, it);
2017 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
2018 "elm", _signal_contract, it);
2019 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
2021 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
2023 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
2025 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
2027 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
2029 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
2032 if ((it->wd->edit_mode) && (!it->edit_obj) &&
2033 (it->item->flags != ELM_GENLIST_ITEM_GROUP) && (it->itc->edit_item_style))
2034 _edit_mode_item_realize(it, EINA_FALSE);
2036 _elm_genlist_item_state_update(it, itc);
2037 _elm_genlist_item_index_update(it);
2040 if ((calc) && (it->wd->homogeneous) &&
2041 ((it->wd->item_width) ||
2042 ((it->wd->item_width) && (it->wd->group_item_width))))
2044 /* homogenous genlist shortcut */
2045 if (!it->item->mincalcd)
2049 it->item->w = it->item->minw = it->wd->group_item_width;
2050 it->item->h = it->item->minh = it->wd->group_item_height;
2054 it->item->w = it->item->minw = it->wd->item_width;
2055 it->item->h = it->item->minh = it->wd->item_height;
2057 it->item->mincalcd = EINA_TRUE;
2062 /* FIXME: If you see that assert, please notify us and we
2063 will clean our mess */
2064 assert(eina_list_count(it->content_objs) == 0);
2066 _item_text_realize(it, VIEW(it), &it->texts, NULL);
2067 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
2068 _item_state_realize(it, VIEW(it), &it->states, NULL);
2071 edje_object_signal_emit(VIEW(it), "elm,state,flip,enabled", "elm");
2072 it->content_objs = _item_flips_realize(it, VIEW(it), &it->contents);
2075 if (!it->item->mincalcd)
2077 Evas_Coord mw = -1, mh = -1;
2079 if (!it->display_only)
2080 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2081 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
2082 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
2084 if (!it->display_only)
2085 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2086 it->item->w = it->item->minw = mw;
2087 it->item->h = it->item->minh = mh;
2088 it->item->mincalcd = EINA_TRUE;
2090 if ((!it->wd->group_item_width) && (it->group))
2092 it->wd->group_item_width = mw;
2093 it->wd->group_item_height = mh;
2095 else if ((!it->wd->item_width) && (it->item->flags == ELM_GENLIST_ITEM_NONE))
2097 it->wd->item_width = mw;
2098 it->wd->item_height = mh;
2101 if (!calc) evas_object_show(VIEW(it));
2104 if (it->tooltip.content_cb)
2106 elm_widget_item_tooltip_content_cb_set(it,
2107 it->tooltip.content_cb,
2108 it->tooltip.data, NULL);
2109 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2110 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
2113 if (it->mouse_cursor)
2114 elm_widget_item_cursor_set(it, it->mouse_cursor);
2116 it->realized = EINA_TRUE;
2117 it->want_unrealize = EINA_FALSE;
2119 if (itc) _item_cache_free(itc);
2120 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2121 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2123 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2125 if ((!calc) && (it->wd->edit_mode) && (it->item->flags != ELM_GENLIST_ITEM_GROUP))
2127 if (it->itc->edit_item_style)
2129 if (!it->edit_obj) _edit_mode_item_realize(it, EINA_FALSE);
2130 edje_object_message_signal_process(it->edit_obj);
2133 edje_object_message_signal_process(VIEW(it));
2137 _item_unrealize_cb(Elm_Gen_Item *it)
2139 if (it->item->nocache)
2141 evas_object_del(VIEW(it));
2143 evas_object_del(it->spacer);
2148 edje_object_mirrored_set(VIEW(it),
2149 elm_widget_mirrored_get(WIDGET(it)));
2150 edje_object_scale_set(VIEW(it),
2151 elm_widget_scale_get(WIDGET(it))
2152 * _elm_config->scale);
2153 _item_cache_add(it);
2156 _mode_item_unrealize(it);
2158 it->realized = EINA_FALSE;
2159 it->want_unrealize = EINA_FALSE;
2160 if (it->wd->edit_mode) _edit_mode_item_unrealize(it);
2164 _item_block_recalc(Item_Block *itb,
2170 Evas_Coord minw = 0, minh = 0;
2171 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2174 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2176 EINA_LIST_FOREACH(itb->items, l, it)
2178 if (it->generation < it->wd->generation) continue;
2179 showme |= it->item->showme;
2184 if (!it->item->mincalcd) changed = EINA_TRUE;
2187 _item_realize(it, in, EINA_TRUE);
2188 _elm_genlist_item_unrealize(it, EINA_TRUE);
2193 _item_realize(it, in, EINA_TRUE);
2194 _elm_genlist_item_unrealize(it, EINA_TRUE);
2198 _item_realize(it, in, EINA_FALSE);
2199 minh += it->item->minh;
2200 if (minw < it->item->minw) minw = it->item->minw;
2208 itb->changed = EINA_FALSE;
2209 itb->position_update = EINA_FALSE;
2210 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2211 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2216 _item_block_realize(Item_Block *itb)
2218 if (itb->realized) return;
2219 itb->realized = EINA_TRUE;
2220 itb->want_unrealize = EINA_FALSE;
2224 _item_block_unrealize(Item_Block *itb)
2228 Eina_Bool dragging = EINA_FALSE;
2230 if (!itb->realized) return;
2231 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2232 EINA_LIST_FOREACH(itb->items, l, it)
2234 if (itb->must_recalc || !it->group)
2238 dragging = EINA_TRUE;
2239 it->want_unrealize = EINA_TRUE;
2242 _elm_genlist_item_unrealize(it, EINA_FALSE);
2247 itb->realized = EINA_FALSE;
2248 itb->want_unrealize = EINA_TRUE;
2251 itb->want_unrealize = EINA_FALSE;
2252 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2253 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2257 _get_space_for_reorder_item(Elm_Gen_Item *it)
2259 Evas_Coord rox, roy, row, roh, oy, oh;
2260 Eina_Bool top = EINA_FALSE;
2261 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2262 if (!reorder_it) return 0;
2264 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2265 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2267 if ((it->wd->reorder_start_y < it->item->block->y) &&
2268 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2270 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2271 if (it->item->block->count == 1)
2272 it->wd->reorder_rel = it;
2274 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2275 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2277 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2280 it->item->block->reorder_offset = 0;
2282 it->item->scrl_y += it->item->block->reorder_offset;
2284 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2285 rox, roy + (roh / 2), row, 1));
2288 it->wd->reorder_rel = it;
2289 it->item->scrl_y += it->wd->reorder_it->item->h;
2290 return it->wd->reorder_it->item->h;
2297 _reorder_move_animator_cb(void *data)
2299 Elm_Gen_Item *it = data;
2300 Eina_Bool down = EINA_FALSE;
2302 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2304 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2306 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2309 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2310 if (diff > it->item->h) y = diff / 2;
2312 if (it->item->old_scrl_y < it->item->scrl_y)
2314 it->item->old_scrl_y += y;
2317 else if (it->item->old_scrl_y > it->item->scrl_y)
2319 it->item->old_scrl_y -= y;
2324 _item_position(it, it->edit_obj, it->item->scrl_x, it->item->old_scrl_y);
2326 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2327 _group_items_recalc(it->wd);
2329 if ((it->wd->reorder_pan_move) ||
2330 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2331 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2333 it->item->old_scrl_y = it->item->scrl_y;
2334 it->item->move_effect_enabled = EINA_FALSE;
2335 it->wd->reorder_move_animator = NULL;
2336 return ECORE_CALLBACK_CANCEL;
2338 return ECORE_CALLBACK_RENEW;
2342 _item_position(Elm_Gen_Item *it,
2350 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2351 evas_object_resize(view, it->item->w, it->item->h);
2352 evas_object_move(view, it_x, it_y);
2353 evas_object_show(view);
2354 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2355 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2359 _item_block_position(Item_Block *itb,
2365 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2366 Eina_Bool vis = EINA_FALSE;
2368 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2369 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2370 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2372 EINA_LIST_FOREACH(itb->items, l, it)
2374 if (it->generation < it->wd->generation) continue;
2375 else if (it->wd->reorder_it == it) continue;
2378 it->item->w = itb->w;
2379 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2380 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2382 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2383 cvx, cvy, cvw, cvh));
2386 if ((itb->realized) && (!it->realized))
2388 if (vis) _item_realize(it, in, EINA_FALSE);
2394 if (it->wd->reorder_mode)
2395 y += _get_space_for_reorder_item(it);
2396 git = it->item->group_item;
2399 if (git->item->scrl_y < oy)
2400 git->item->scrl_y = oy;
2401 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2402 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2403 git->item->want_realize = EINA_TRUE;
2405 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2407 if (!it->item->move_effect_enabled)
2409 it->item->move_effect_enabled = EINA_TRUE;
2410 it->wd->reorder_move_animator =
2412 _reorder_move_animator_cb, it);
2415 if (!it->item->move_effect_enabled)
2417 if ((it->wd->edit_mode) && (it->itc->edit_item_style))
2418 _edit_mode_item_position(it, it->item->scrl_x,
2422 if (it->item->mode_view)
2423 _item_position(it, it->item->mode_view,
2427 _item_position(it, VIEW(it), it->item->scrl_x,
2430 it->item->old_scrl_y = it->item->scrl_y;
2435 if (!it->dragging) _elm_genlist_item_unrealize(it, EINA_FALSE);
2442 if (vis) it->item->want_realize = EINA_TRUE;
2446 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2447 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2451 _group_items_recalc(void *data)
2453 Widget_Data *wd = data;
2457 evas_event_freeze(evas_object_evas_get(wd->obj));
2458 EINA_LIST_FOREACH(wd->group_items, l, git)
2460 if (git->item->want_realize)
2463 _item_realize(git, 0, EINA_FALSE);
2464 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2465 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2466 evas_object_show(VIEW(git));
2467 evas_object_raise(VIEW(git));
2469 else if (!git->item->want_realize && git->realized)
2472 _elm_genlist_item_unrealize(git, EINA_FALSE);
2475 evas_event_thaw(evas_object_evas_get(wd->obj));
2476 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2480 _must_recalc_idler(void *data)
2482 Widget_Data *wd = data;
2483 if (wd->calc_job) ecore_job_del(wd->calc_job);
2484 wd->calc_job = ecore_job_add(_calc_job, wd);
2485 wd->must_recalc_idler = NULL;
2486 return ECORE_CALLBACK_CANCEL;
2490 _scroll_item(Widget_Data *wd)
2492 Elm_Gen_Item *it = NULL;
2493 Evas_Coord gith = 0;
2494 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
2496 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2498 dx = it->x + it->item->block->x;
2499 dy = it->y + it->item->block->y;
2500 dw = it->item->block->w;
2502 switch (wd->scrollto_type)
2504 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2505 if (it->item->group_item) gith = it->item->group_item->item->h;
2508 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2509 dy += (it->item->h / 2 - oh / 2);
2511 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2513 if ((wd->expanded_item) &&
2514 ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h)
2515 - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh))
2517 it = wd->expanded_item;
2518 if (it->item->group_item) gith = it->item->group_item->item->h;
2519 dx = it->x + it->item->block->x;
2520 dy = it->y + it->item->block->y - gith;
2521 dw = it->item->block->w;
2525 if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y)))
2526 gith = it->item->group_item->item->h;
2533 elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh);
2535 elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh);
2537 it->item->showme = EINA_FALSE;
2538 wd->show_item = NULL;
2539 wd->auto_scroll_enabled = EINA_FALSE;
2540 wd->check_scroll = EINA_FALSE;
2544 _calc_job(void *data)
2546 Widget_Data *wd = data;
2547 Item_Block *itb, *chb = NULL;
2548 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw;
2549 Evas_Coord pan_w = 0, pan_h = 0;
2551 Eina_Bool minw_change = EINA_FALSE;
2552 Eina_Bool did_must_recalc = EINA_FALSE;
2555 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2556 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, NULL);
2561 evas_event_freeze(evas_object_evas_get(wd->obj));
2562 EINA_INLIST_FOREACH(wd->blocks, itb)
2564 Eina_Bool showme = EINA_FALSE;
2567 showme = itb->showme;
2568 itb->showme = EINA_FALSE;
2571 if (itb->realized) _item_block_unrealize(itb);
2573 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2575 if (itb->must_recalc)
2579 EINA_LIST_FOREACH(itb->items, l, it)
2580 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2581 itb->changed = EINA_TRUE;
2582 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2583 if (itb->realized) _item_block_unrealize(itb);
2584 itb->must_recalc = EINA_FALSE;
2586 showme = _item_block_recalc(itb, in, EINA_FALSE);
2592 if (minw == -1) minw = itb->minw;
2593 else if ((!itb->must_recalc) && (minw < itb->minw))
2596 minw_change = EINA_TRUE;
2601 minw_change = EINA_TRUE;
2607 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2608 wd->check_scroll = EINA_TRUE;
2612 EINA_INLIST_FOREACH(wd->blocks, itb)
2618 if ((chb) && (EINA_INLIST_GET(chb)->next))
2620 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2622 if (itb->realized) _item_block_unrealize(itb);
2625 wd->realminw = minw;
2626 if (minw < wd->w) minw = wd->w;
2627 if ((minw != wd->minw) || (minh != wd->minh))
2631 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2632 _sizing_eval(wd->obj);
2633 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2638 it = wd->anchor_item;
2639 it_y = wd->anchor_y;
2640 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2641 it->item->block->y + it->y + it_y);
2642 wd->anchor_item = it;
2643 wd->anchor_y = it_y;
2646 if (did_must_recalc)
2648 if (!wd->must_recalc_idler)
2649 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2651 if (wd->check_scroll)
2653 _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h);
2654 if (EINA_INLIST_GET(wd->show_item) == wd->items->last)
2655 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
2656 switch (wd->scrollto_type)
2658 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
2661 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2664 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2669 if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) &&
2670 (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy)))
2675 wd->calc_job = NULL;
2676 evas_object_smart_changed(wd->pan_smart);
2677 evas_event_thaw(evas_object_evas_get(wd->obj));
2678 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2682 _update_job(void *data)
2684 Widget_Data *wd = data;
2688 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2690 wd->update_job = NULL;
2693 evas_event_freeze(evas_object_evas_get(wd->obj));
2694 EINA_INLIST_FOREACH(wd->blocks, itb)
2696 Evas_Coord itminw, itminh;
2703 _item_block_position(itb, num);
2707 recalc = EINA_FALSE;
2708 EINA_LIST_FOREACH(itb->items, l2, it)
2710 if (it->item->updateme)
2712 itminw = it->item->minw;
2713 itminh = it->item->minh;
2715 it->item->updateme = EINA_FALSE;
2718 _elm_genlist_item_unrealize(it, EINA_FALSE);
2719 _item_realize(it, num, EINA_FALSE);
2720 position = EINA_TRUE;
2724 _item_realize(it, num, EINA_TRUE);
2725 _elm_genlist_item_unrealize(it, EINA_TRUE);
2727 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2732 itb->updateme = EINA_FALSE;
2735 position = EINA_TRUE;
2736 itb->changed = EINA_TRUE;
2737 _item_block_recalc(itb, num0, EINA_FALSE);
2738 _item_block_position(itb, num0);
2743 if (wd->calc_job) ecore_job_del(wd->calc_job);
2744 wd->calc_job = ecore_job_add(_calc_job, wd);
2746 evas_event_thaw(evas_object_evas_get(wd->obj));
2747 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2751 _pan_set(Evas_Object *obj,
2755 Pan *sd = evas_object_smart_data_get(obj);
2759 // Evas_Coord ow, oh;
2760 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2761 // ow = sd->wd->minw - ow;
2762 // if (ow < 0) ow = 0;
2763 // oh = sd->wd->minh - oh;
2764 // if (oh < 0) oh = 0;
2765 // if (x < 0) x = 0;
2766 // if (y < 0) y = 0;
2767 // if (x > ow) x = ow;
2768 // if (y > oh) y = oh;
2769 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2773 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2775 if ((itb->y + itb->h) > y)
2780 EINA_LIST_FOREACH(itb->items, l2, it)
2782 if ((itb->y + it->y) >= y)
2784 sd->wd->anchor_item = it;
2785 sd->wd->anchor_y = -(itb->y + it->y - y);
2792 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2796 _pan_get(Evas_Object *obj,
2800 Pan *sd = evas_object_smart_data_get(obj);
2803 if (x) *x = sd->wd->pan_x;
2804 if (y) *y = sd->wd->pan_y;
2808 _pan_max_get(Evas_Object *obj,
2812 Pan *sd = evas_object_smart_data_get(obj);
2816 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2817 ow = sd->wd->minw - ow;
2819 oh = sd->wd->minh - oh;
2826 _pan_min_get(Evas_Object *obj __UNUSED__,
2835 _pan_child_size_get(Evas_Object *obj,
2839 Pan *sd = evas_object_smart_data_get(obj);
2842 if (w) *w = sd->wd->minw;
2843 if (h) *h = sd->wd->minh;
2847 _pan_add(Evas_Object *obj)
2850 Evas_Object_Smart_Clipped_Data *cd;
2853 cd = evas_object_smart_data_get(obj);
2856 sd->__clipped_data = *cd;
2858 evas_object_smart_data_set(obj, sd);
2862 _pan_del(Evas_Object *obj)
2864 Pan *sd = evas_object_smart_data_get(obj);
2869 ecore_job_del(sd->resize_job);
2870 sd->resize_job = NULL;
2876 _pan_resize_job(void *data)
2880 _sizing_eval(sd->wd->obj);
2881 sd->resize_job = NULL;
2885 _pan_resize(Evas_Object *obj,
2889 Pan *sd = evas_object_smart_data_get(obj);
2893 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2894 if ((ow == w) && (oh == h)) return;
2895 if ((sd->wd->height_for_width) && (ow != w))
2898 if (sd->resize_job) ecore_job_del(sd->resize_job);
2899 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2901 sd->wd->pan_changed = EINA_TRUE;
2902 evas_object_smart_changed(obj);
2903 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2904 sd->wd->calc_job = NULL;
2906 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2907 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2912 _pan_calculate(Evas_Object *obj)
2914 Pan *sd = evas_object_smart_data_get(obj);
2916 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2922 evas_event_freeze(evas_object_evas_get(obj));
2924 if (sd->wd->pan_changed)
2927 sd->wd->pan_changed = EINA_FALSE;
2930 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2931 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2932 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2934 git->item->want_realize = EINA_FALSE;
2936 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2938 itb->w = sd->wd->minw;
2939 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2940 itb->y - sd->wd->pan_y + oy,
2942 cvx, cvy, cvw, cvh))
2944 if ((!itb->realized) || (itb->changed))
2945 _item_block_realize(itb);
2946 _item_block_position(itb, in);
2950 if (itb->realized) _item_block_unrealize(itb);
2954 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2955 _group_items_recalc(sd->wd);
2956 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2958 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2959 sd->wd->reorder_pan_move = EINA_TRUE;
2960 else sd->wd->reorder_pan_move = EINA_FALSE;
2961 evas_object_raise(sd->wd->VIEW(reorder_it));
2962 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2963 sd->wd->start_time = ecore_loop_time_get();
2965 _item_auto_scroll(sd->wd);
2966 evas_event_thaw(evas_object_evas_get(obj));
2967 evas_event_thaw_eval(evas_object_evas_get(obj));
2971 _pan_move(Evas_Object *obj,
2972 Evas_Coord x __UNUSED__,
2973 Evas_Coord y __UNUSED__)
2975 Pan *sd = evas_object_smart_data_get(obj);
2979 sd->wd->pan_changed = EINA_TRUE;
2980 evas_object_smart_changed(obj);
2981 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2982 sd->wd->calc_job = NULL;
2986 _hold_on(void *data __UNUSED__,
2988 void *event_info __UNUSED__)
2990 Widget_Data *wd = elm_widget_data_get(obj);
2992 elm_smart_scroller_hold_set(wd->scr, 1);
2996 _hold_off(void *data __UNUSED__,
2998 void *event_info __UNUSED__)
3000 Widget_Data *wd = elm_widget_data_get(obj);
3002 elm_smart_scroller_hold_set(wd->scr, 0);
3006 _freeze_on(void *data __UNUSED__,
3008 void *event_info __UNUSED__)
3010 Widget_Data *wd = elm_widget_data_get(obj);
3012 elm_smart_scroller_freeze_set(wd->scr, 1);
3016 _freeze_off(void *data __UNUSED__,
3018 void *event_info __UNUSED__)
3020 Widget_Data *wd = elm_widget_data_get(obj);
3022 elm_smart_scroller_freeze_set(wd->scr, 0);
3026 _scr_anim_start(void *data,
3027 Evas_Object *obj __UNUSED__,
3028 void *event_info __UNUSED__)
3030 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
3034 _scr_anim_stop(void *data,
3035 Evas_Object *obj __UNUSED__,
3036 void *event_info __UNUSED__)
3038 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
3042 _scr_drag_start(void *data,
3043 Evas_Object *obj __UNUSED__,
3044 void *event_info __UNUSED__)
3046 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3050 _scr_drag_stop(void *data,
3051 Evas_Object *obj __UNUSED__,
3052 void *event_info __UNUSED__)
3054 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3058 _edge_left(void *data,
3059 Evas_Object *scr __UNUSED__,
3060 void *event_info __UNUSED__)
3062 Evas_Object *obj = data;
3063 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
3067 _edge_right(void *data,
3068 Evas_Object *scr __UNUSED__,
3069 void *event_info __UNUSED__)
3071 Evas_Object *obj = data;
3072 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
3076 _edge_top(void *data,
3077 Evas_Object *scr __UNUSED__,
3078 void *event_info __UNUSED__)
3080 Evas_Object *obj = data;
3081 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
3085 _edge_bottom(void *data,
3086 Evas_Object *scr __UNUSED__,
3087 void *event_info __UNUSED__)
3089 Evas_Object *obj = data;
3090 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
3094 _mode_item_realize(Elm_Gen_Item *it)
3098 if ((it->item->mode_view) || (it->generation < it->wd->generation)) return;
3100 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3101 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
3102 edje_object_scale_set(it->item->mode_view,
3103 elm_widget_scale_get(WIDGET(it)) *
3104 _elm_config->scale);
3105 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
3106 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
3108 strncpy(buf, "item", sizeof(buf));
3109 if (it->wd->compress)
3110 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3112 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
3113 strncat(buf, "/", sizeof(buf) - strlen(buf));
3114 strncat(buf, it->itc->mode_item_style, sizeof(buf) - strlen(buf));
3116 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
3117 elm_widget_style_get(WIDGET(it)));
3118 edje_object_mirrored_set(it->item->mode_view,
3119 elm_widget_mirrored_get(WIDGET(it)));
3121 /* signal callback add */
3122 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
3124 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
3126 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
3129 /* text_get, content_get, state_get */
3130 /* FIXME: If you see that assert, please notify us and we
3131 will clean our mess */
3132 assert(eina_list_count(it->item->mode_content_objs) == 0);
3134 _item_text_realize(it, it->item->mode_view, &it->item->mode_texts, NULL);
3135 it->item->mode_content_objs =
3136 _item_content_realize(it, it->item->mode_view,
3137 &it->item->mode_contents, NULL);
3138 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
3140 edje_object_part_swallow(it->item->mode_view,
3141 edje_object_data_get(it->item->mode_view, "mode_part"),
3144 it->want_unrealize = EINA_FALSE;
3145 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3146 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3150 _mode_item_unrealize(Elm_Gen_Item *it)
3152 Widget_Data *wd = it->wd;
3153 Evas_Object *content;
3154 if (!it->item->mode_view) return;
3156 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3157 elm_widget_stringlist_free(it->item->mode_texts);
3158 it->item->mode_texts = NULL;
3159 elm_widget_stringlist_free(it->item->mode_contents);
3160 it->item->mode_contents = NULL;
3161 elm_widget_stringlist_free(it->item->mode_states);
3163 EINA_LIST_FREE(it->item->mode_content_objs, content)
3164 evas_object_del(content);
3166 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
3167 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
3168 evas_object_del(it->item->mode_view);
3169 it->item->mode_view = NULL;
3171 if (wd->mode_item == it)
3172 wd->mode_item = NULL;
3173 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3174 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3178 _item_mode_set(Elm_Gen_Item *it)
3181 Widget_Data *wd = it->wd;
3186 it->item->nocache = EINA_TRUE;
3188 if (wd->scr_hold_timer)
3190 ecore_timer_del(wd->scr_hold_timer);
3191 wd->scr_hold_timer = NULL;
3193 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3194 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3196 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3197 _mode_item_realize(it);
3198 if (it->item->group_item)
3199 evas_object_raise(it->item->VIEW(group_item));
3200 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
3201 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3202 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3204 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
3205 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3209 _item_mode_unset(Widget_Data *wd)
3212 if (!wd->mode_item) return;
3213 char buf[1024], buf2[1024];
3217 it->item->nocache = EINA_TRUE;
3219 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
3220 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
3222 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3223 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
3225 wd->mode_item = NULL;
3229 _edit_mode_item_position(Elm_Gen_Item *it, int itx, int ity)
3231 if ((!it) || (!it->wd->edit_mode)) return;
3232 evas_object_resize(it->edit_obj, it->item->w, it->item->h);
3233 evas_object_move(it->edit_obj, itx, ity);
3237 _edit_mode_item_realize(Elm_Gen_Item *it, Eina_Bool effect_on)
3240 const char *stacking_even;
3241 const char *stacking;
3243 if ((!it) || (it->item->edit_mode_item_realized) ||
3244 (it->generation < it->wd->generation))
3247 it->edit_obj = edje_object_add(evas_object_evas_get(WIDGET(it)));
3248 edje_object_scale_set(it->edit_obj, elm_widget_scale_get(WIDGET(it)) *
3249 _elm_config->scale);
3250 evas_object_smart_member_add(it->edit_obj, it->wd->pan_smart);
3251 elm_widget_sub_object_add(WIDGET(it), it->edit_obj);
3253 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
3254 strncpy(buf, "tree", sizeof(buf));
3255 else strncpy(buf, "item", sizeof(buf));
3256 if (it->wd->compress)
3257 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
3259 strncat(buf, "/", sizeof(buf) - strlen(buf));
3260 strncat(buf, it->itc->edit_item_style, sizeof(buf) - strlen(buf));
3262 _elm_theme_object_set(WIDGET(it), it->edit_obj, "genlist", buf,
3263 elm_widget_style_get(WIDGET(it)));
3265 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
3266 if (!stacking_even) stacking_even = "above";
3267 it->item->stacking_even = !!strcmp("above", stacking_even);
3269 stacking = edje_object_data_get(VIEW(it), "stacking");
3270 if (!stacking) stacking = "yes";
3271 it->item->nostacking = !!strcmp("yes", stacking);
3273 edje_object_mirrored_set(it->edit_obj,
3274 elm_widget_mirrored_get(WIDGET(it)));
3276 _elm_genlist_item_odd_even_update(it);
3277 _elm_genlist_item_state_update(it, NULL);
3279 if (effect_on) edje_object_signal_emit(it->edit_obj, "elm,state,edit,enabled,effect", "elm");
3280 else edje_object_signal_emit(it->edit_obj, "elm,state,edit,enabled", "elm");
3282 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
3284 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
3286 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
3288 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MULTI_DOWN,
3290 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MULTI_UP,
3292 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MULTI_MOVE,
3295 _item_text_realize(it, it->edit_obj, &it->item->edit_texts, NULL);
3296 if (it->flipped) edje_object_signal_emit(it->edit_obj, "elm,state,flip,enabled", "elm");
3297 it->item->edit_content_objs =
3298 _item_content_realize(it, it->edit_obj, &it->item->edit_contents, NULL);
3299 _item_state_realize(it, it->edit_obj, &it->item->edit_states, NULL);
3300 edje_object_part_swallow(it->edit_obj, "elm.swallow.edit.content", VIEW(it));
3302 _edit_mode_item_position(it, it->item->scrl_x, it->item->scrl_y);
3303 evas_object_show(it->edit_obj);
3305 it->item->edit_mode_item_realized = EINA_TRUE;
3306 it->want_unrealize = EINA_FALSE;
3310 _edit_mode_item_unrealize(Elm_Gen_Item *it)
3313 if ((!it) || (!it->item->edit_mode_item_realized)) return;
3315 edje_object_part_unswallow(it->edit_obj, VIEW(it));
3316 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
3317 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3318 _elm_genlist_item_odd_even_update(it);
3319 _elm_genlist_item_state_update(it, NULL);
3321 evas_object_del(it->edit_obj);
3322 it->edit_obj = NULL;
3323 elm_widget_stringlist_free(it->item->edit_texts);
3324 it->item->edit_texts = NULL;
3325 elm_widget_stringlist_free(it->item->edit_contents);
3326 it->item->edit_contents = NULL;
3327 elm_widget_stringlist_free(it->item->edit_states);
3328 it->item->edit_states = NULL;
3329 EINA_LIST_FREE(it->item->edit_content_objs, icon)
3330 evas_object_del(icon);
3331 edje_object_message_signal_process(it->edit_obj);
3333 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
3335 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
3337 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
3339 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MULTI_DOWN,
3341 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MULTI_UP,
3343 evas_object_event_callback_del_full(it->edit_obj, EVAS_CALLBACK_MULTI_MOVE,
3345 it->item->edit_mode_item_realized = EINA_FALSE;
3349 _item_auto_scroll(Widget_Data *wd)
3352 Elm_Gen_Item *tmp_item = NULL;
3354 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3356 tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items));
3357 if (!tmp_item) return;
3358 wd->show_item = tmp_item;
3359 wd->bring_in = EINA_TRUE;
3360 wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3361 if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd))
3363 wd->show_item->item->showme = EINA_TRUE;
3364 wd->auto_scroll_enabled = EINA_FALSE;
3372 elm_genlist_add(Evas_Object *parent)
3377 Evas_Coord minw, minh;
3378 static Evas_Smart *smart = NULL;
3382 static Evas_Smart_Class sc;
3384 evas_object_smart_clipped_smart_set(&_pan_sc);
3386 sc.name = "elm_genlist_pan";
3387 sc.version = EVAS_SMART_CLASS_VERSION;
3390 sc.resize = _pan_resize;
3391 sc.move = _pan_move;
3392 sc.calculate = _pan_calculate;
3393 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3396 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3398 ELM_SET_WIDTYPE(widtype, "genlist");
3400 elm_widget_type_set(obj, "genlist");
3401 elm_widget_sub_object_add(parent, obj);
3402 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3403 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3404 elm_widget_data_set(obj, wd);
3405 elm_widget_del_hook_set(obj, _del_hook);
3406 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3407 elm_widget_theme_hook_set(obj, _theme_hook);
3408 elm_widget_can_focus_set(obj, EINA_TRUE);
3409 elm_widget_event_hook_set(obj, _event_hook);
3410 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3411 elm_widget_translate_hook_set(obj, _translate_hook);
3414 wd->scr = elm_smart_scroller_add(e);
3415 elm_smart_scroller_widget_set(wd->scr, obj);
3416 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3417 elm_widget_style_get(obj));
3418 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3419 _elm_config->thumbscroll_bounce_enable);
3420 elm_widget_resize_object_set(obj, wd->scr);
3422 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3423 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3424 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3425 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3426 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3427 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3428 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3429 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3432 wd->mode = ELM_LIST_SCROLL;
3433 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3434 wd->item_cache_max = wd->max_items_per_block * 2;
3435 wd->longpress_timeout = _elm_config->longpress_timeout;
3437 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3438 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3439 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3440 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3442 wd->pan_smart = evas_object_smart_add(e, smart);
3443 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3446 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3447 _pan_set, _pan_get, _pan_max_get,
3448 _pan_min_get, _pan_child_size_get);
3450 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3452 evas_object_size_hint_min_set(obj, minw, minh);
3454 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3456 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3462 _item_select(Elm_Gen_Item *it)
3464 if ((it->wd->no_select) || (it->generation < it->wd->generation) || (it->mode_set)) return;
3467 it->selected = EINA_TRUE;
3468 it->wd->selected = eina_list_append(it->wd->selected, it);
3470 else if (!it->wd->always_select) return;
3472 evas_object_ref(WIDGET(it));
3475 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3476 if (it->generation == it->wd->generation)
3477 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3480 evas_object_unref(WIDGET(it));
3481 if ((it->wd->clear_me) && (!it->wd->walking))
3482 _elm_genlist_clear(WIDGET(it), EINA_TRUE);
3485 if ((!it->walking) && (it->generation < it->wd->generation))
3490 elm_widget_item_free(it);
3494 it->wd->last_selected_item = (Elm_Object_Item *) it;
3498 static Evas_Object *
3499 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3501 return edje_object_part_swallow_get(VIEW(it), part);
3505 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3507 if (content && part)
3509 it->content_objs = eina_list_append(it->content_objs, content);
3510 edje_object_part_swallow(VIEW(it), part, content);
3514 static Evas_Object *
3515 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3518 obj = edje_object_part_swallow_get(VIEW(it), part);
3519 if (!obj) return NULL;
3520 it->content_objs = eina_list_remove(it->content_objs, obj);
3521 edje_object_part_unswallow(VIEW(it), obj);
3526 _item_text_hook(Elm_Gen_Item *it, const char *part)
3528 if (!it->itc->func.text_get) return NULL;
3529 return edje_object_part_text_get(VIEW(it), part);
3533 _item_disable_hook(Elm_Object_Item *it)
3537 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
3539 if (_it->generation < _it->wd->generation) return;
3542 elm_genlist_item_selected_set(it, EINA_FALSE);
3546 if (elm_widget_item_disabled_get(it))
3548 edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm");
3550 edje_object_signal_emit(_it->edit_obj, "elm,state,disabled", "elm");
3554 edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm");
3556 edje_object_signal_emit(_it->edit_obj, "elm,state,enabled", "elm");
3558 EINA_LIST_FOREACH(_it->content_objs, l, obj)
3559 elm_widget_disabled_set(obj, elm_widget_item_disabled_get(_it));
3564 _item_del_pre_hook(Elm_Object_Item *it)
3566 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
3568 if ((_it->relcount > 0) || (_it->walking > 0))
3570 elm_genlist_item_subitems_clear(it);
3571 if (_it->wd->show_item == _it) _it->wd->show_item = NULL;
3572 _elm_genlist_item_del_notserious(_it);
3573 if (_it->item->block)
3575 if (_it->realized) _elm_genlist_item_unrealize(_it, EINA_FALSE);
3576 _it->item->block->changed = EINA_TRUE;
3577 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
3578 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
3582 _it->parent->item->items =
3583 eina_list_remove(_it->parent->item->items, it);
3593 _elm_genlist_item_new(Widget_Data *wd,
3594 const Elm_Gen_Item_Class *itc,
3596 Elm_Gen_Item *parent,
3598 const void *func_data)
3602 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3603 if (!it) return NULL;
3605 it->generation = wd->generation;
3607 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
3608 it->base.data = data;
3609 it->parent = parent;
3610 it->func.func = func;
3611 it->func.data = func_data;
3612 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3613 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3614 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3615 elm_widget_item_text_get_hook_set(it, _item_text_hook);
3616 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3617 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3619 it->sel_cb = (Ecore_Cb)_item_select;
3624 static Elm_Gen_Item *
3625 _item_new(Widget_Data *wd,
3626 const Elm_Genlist_Item_Class *itc,
3628 Elm_Gen_Item *parent,
3629 Elm_Genlist_Item_Flags flags,
3631 const void *func_data)
3633 Elm_Gen_Item *it, *it2;
3636 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3637 if (!it) return NULL;
3638 it->item = ELM_NEW(Elm_Gen_Item_Type);
3639 it->item->flags = flags;
3640 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3641 it->item->expanded_depth = 0;
3642 ELM_GEN_ITEM_SETUP(it);
3645 if (it->parent->group)
3646 it->item->group_item = parent;
3647 else if (it->parent->item->group_item)
3648 it->item->group_item = it->parent->item->group_item;
3650 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
3652 if (!it2->parent->group) depth += 1;
3654 it->item->expanded_depth = depth;
3660 _item_block_new(Widget_Data *wd, Eina_Bool prepend)
3664 itb = calloc(1, sizeof(Item_Block));
3665 if (!itb) return NULL;
3669 wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3670 _item_block_position_update(wd->blocks, 0);
3674 wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3675 itb->position_update = EINA_TRUE;
3676 if (wd->blocks != EINA_INLIST_GET(itb))
3678 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3689 _item_block_add(Widget_Data *wd,
3692 Item_Block *itb = NULL;
3699 itb = calloc(1, sizeof(Item_Block));
3700 if (!itb) return EINA_FALSE;
3702 if (!it->item->rel->item->block)
3705 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3706 itb->items = eina_list_append(itb->items, it);
3707 itb->position_update = EINA_TRUE;
3708 it->position = eina_list_count(itb->items);
3709 it->position_update = EINA_TRUE;
3711 if (wd->blocks != EINA_INLIST_GET(itb))
3713 itb->position = ((Item_Block *) (EINA_INLIST_GET(itb)->prev))->position + 1;
3724 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3725 if (it->item->before)
3727 wd->blocks = eina_inlist_prepend_relative
3728 (wd->blocks, EINA_INLIST_GET(itb),
3729 EINA_INLIST_GET(it->item->rel->item->block));
3731 eina_list_prepend_relative_list(itb->items, it, tmp);
3733 /* Update index from where we prepended */
3734 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3735 _item_block_position_update(EINA_INLIST_GET(itb),
3736 it->item->rel->item->block->position);
3740 wd->blocks = eina_inlist_append_relative
3741 (wd->blocks, EINA_INLIST_GET(itb),
3742 EINA_INLIST_GET(it->item->rel->item->block));
3744 eina_list_append_relative_list(itb->items, it, tmp);
3746 /* Update block index from where we appended */
3747 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3748 _item_block_position_update(EINA_INLIST_GET(itb),
3749 it->item->rel->item->block->position + 1);
3755 if (it->item->before)
3759 itb = (Item_Block *)(wd->blocks);
3760 if (itb->count >= wd->max_items_per_block)
3762 itb = _item_block_new(wd, EINA_TRUE);
3763 if (!itb) return EINA_FALSE;
3768 itb = _item_block_new(wd, EINA_TRUE);
3769 if (!itb) return EINA_FALSE;
3771 itb->items = eina_list_prepend(itb->items, it);
3773 _item_position_update(itb->items, 0);
3779 itb = (Item_Block *)(wd->blocks->last);
3780 if (itb->count >= wd->max_items_per_block)
3782 itb = _item_block_new(wd, EINA_FALSE);
3783 if (!itb) return EINA_FALSE;
3788 itb = _item_block_new(wd, EINA_FALSE);
3789 if (!itb) return EINA_FALSE;
3791 itb->items = eina_list_append(itb->items, it);
3792 it->position = eina_list_count(itb->items);
3800 if (it->item->rel->item->queued)
3802 /* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
3803 on sorted insertion order, so the queue is not always ordered like the item list.
3804 This lead to issue where we depend on an item that is not yet created. As a quick
3805 work around, we reschedule the calc of the item and stop reordering the list to
3806 prevent any nasty issue to show up here.
3808 wd->queue = eina_list_append(wd->queue, it);
3809 wd->requeued = EINA_TRUE;
3810 it->item->queued = EINA_TRUE;
3813 itb = it->item->rel->item->block;
3814 if (!itb) goto newblock;
3815 tmp = eina_list_data_find_list(itb->items, it->item->rel);
3816 if (it->item->before)
3818 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
3819 _item_position_update(eina_list_prev(tmp), it->item->rel->position);
3823 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
3824 _item_position_update(eina_list_next(tmp), it->item->rel->position + 1);
3828 itb->changed = EINA_TRUE;
3829 it->item->block = itb;
3830 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3831 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3834 it->item->rel->relcount--;
3835 if ((it->item->rel->generation < it->wd->generation) && (!it->item->rel->relcount))
3837 _item_del(it->item->rel);
3838 elm_widget_item_free(it->item->rel);
3840 it->item->rel = NULL;
3842 if (itb->count > itb->wd->max_items_per_block)
3847 Eina_Bool done = EINA_FALSE;
3849 newc = itb->count / 2;
3851 if (EINA_INLIST_GET(itb)->prev)
3853 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
3855 if (itbp->count + newc < wd->max_items_per_block / 2)
3857 /* moving items to previous block */
3858 while ((itb->count > newc) && (itb->items))
3860 it2 = eina_list_data_get(itb->items);
3861 itb->items = eina_list_remove_list(itb->items, itb->items);
3864 itbp->items = eina_list_append(itbp->items, it2);
3865 it2->item->block = itbp;
3873 if (!done && EINA_INLIST_GET(itb)->next)
3875 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
3877 if (itbn->count + newc < wd->max_items_per_block / 2)
3879 /* moving items to next block */
3880 while ((itb->count > newc) && (itb->items))
3884 l = eina_list_last(itb->items);
3885 it2 = eina_list_data_get(l);
3886 itb->items = eina_list_remove_list(itb->items, l);
3889 itbn->items = eina_list_prepend(itbn->items, it2);
3890 it2->item->block = itbn;
3900 /* moving items to new block */
3901 itb2 = calloc(1, sizeof(Item_Block));
3902 if (!itb2) return EINA_FALSE;
3905 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3906 EINA_INLIST_GET(itb));
3907 itb2->changed = EINA_TRUE;
3908 while ((itb->count > newc) && (itb->items))
3912 l = eina_list_last(itb->items);
3914 itb->items = eina_list_remove_list(itb->items, l);
3917 itb2->items = eina_list_prepend(itb2->items, it2);
3918 it2->item->block = itb2;
3928 _queue_process(Widget_Data *wd)
3931 Eina_Bool showme = EINA_FALSE;
3934 t0 = ecore_loop_time_get();
3935 //evas_event_freeze(evas_object_evas_get(wd->obj));
3936 for (n = 0; (wd->queue) && (n < 128); n++)
3940 it = eina_list_data_get(wd->queue);
3941 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3942 it->item->queued = EINA_FALSE;
3943 if (!_item_block_add(wd, it)) continue;
3945 _item_block_realize(it->item->block);
3946 t = ecore_time_get();
3947 if (it->item->block->changed)
3949 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3950 it->item->block->changed = 0;
3951 if (wd->pan_changed)
3953 if (wd->calc_job) ecore_job_del(wd->calc_job);
3954 wd->calc_job = NULL;
3956 wd->pan_changed = EINA_FALSE;
3959 if (showme) it->item->block->showme = EINA_TRUE;
3960 /* same as eina_inlist_count > 1 */
3961 if (wd->blocks && wd->blocks->next)
3963 if ((t - t0) > (ecore_animator_frametime_get())) break;
3966 //evas_event_thaw(evas_object_evas_get(wd->obj));
3967 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3972 _idle_process(void *data, Eina_Bool *wakeup)
3974 Widget_Data *wd = data;
3977 //static double q_start = 0.0;
3978 //if (q_start == 0.0) q_start = ecore_time_get();
3980 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
3984 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
3986 return ECORE_CALLBACK_CANCEL;
3988 return ECORE_CALLBACK_RENEW;
3992 _item_idle_enterer(void *data)
3994 Widget_Data *wd = data;
3995 Eina_Bool wakeup = EINA_FALSE;
3996 Eina_Bool ok = _idle_process(data, &wakeup);
4001 if (wd->calc_job) ecore_job_del(wd->calc_job);
4002 wd->calc_job = ecore_job_add(_calc_job, wd);
4004 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
4009 _item_queue(Widget_Data *wd,
4013 if (it->item->queued) return;
4014 it->item->queued = EINA_TRUE;
4015 if (cb && !wd->requeued)
4016 wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
4018 wd->queue = eina_list_append(wd->queue, it);
4019 // FIXME: why does a freeze then thaw here cause some genlist
4020 // elm_genlist_item_append() to be much much slower?
4021 // evas_event_freeze(evas_object_evas_get(wd->obj));
4022 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
4024 if (wd->queue_idle_enterer)
4026 ecore_idle_enterer_del(wd->queue_idle_enterer);
4027 wd->queue_idle_enterer = NULL;
4031 // evas_event_thaw(evas_object_evas_get(wd->obj));
4032 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4033 if (!wd->queue_idle_enterer)
4034 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
4038 _elm_genlist_item_compare(const void *data, const void *data1)
4040 const Elm_Gen_Item *it, *item1;
4041 it = ELM_GEN_ITEM_FROM_INLIST(data);
4042 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
4043 return it->wd->item_compare_cb(it, item1);
4047 _elm_genlist_item_list_compare(const void *data, const void *data1)
4049 const Elm_Gen_Item *it = data;
4050 const Elm_Gen_Item *item1 = data1;
4051 return it->wd->item_compare_cb(it, item1);
4055 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
4060 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4061 _item_block_del(it);
4063 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4064 it->item->rel = after;
4065 it->item->rel->relcount++;
4066 it->item->before = EINA_FALSE;
4067 if (after->item->group_item) it->item->group_item = after->item->group_item;
4068 _item_queue(it->wd, it, NULL);
4070 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4074 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
4077 if (!before) return;
4079 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
4080 _item_block_del(it);
4081 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4082 it->item->rel = before;
4083 it->item->rel->relcount++;
4084 it->item->before = EINA_TRUE;
4085 if (before->item->group_item) it->item->group_item = before->item->group_item;
4086 _item_queue(it->wd, it, NULL);
4088 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
4092 elm_genlist_items_count(const Evas_Object *obj)
4094 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4095 Widget_Data *wd = elm_widget_data_get(obj);
4097 return wd->item_count;
4100 EAPI Elm_Object_Item *
4101 elm_genlist_item_append(Evas_Object *obj,
4102 const Elm_Genlist_Item_Class *itc,
4104 Elm_Object_Item *parent,
4105 Elm_Genlist_Item_Flags flags,
4107 const void *func_data)
4109 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4110 Widget_Data *wd = elm_widget_data_get(obj);
4111 if (!wd) return NULL;
4112 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, flags,
4114 if (!it) return NULL;
4118 wd->group_items = eina_list_append(wd->group_items, it);
4119 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
4120 it->item->rel = NULL;
4124 Elm_Gen_Item *it2 = NULL;
4125 Eina_List *ll = eina_list_last(it->parent->item->items);
4126 if (ll) it2 = ll->data;
4127 it->parent->item->items = eina_list_append(it->parent->item->items, it);
4128 if (!it2) it2 = it->parent;
4130 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4131 EINA_INLIST_GET(it2));
4132 it->item->rel = it2;
4133 it->item->rel->relcount++;
4135 it->item->before = EINA_FALSE;
4136 _item_queue(wd, it, NULL);
4137 return (Elm_Object_Item *) it;
4140 EAPI Elm_Object_Item *
4141 elm_genlist_item_prepend(Evas_Object *obj,
4142 const Elm_Genlist_Item_Class *itc,
4144 Elm_Object_Item *parent,
4145 Elm_Genlist_Item_Flags flags,
4147 const void *func_data)
4149 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4150 Widget_Data *wd = elm_widget_data_get(obj);
4151 if (!wd) return NULL;
4152 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, flags,
4154 if (!it) return NULL;
4158 wd->group_items = eina_list_prepend(wd->group_items, it);
4159 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
4160 it->item->rel = NULL;
4164 Elm_Gen_Item *it2 = NULL;
4165 Eina_List *ll = it->parent->item->items;
4166 if (ll) it2 = ll->data;
4167 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
4168 if (!it2) it2 = it->parent;
4170 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4171 EINA_INLIST_GET(it2));
4172 it->item->rel = it2;
4173 it->item->rel->relcount++;
4175 it->item->before = EINA_TRUE;
4176 _item_queue(wd, it, NULL);
4177 return (Elm_Object_Item *) it;
4180 EAPI Elm_Object_Item *
4181 elm_genlist_item_insert_after(Evas_Object *obj,
4182 const Elm_Genlist_Item_Class *itc,
4184 Elm_Object_Item *parent,
4185 Elm_Object_Item *after,
4186 Elm_Genlist_Item_Flags flags,
4188 const void *func_data)
4190 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4191 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
4192 Widget_Data *wd = elm_widget_data_get(obj);
4193 Elm_Gen_Item *_after = (Elm_Gen_Item *) after;
4194 if (!wd) return NULL;
4195 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
4196 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4198 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, flags,
4200 if (!it) return NULL;
4203 if ((it->group) && (_after->group))
4204 wd->group_items = eina_list_append_relative(wd->group_items, it,
4209 it->parent->item->items =
4210 eina_list_append_relative(it->parent->item->items, it, _after);
4212 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
4213 EINA_INLIST_GET(_after));
4214 it->item->rel = _after;
4215 it->item->rel->relcount++;
4216 it->item->before = EINA_FALSE;
4217 _item_queue(wd, it, NULL);
4218 return (Elm_Object_Item *) it;
4221 EAPI Elm_Object_Item *
4222 elm_genlist_item_insert_before(Evas_Object *obj,
4223 const Elm_Genlist_Item_Class *itc,
4225 Elm_Object_Item *parent,
4226 Elm_Object_Item *before,
4227 Elm_Genlist_Item_Flags flags,
4229 const void *func_data)
4231 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4232 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
4233 Widget_Data *wd = elm_widget_data_get(obj);
4234 Elm_Gen_Item *_before = (Elm_Gen_Item *) before;
4235 if (!wd) return NULL;
4236 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
4237 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
4239 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, flags,
4241 if (!it) return NULL;
4244 if (it->group && _before->group)
4245 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
4250 it->parent->item->items =
4251 eina_list_prepend_relative(it->parent->item->items, it, _before);
4253 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
4254 EINA_INLIST_GET(_before));
4255 it->item->rel = _before;
4256 it->item->rel->relcount++;
4257 it->item->before = EINA_TRUE;
4258 _item_queue(wd, it, NULL);
4259 return (Elm_Object_Item *) it;
4262 EAPI Elm_Object_Item *
4263 elm_genlist_item_sorted_insert(Evas_Object *obj,
4264 const Elm_Genlist_Item_Class *itc,
4266 Elm_Object_Item *parent,
4267 Elm_Genlist_Item_Flags flags,
4268 Eina_Compare_Cb comp,
4270 const void *func_data)
4272 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4273 Widget_Data *wd = elm_widget_data_get(obj);
4274 if (!wd) return NULL;
4275 Elm_Gen_Item *rel = NULL;
4276 Elm_Gen_Item *it = _item_new(wd, itc, data, (Elm_Gen_Item *) parent, flags,
4278 if (!it) return NULL;
4280 wd->item_compare_cb = comp;
4287 l = eina_list_search_sorted_near_list(it->parent->item->items,
4288 _elm_genlist_item_list_compare,
4292 rel = eina_list_data_get(l);
4296 if (cmp_result >= 0)
4298 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
4299 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4300 it->item->before = EINA_FALSE;
4302 else if (cmp_result < 0)
4304 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
4305 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
4306 it->item->before = EINA_TRUE;
4313 wd->state = eina_inlist_sorted_state_new();
4314 eina_inlist_sorted_state_init(wd->state, wd->items);
4315 wd->requeued = EINA_FALSE;
4319 wd->group_items = eina_list_append(wd->group_items, it);
4321 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
4322 _elm_genlist_item_compare, wd->state);
4324 if (EINA_INLIST_GET(it)->next)
4326 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4327 it->item->before = EINA_TRUE;
4329 else if (EINA_INLIST_GET(it)->prev)
4331 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4332 it->item->before = EINA_FALSE;
4338 it->item->rel = rel;
4339 it->item->rel->relcount++;
4342 _item_queue(wd, it, _elm_genlist_item_list_compare);
4344 return (Elm_Object_Item *) it;
4348 _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
4350 Eina_Inlist *next, *l;
4352 ELM_CHECK_WIDTYPE(obj, widtype);
4353 Widget_Data *wd = elm_widget_data_get(obj);
4356 if (!standby) wd->generation++;
4360 eina_inlist_sorted_state_free(wd->state);
4364 if (wd->walking > 0)
4366 wd->clear_me = EINA_TRUE;
4369 evas_event_freeze(evas_object_evas_get(wd->obj));
4370 for (l = wd->items, next = l ? l->next : NULL;
4372 l = next, next = next ? next->next : NULL)
4374 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
4376 if (it->generation < wd->generation)
4378 Elm_Gen_Item *itn = NULL;
4380 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
4381 if (itn) itn->walking++; /* prevent early death of subitem */
4383 elm_widget_item_free(it);
4384 if (itn) itn->walking--;
4387 wd->clear_me = EINA_FALSE;
4388 wd->pan_changed = EINA_TRUE;
4391 ecore_job_del(wd->calc_job);
4392 wd->calc_job = NULL;
4394 if (wd->selected) wd->selected = eina_list_free(wd->selected);
4395 if (wd->clear_cb) wd->clear_cb(wd);
4402 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
4403 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
4405 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
4406 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
4407 evas_event_thaw(evas_object_evas_get(wd->obj));
4408 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
4412 elm_genlist_clear(Evas_Object *obj)
4414 _elm_genlist_clear(obj, EINA_FALSE);
4418 elm_genlist_multi_select_set(Evas_Object *obj,
4421 ELM_CHECK_WIDTYPE(obj, widtype);
4422 Widget_Data *wd = elm_widget_data_get(obj);
4424 wd->multi = !!multi;
4428 elm_genlist_multi_select_get(const Evas_Object *obj)
4430 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4431 Widget_Data *wd = elm_widget_data_get(obj);
4432 if (!wd) return EINA_FALSE;
4436 EAPI Elm_Object_Item *
4437 elm_genlist_selected_item_get(const Evas_Object *obj)
4439 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4440 Widget_Data *wd = elm_widget_data_get(obj);
4441 if (!wd) return NULL;
4442 if (wd->selected) return wd->selected->data;
4446 EAPI const Eina_List *
4447 elm_genlist_selected_items_get(const Evas_Object *obj)
4449 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4450 Widget_Data *wd = elm_widget_data_get(obj);
4451 if (!wd) return NULL;
4452 return wd->selected;
4456 elm_genlist_realized_items_get(const Evas_Object *obj)
4458 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4459 Widget_Data *wd = elm_widget_data_get(obj);
4460 Eina_List *list = NULL;
4462 Eina_Bool done = EINA_FALSE;
4463 if (!wd) return NULL;
4464 EINA_INLIST_FOREACH(wd->blocks, itb)
4472 EINA_LIST_FOREACH(itb->items, l, it)
4474 if (it->realized) list = eina_list_append(list, it);
4485 EAPI Elm_Object_Item *
4486 elm_genlist_at_xy_item_get(const Evas_Object *obj,
4491 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4492 Widget_Data *wd = elm_widget_data_get(obj);
4493 Evas_Coord ox, oy, ow, oh;
4496 if (!wd) return NULL;
4497 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4499 EINA_INLIST_FOREACH(wd->blocks, itb)
4504 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
4505 oy + itb->y - itb->wd->pan_y,
4506 itb->w, itb->h, x, y, 1, 1))
4508 EINA_LIST_FOREACH(itb->items, l, it)
4510 Evas_Coord itx, ity;
4512 itx = ox + itb->x + it->x - itb->wd->pan_x;
4513 ity = oy + itb->y + it->y - itb->wd->pan_y;
4514 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
4518 if (y <= (ity + (it->item->h / 4))) *posret = -1;
4519 else if (y >= (ity + it->item->h - (it->item->h / 4)))
4523 return (Elm_Object_Item *) it;
4525 lasty = ity + it->item->h;
4530 if (y > lasty) *posret = 1;
4536 EAPI Elm_Object_Item *
4537 elm_genlist_first_item_get(const Evas_Object *obj)
4539 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4540 Widget_Data *wd = elm_widget_data_get(obj);
4541 if (!wd) return NULL;
4542 if (!wd->items) return NULL;
4543 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4544 while ((it) && (it->generation < wd->generation))
4545 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4546 return (Elm_Object_Item *) it;
4549 EAPI Elm_Object_Item *
4550 elm_genlist_last_item_get(const Evas_Object *obj)
4552 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4553 Widget_Data *wd = elm_widget_data_get(obj);
4554 if (!wd) return NULL;
4555 if (!wd->items) return NULL;
4556 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4557 while ((it) && (it->generation < wd->generation))
4558 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4559 return (Elm_Object_Item *) it;
4562 EAPI Elm_Object_Item *
4563 elm_genlist_item_next_get(const Elm_Object_Item *it)
4565 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4566 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4569 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->next);
4570 if ((_it) && (_it->generation == _it->wd->generation)) break;
4572 return (Elm_Object_Item *) _it;
4575 EAPI Elm_Object_Item *
4576 elm_genlist_item_prev_get(const Elm_Object_Item *it)
4578 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4579 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4582 _it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(_it)->prev);
4583 if ((_it) && (_it->generation == _it->wd->generation)) break;
4585 return (Elm_Object_Item *) _it;
4588 EINA_DEPRECATED EAPI Evas_Object *
4589 elm_genlist_item_genlist_get(const Elm_Object_Item *it)
4591 return elm_object_item_widget_get(it);
4594 EAPI Elm_Object_Item *
4595 elm_genlist_item_parent_get(const Elm_Object_Item *it)
4597 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4598 return (Elm_Object_Item *) ((Elm_Gen_Item *) it)->parent;
4602 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
4604 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4605 Eina_List *tl = NULL, *l;
4607 Elm_Object_Item *it2;
4608 _it = (Elm_Gen_Item *) it;
4610 EINA_LIST_FOREACH(_it->item->items, l, it2)
4611 tl = eina_list_append(tl, it2);
4612 EINA_LIST_FREE(tl, it2)
4613 elm_object_item_del(it2);
4617 elm_genlist_item_selected_set(Elm_Object_Item *it,
4620 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4621 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4622 Widget_Data *wd = _it->wd;
4624 if ((_it->generation < wd->generation) || elm_widget_item_disabled_get(_it))
4626 selected = !!selected;
4627 if (_it->selected == selected) return;
4633 while (wd->selected)
4635 if (_it->unhighlight_cb) _it->unhighlight_cb(wd->selected->data);
4636 _it->unsel_cb(wd->selected->data);
4639 _it->highlight_cb(_it);
4643 if (_it->unhighlight_cb) _it->unhighlight_cb(_it);
4648 elm_genlist_item_selected_get(const Elm_Object_Item *it)
4650 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4651 return ((Elm_Gen_Item *) it)->selected;
4655 elm_genlist_item_expanded_set(Elm_Object_Item *it,
4658 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4659 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4660 expanded = !!expanded;
4661 if (_it->item->expanded == expanded) return;
4662 _it->item->expanded = expanded;
4663 if (_it->item->expanded)
4666 edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
4667 evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
4668 _it->wd->auto_scroll_enabled = EINA_TRUE;
4669 _it->wd->expanded_item = _it;
4674 edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
4675 evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
4676 _it->wd->auto_scroll_enabled = EINA_FALSE;
4677 _it->wd->expanded_item = NULL;
4682 elm_genlist_item_expanded_get(const Elm_Object_Item *it)
4684 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4685 return ((Elm_Gen_Item *) it)->item->expanded;
4689 elm_genlist_item_expanded_depth_get(const Elm_Object_Item *it)
4691 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
4692 return ((Elm_Gen_Item *) it)->item->expanded_depth;
4695 EINA_DEPRECATED EAPI void
4696 elm_genlist_item_disabled_set(Elm_Object_Item *it,
4699 elm_object_item_disabled_set(it, disabled);
4702 EINA_DEPRECATED EAPI Eina_Bool
4703 elm_genlist_item_disabled_get(const Elm_Object_Item *it)
4705 return elm_object_item_disabled_get(it);
4709 elm_genlist_item_display_only_set(Elm_Object_Item *it,
4710 Eina_Bool display_only)
4712 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4713 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4714 display_only = !!display_only;
4715 if (_it->display_only == display_only) return;
4716 if (_it->generation < _it->wd->generation) return;
4717 _it->display_only = display_only;
4718 _it->item->mincalcd = EINA_FALSE;
4719 _it->item->updateme = EINA_TRUE;
4720 if (_it->item->block) _it->item->block->updateme = EINA_TRUE;
4721 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
4722 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
4726 elm_genlist_item_display_only_get(const Elm_Object_Item *it)
4728 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4729 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4730 if (_it->generation < _it->wd->generation) return EINA_FALSE;
4731 return _it->display_only;
4735 elm_genlist_item_show(Elm_Object_Item *it)
4737 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4738 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4739 Evas_Coord gith = 0;
4740 if (_it->generation < _it->wd->generation) return;
4741 if ((_it->item->queued) || (!_it->item->mincalcd))
4743 _it->wd->show_item = _it;
4744 _it->wd->bring_in = EINA_FALSE;
4745 _it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
4746 _it->item->showme = EINA_TRUE;
4749 if (_it->wd->show_item)
4751 _it->wd->show_item->item->showme = EINA_FALSE;
4752 _it->wd->show_item = NULL;
4754 if ((_it->item->group_item) &&
4755 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4756 gith = _it->item->group_item->item->h;
4757 elm_smart_scroller_child_region_show(_it->wd->scr,
4758 _it->x + _it->item->block->x,
4759 _it->y + _it->item->block->y - gith,
4760 _it->item->block->w, _it->item->h);
4764 elm_genlist_item_promote(Elm_Object_Item *it)
4766 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4767 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4768 if (_it->generation < _it->wd->generation) return;
4769 _item_move_before(_it,
4770 (Elm_Gen_Item *) elm_genlist_first_item_get(WIDGET(_it)));
4774 elm_genlist_item_demote(Elm_Object_Item *it)
4776 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4777 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4778 if (_it->generation < _it->wd->generation) return;
4779 _item_move_after(_it,
4780 (Elm_Gen_Item *) elm_genlist_last_item_get(WIDGET(_it)));
4784 elm_genlist_item_bring_in(Elm_Object_Item *it)
4786 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4787 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4788 Evas_Coord gith = 0;
4789 if (_it->generation < _it->wd->generation) return;
4790 if ((_it->item->queued) || (!_it->item->mincalcd))
4792 _it->wd->show_item = _it;
4793 _it->wd->bring_in = EINA_TRUE;
4794 _it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
4795 _it->item->showme = EINA_TRUE;
4798 if (_it->wd->show_item)
4800 _it->wd->show_item->item->showme = EINA_FALSE;
4801 _it->wd->show_item = NULL;
4803 if ((_it->item->group_item) &&
4804 (_it->wd->pan_y > (_it->y + _it->item->block->y)))
4805 gith = _it->item->group_item->item->h;
4806 elm_smart_scroller_region_bring_in(_it->wd->scr,
4807 _it->x + _it->item->block->x,
4808 _it->y + _it->item->block->y - gith,
4809 _it->item->block->w, _it->item->h);
4813 elm_genlist_item_top_show(Elm_Object_Item *it)
4815 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4816 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4818 Evas_Coord gith = 0;
4820 if (_it->generation < _it->wd->generation) return;
4821 if ((_it->item->queued) || (!_it->item->mincalcd))
4823 _it->wd->show_item = _it;
4824 _it->wd->bring_in = EINA_FALSE;
4825 _it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
4826 _it->item->showme = EINA_TRUE;
4829 if (_it->wd->show_item)
4831 _it->wd->show_item->item->showme = EINA_FALSE;
4832 _it->wd->show_item = NULL;
4834 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, &ow, &oh);
4835 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4836 elm_smart_scroller_child_region_show(_it->wd->scr,
4837 _it->x + _it->item->block->x,
4838 _it->y + _it->item->block->y - gith,
4839 _it->item->block->w, oh);
4843 elm_genlist_item_top_bring_in(Elm_Object_Item *it)
4845 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4846 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4848 Evas_Coord gith = 0;
4850 if (_it->generation < _it->wd->generation) return;
4851 if ((_it->item->queued) || (!_it->item->mincalcd))
4853 _it->wd->show_item = _it;
4854 _it->wd->bring_in = EINA_TRUE;
4855 _it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
4856 _it->item->showme = EINA_TRUE;
4859 if (_it->wd->show_item)
4861 _it->wd->show_item->item->showme = EINA_FALSE;
4862 _it->wd->show_item = NULL;
4864 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, &ow, &oh);
4865 if (_it->item->group_item) gith = _it->item->group_item->item->h;
4866 elm_smart_scroller_region_bring_in(_it->wd->scr,
4867 _it->x + _it->item->block->x,
4868 _it->y + _it->item->block->y - gith,
4869 _it->item->block->w, oh);
4873 elm_genlist_item_middle_show(Elm_Object_Item *it)
4875 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4876 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4879 if (_it->generation < _it->wd->generation) return;
4880 if ((_it->item->queued) || (!_it->item->mincalcd))
4882 _it->wd->show_item = _it;
4883 _it->wd->bring_in = EINA_FALSE;
4884 _it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE;
4885 _it->item->showme = EINA_TRUE;
4888 if (_it->wd->show_item)
4890 _it->wd->show_item->item->showme = EINA_FALSE;
4891 _it->wd->show_item = NULL;
4893 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, &ow, &oh);
4894 elm_smart_scroller_child_region_show(_it->wd->scr,
4895 _it->x + _it->item->block->x,
4896 _it->y + _it->item->block->y - oh / 2 +
4897 _it->item->h / 2, _it->item->block->w,
4902 elm_genlist_item_middle_bring_in(Elm_Object_Item *it)
4904 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4905 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4908 if (_it->generation < _it->wd->generation) return;
4909 if ((_it->item->queued) || (!_it->item->mincalcd))
4911 _it->wd->show_item = _it;
4912 _it->wd->bring_in = EINA_TRUE;
4913 _it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE;
4914 _it->item->showme = EINA_TRUE;
4917 if (_it->wd->show_item)
4919 _it->wd->show_item->item->showme = EINA_FALSE;
4920 _it->wd->show_item = NULL;
4922 evas_object_geometry_get(_it->wd->pan_smart, NULL, NULL, &ow, &oh);
4923 elm_smart_scroller_region_bring_in(_it->wd->scr,
4924 _it->x + _it->item->block->x,
4925 _it->y + _it->item->block->y - oh / 2 +
4926 _it->item->h / 2, _it->item->block->w,
4931 elm_genlist_item_del(Elm_Object_Item *it)
4933 elm_object_item_del(it);
4937 elm_genlist_item_data_set(Elm_Object_Item *it,
4940 elm_object_item_data_set(it, (void *) data);
4944 elm_genlist_item_data_get(const Elm_Object_Item *it)
4946 return elm_object_item_data_get(it);
4950 elm_genlist_item_icons_orphan(Elm_Object_Item *it)
4952 elm_genlist_item_contents_orphan(it);
4956 elm_genlist_item_contents_orphan(Elm_Object_Item *it)
4958 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4960 Evas_Object *content;
4961 EINA_LIST_FREE(((Elm_Gen_Item *) it)->content_objs, content)
4963 elm_widget_sub_object_del(WIDGET(it), content);
4964 evas_object_smart_member_del(content);
4965 evas_object_hide(content);
4969 EINA_DEPRECATED EAPI const Evas_Object *
4970 elm_genlist_item_object_get(const Elm_Object_Item *it)
4972 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
4977 elm_genlist_item_update(Elm_Object_Item *it)
4979 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4980 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4982 if (!_it->item->block) return;
4983 if (_it->generation < _it->wd->generation) return;
4984 _it->item->mincalcd = EINA_FALSE;
4985 _it->item->updateme = EINA_TRUE;
4986 _it->item->block->updateme = EINA_TRUE;
4987 if (_it->wd->update_job) ecore_job_del(_it->wd->update_job);
4988 _it->wd->update_job = ecore_job_add(_update_job, _it->wd);
4992 elm_genlist_item_fields_update(Elm_Object_Item *it,
4994 Elm_Genlist_Item_Field_Flags itf)
4996 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
4997 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
4999 if (!_it->item->block) return;
5000 if (_it->generation < _it->wd->generation) return;
5002 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
5003 _item_text_realize(_it, VIEW(_it), &_it->texts, parts);
5004 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
5006 _it->content_objs = _item_content_unrealize(_it, VIEW(_it),
5007 &_it->contents, parts);
5008 _it->content_objs = _item_content_realize(_it, VIEW(_it),
5009 &_it->contents, parts);
5011 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
5012 _item_state_realize(_it, VIEW(_it), &_it->states, parts);
5016 elm_genlist_item_item_class_update(Elm_Object_Item *it,
5017 const Elm_Genlist_Item_Class *itc)
5019 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5020 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5022 if (!_it->item->block) return;
5023 EINA_SAFETY_ON_NULL_RETURN(itc);
5024 if (_it->generation < _it->wd->generation) return;
5026 _it->item->nocache = EINA_TRUE;
5027 elm_genlist_item_update(it);
5030 EAPI const Elm_Genlist_Item_Class *
5031 elm_genlist_item_item_class_get(const Elm_Object_Item *it)
5033 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
5034 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5035 if (_it->generation < _it->wd->generation) return NULL;
5039 static Evas_Object *
5040 _elm_genlist_item_label_create(void *data,
5041 Evas_Object *obj __UNUSED__,
5042 Evas_Object *tooltip,
5043 void *it __UNUSED__)
5045 Evas_Object *label = elm_label_add(tooltip);
5048 elm_object_style_set(label, "tooltip");
5049 elm_object_text_set(label, data);
5054 _elm_genlist_item_label_del_cb(void *data,
5055 Evas_Object *obj __UNUSED__,
5056 void *event_info __UNUSED__)
5058 eina_stringshare_del(data);
5062 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
5065 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5066 text = eina_stringshare_add(text);
5067 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
5069 _elm_genlist_item_label_del_cb);
5073 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *it,
5074 Elm_Tooltip_Item_Content_Cb func,
5076 Evas_Smart_Cb del_cb)
5078 ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error);
5079 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5081 if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data))
5084 if (_it->tooltip.del_cb)
5085 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(it), it);
5087 _it->tooltip.content_cb = func;
5088 _it->tooltip.data = data;
5089 _it->tooltip.del_cb = del_cb;
5093 elm_widget_item_tooltip_content_cb_set(_it,
5094 _it->tooltip.content_cb,
5095 _it->tooltip.data, NULL);
5096 elm_widget_item_tooltip_style_set(_it, _it->tooltip.style);
5097 elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size);
5103 if (del_cb) del_cb((void *)data, NULL, NULL);
5107 elm_genlist_item_tooltip_unset(Elm_Object_Item *it)
5109 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5110 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5112 if ((VIEW(_it)) && (_it->tooltip.content_cb))
5113 elm_widget_item_tooltip_unset(_it);
5115 if (_it->tooltip.del_cb)
5116 _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it);
5117 _it->tooltip.del_cb = NULL;
5118 _it->tooltip.content_cb = NULL;
5119 _it->tooltip.data = NULL;
5120 _it->tooltip.free_size = EINA_FALSE;
5121 if (_it->tooltip.style)
5122 elm_genlist_item_tooltip_style_set(it, NULL);
5126 elm_genlist_item_tooltip_style_set(Elm_Object_Item *it,
5129 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5130 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5132 eina_stringshare_replace(&_it->tooltip.style, style);
5133 if (VIEW(_it)) elm_widget_item_tooltip_style_set(_it, style);
5137 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
5139 return elm_object_item_tooltip_style_get(it);
5143 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *it,
5146 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5147 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5149 _it->tooltip.free_size = disable;
5150 if (VIEW(_it)) return elm_widget_item_tooltip_window_mode_set(_it, disable);
5155 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *it)
5157 return elm_object_tooltip_window_mode_get(VIEW(it));
5161 elm_genlist_item_cursor_set(Elm_Object_Item *it,
5164 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5165 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5166 eina_stringshare_replace(&_it->mouse_cursor, cursor);
5167 if (VIEW(_it)) elm_widget_item_cursor_set(_it, cursor);
5171 elm_genlist_item_cursor_get(const Elm_Object_Item *it)
5173 return elm_widget_item_cursor_get(it);
5177 elm_genlist_item_cursor_unset(Elm_Object_Item *it)
5179 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5180 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5182 if (!_it->mouse_cursor) return;
5184 if (VIEW(_it)) elm_widget_item_cursor_unset(_it);
5186 eina_stringshare_del(_it->mouse_cursor);
5187 _it->mouse_cursor = NULL;
5191 elm_genlist_item_cursor_style_set(Elm_Object_Item *it,
5194 elm_widget_item_cursor_style_set(it, style);
5198 elm_genlist_item_cursor_style_get(const Elm_Object_Item *it)
5200 return elm_widget_item_cursor_style_get(it);
5204 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *it,
5205 Eina_Bool engine_only)
5207 elm_widget_item_cursor_engine_only_set(it, engine_only);
5211 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *it)
5213 return elm_widget_item_cursor_engine_only_get(it);
5217 elm_genlist_item_index_get(const Elm_Object_Item *it)
5219 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1);
5220 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5222 if (_it->item->block)
5223 return _it->position + _it->item->block->position;
5228 elm_genlist_mode_set(Evas_Object *obj,
5231 ELM_CHECK_WIDTYPE(obj, widtype);
5232 Widget_Data *wd = elm_widget_data_get(obj);
5234 if (wd->mode == mode) return;
5240 elm_genlist_horizontal_set(Evas_Object *obj,
5243 elm_genlist_mode_set(obj, mode);
5247 elm_genlist_horizontal_mode_set(Evas_Object *obj,
5250 elm_genlist_mode_set(obj, mode);
5254 elm_genlist_mode_get(const Evas_Object *obj)
5256 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
5257 Widget_Data *wd = elm_widget_data_get(obj);
5258 if (!wd) return ELM_LIST_LAST;
5262 EINA_DEPRECATED EAPI Elm_List_Mode
5263 elm_genlist_horizontal_get(const Evas_Object *obj)
5265 return elm_genlist_mode_get(obj);
5268 EINA_DEPRECATED EAPI Elm_List_Mode
5269 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
5271 return elm_genlist_mode_get(obj);
5275 elm_genlist_always_select_mode_set(Evas_Object *obj,
5276 Eina_Bool always_select)
5278 ELM_CHECK_WIDTYPE(obj, widtype);
5279 Widget_Data *wd = elm_widget_data_get(obj);
5281 wd->always_select = !!always_select;
5285 elm_genlist_always_select_mode_get(const Evas_Object *obj)
5287 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5288 Widget_Data *wd = elm_widget_data_get(obj);
5289 if (!wd) return EINA_FALSE;
5290 return wd->always_select;
5294 elm_genlist_no_select_mode_set(Evas_Object *obj,
5295 Eina_Bool no_select)
5297 ELM_CHECK_WIDTYPE(obj, widtype);
5298 Widget_Data *wd = elm_widget_data_get(obj);
5300 wd->no_select = !!no_select;
5304 elm_genlist_no_select_mode_get(const Evas_Object *obj)
5306 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5307 Widget_Data *wd = elm_widget_data_get(obj);
5308 if (!wd) return EINA_FALSE;
5309 return wd->no_select;
5313 elm_genlist_compress_mode_set(Evas_Object *obj,
5316 ELM_CHECK_WIDTYPE(obj, widtype);
5317 Widget_Data *wd = elm_widget_data_get(obj);
5319 wd->compress = !!compress;
5320 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
5324 elm_genlist_compress_mode_get(const Evas_Object *obj)
5326 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5327 Widget_Data *wd = elm_widget_data_get(obj);
5328 if (!wd) return EINA_FALSE;
5329 return wd->compress;
5333 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
5334 Eina_Bool height_for_width)
5336 ELM_CHECK_WIDTYPE(obj, widtype);
5337 Widget_Data *wd = elm_widget_data_get(obj);
5339 wd->height_for_width = !!height_for_width;
5340 if (wd->height_for_width)
5342 elm_genlist_homogeneous_set(obj, EINA_FALSE);
5343 elm_genlist_compress_mode_set(obj, EINA_TRUE);
5348 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
5350 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5351 Widget_Data *wd = elm_widget_data_get(obj);
5352 if (!wd) return EINA_FALSE;
5353 return wd->height_for_width;
5357 elm_genlist_bounce_set(Evas_Object *obj,
5361 ELM_CHECK_WIDTYPE(obj, widtype);
5362 Widget_Data *wd = elm_widget_data_get(obj);
5364 wd->h_bounce = !!h_bounce;
5365 wd->v_bounce = !!v_bounce;
5366 elm_smart_scroller_bounce_allow_set(wd->scr, wd->h_bounce, wd->v_bounce);
5370 elm_genlist_bounce_get(const Evas_Object *obj,
5371 Eina_Bool *h_bounce,
5372 Eina_Bool *v_bounce)
5374 ELM_CHECK_WIDTYPE(obj, widtype);
5375 Widget_Data *wd = elm_widget_data_get(obj);
5377 if (h_bounce) *h_bounce = wd->h_bounce;
5378 if (v_bounce) *v_bounce = wd->v_bounce;
5382 elm_genlist_homogeneous_set(Evas_Object *obj,
5383 Eina_Bool homogeneous)
5385 ELM_CHECK_WIDTYPE(obj, widtype);
5386 Widget_Data *wd = elm_widget_data_get(obj);
5388 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
5389 wd->homogeneous = !!homogeneous;
5393 elm_genlist_homogeneous_get(const Evas_Object *obj)
5395 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5396 Widget_Data *wd = elm_widget_data_get(obj);
5397 if (!wd) return EINA_FALSE;
5398 return wd->homogeneous;
5402 elm_genlist_block_count_set(Evas_Object *obj,
5405 ELM_CHECK_WIDTYPE(obj, widtype);
5406 Widget_Data *wd = elm_widget_data_get(obj);
5408 wd->max_items_per_block = count;
5409 wd->item_cache_max = wd->max_items_per_block * 2;
5410 _item_cache_clean(wd);
5414 elm_genlist_block_count_get(const Evas_Object *obj)
5416 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5417 Widget_Data *wd = elm_widget_data_get(obj);
5419 return wd->max_items_per_block;
5423 elm_genlist_longpress_timeout_set(Evas_Object *obj,
5426 ELM_CHECK_WIDTYPE(obj, widtype);
5427 Widget_Data *wd = elm_widget_data_get(obj);
5429 wd->longpress_timeout = timeout;
5433 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
5435 ELM_CHECK_WIDTYPE(obj, widtype) 0;
5436 Widget_Data *wd = elm_widget_data_get(obj);
5438 return wd->longpress_timeout;
5442 elm_genlist_scroller_policy_set(Evas_Object *obj,
5443 Elm_Scroller_Policy policy_h,
5444 Elm_Scroller_Policy policy_v)
5446 ELM_CHECK_WIDTYPE(obj, widtype);
5447 Widget_Data *wd = elm_widget_data_get(obj);
5448 if ((!wd) || (!wd->scr)) return;
5449 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
5450 (policy_v >= ELM_SCROLLER_POLICY_LAST))
5452 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
5456 elm_genlist_scroller_policy_get(const Evas_Object *obj,
5457 Elm_Scroller_Policy *policy_h,
5458 Elm_Scroller_Policy *policy_v)
5460 ELM_CHECK_WIDTYPE(obj, widtype);
5461 Widget_Data *wd = elm_widget_data_get(obj);
5462 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
5463 if ((!wd) || (!wd->scr)) return;
5464 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
5465 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
5466 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
5470 elm_genlist_realized_items_update(Evas_Object *obj)
5472 ELM_CHECK_WIDTYPE(obj, widtype);
5474 Eina_List *list, *l;
5475 Elm_Object_Item *it;
5477 list = elm_genlist_realized_items_get(obj);
5478 EINA_LIST_FOREACH(list, l, it)
5479 elm_genlist_item_update(it);
5483 elm_genlist_item_mode_set(Elm_Object_Item *it,
5484 const char *mode_type,
5487 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5488 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5490 Widget_Data *wd = _it->wd;
5492 Elm_Object_Item *it2;
5495 if (!mode_type) return;
5496 if ((_it->generation < _it->wd->generation) ||
5497 elm_widget_item_disabled_get(_it)) return;
5498 if (wd->edit_mode) return;
5500 if ((wd->mode_item == _it) &&
5501 (!strcmp(mode_type, wd->mode_type)) &&
5504 if (!_it->itc->mode_item_style) return;
5505 _it->mode_set = mode_set;
5509 EINA_LIST_FOREACH(wd->selected, l, it2)
5510 if (((Elm_Gen_Item *) it2)->realized)
5511 elm_genlist_item_selected_set(it2, EINA_FALSE);
5515 it2 = elm_genlist_selected_item_get(wd->obj);
5516 if ((it2) && (((Elm_Gen_Item *) it2)->realized))
5517 elm_genlist_item_selected_set(it2, EINA_FALSE);
5520 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
5522 ((_it == wd->mode_item) && (!mode_set)))
5523 _item_mode_unset(wd);
5525 eina_stringshare_replace(&wd->mode_type, mode_type);
5526 if (mode_set) _item_mode_set(_it);
5530 elm_genlist_mode_item_style_get(const Evas_Object *obj)
5532 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5533 Widget_Data *wd = elm_widget_data_get(obj);
5534 if (!wd) return NULL;
5535 return wd->mode_item->itc->mode_item_style;
5539 elm_genlist_mode_item_style_set(Evas_Object *obj, const char *style)
5541 ELM_CHECK_WIDTYPE(obj, widtype);
5542 Widget_Data *wd = elm_widget_data_get(obj);
5544 if ((style == wd->mode_item->itc->mode_item_style) ||
5545 (style && wd->mode_item->itc->mode_item_style &&
5546 (!strcmp(style, wd->mode_item->itc->mode_item_style))))
5548 eina_stringshare_replace((const char**)&wd->mode_item->itc->mode_item_style, style);
5549 elm_genlist_realized_items_update(obj);
5553 elm_genlist_mode_type_get(const Evas_Object *obj)
5555 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5556 Widget_Data *wd = elm_widget_data_get(obj);
5557 if (!wd) return NULL;
5558 return wd->mode_type;
5561 EAPI const Elm_Object_Item *
5562 elm_genlist_mode_item_get(const Evas_Object *obj)
5564 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5565 Widget_Data *wd = elm_widget_data_get(obj);
5566 if (!wd) return NULL;
5567 return (Elm_Object_Item *) wd->mode_item;
5571 elm_genlist_edit_mode_get(const Evas_Object *obj)
5573 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5574 Widget_Data *wd = elm_widget_data_get(obj);
5575 if (!wd) return EINA_FALSE;
5577 return wd->edit_mode;
5581 elm_genlist_edit_mode_set(Evas_Object *obj, Eina_Bool edit_mode)
5583 ELM_CHECK_WIDTYPE(obj, widtype);
5584 Eina_List *list, *l;
5587 Widget_Data *wd = elm_widget_data_get(obj);
5589 edit_mode = !!edit_mode;
5590 if (wd->edit_mode == edit_mode) return;
5591 wd->edit_mode = edit_mode;
5593 list = elm_genlist_realized_items_get(obj);
5596 EINA_LIST_FOREACH(list, l, it)
5598 if (it->item->flags != ELM_GENLIST_ITEM_GROUP)
5599 _edit_mode_item_unrealize(it);
5601 _item_cache_zero(wd);
5605 EINA_LIST_FOREACH(list, l, it)
5607 if (it->item->flags != ELM_GENLIST_ITEM_GROUP)
5609 if (it->selected) _item_unselect(it);
5610 if (it->itc->edit_item_style)
5611 _edit_mode_item_realize(it, EINA_TRUE);
5615 if (wd->calc_job) ecore_job_del(wd->calc_job);
5616 wd->calc_job = ecore_job_add(_calc_job, wd);
5620 elm_genlist_reorder_mode_set(Evas_Object *obj,
5621 Eina_Bool reorder_mode)
5623 ELM_CHECK_WIDTYPE(obj, widtype);
5624 Widget_Data *wd = elm_widget_data_get(obj);
5626 wd->reorder_mode = !!reorder_mode;
5630 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5632 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5633 Widget_Data *wd = elm_widget_data_get(obj);
5634 if (!wd) return EINA_FALSE;
5635 return wd->reorder_mode;
5638 EAPI Elm_Genlist_Item_Flags
5639 elm_genlist_item_flags_get(const Elm_Object_Item *it)
5641 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
5642 Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
5643 return _it->item->flags;
5646 EAPI Elm_Genlist_Item_Class *
5647 elm_genlist_item_class_new(void)
5649 Elm_Genlist_Item_Class *itc;
5651 itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
5654 itc->version = ELM_GENLIST_ITEM_CLASS_VERSION;
5656 itc->delete_me = EINA_FALSE;
5662 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
5664 if (itc && (itc->version == ELM_GENLIST_ITEM_CLASS_VERSION))
5666 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
5667 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
5677 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
5679 if (itc && (itc->version == ELM_GENLIST_ITEM_CLASS_VERSION))
5682 if (itc->refcount == 0) itc->refcount--;
5687 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
5689 if (itc && (itc->version == ELM_GENLIST_ITEM_CLASS_VERSION))
5691 if (itc->refcount > 0) itc->refcount--;
5692 if (itc->delete_me && (!itc->refcount))
5693 elm_genlist_item_class_free(itc);
5697 void _flip_job(void *data)
5699 Elm_Gen_Item *it = (Elm_Gen_Item *) data;
5700 _elm_genlist_item_unrealize(it, EINA_FALSE);
5701 if (it->selected) _item_unselect(it);
5702 it->flipped = EINA_TRUE;
5703 it->item->nocache = EINA_TRUE;
5707 elm_genlist_item_flip_set(Elm_Object_Item *it,
5710 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
5711 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5714 if (_it->flipped == flip) return;
5718 ecore_job_add(_flip_job, _it);
5719 if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
5720 _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
5724 _it->flipped = flip;
5725 _it->item->nocache = EINA_TRUE;
5726 _item_cache_zero(_it->wd);
5727 elm_genlist_item_update(it);
5732 elm_genlist_item_flip_get(const Elm_Object_Item *it)
5734 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
5735 Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
5736 return _it->flipped;
5739 /* for gengrid as of now */
5741 _elm_genlist_page_relative_set(Evas_Object *obj,
5745 Evas_Coord pagesize_h;
5746 Evas_Coord pagesize_v;
5748 ELM_CHECK_WIDTYPE(obj, widtype);
5749 Widget_Data *wd = elm_widget_data_get(obj);
5752 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5753 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5757 /* for gengrid as of now */
5759 _elm_genlist_page_relative_get(const Evas_Object *obj,
5763 ELM_CHECK_WIDTYPE(obj, widtype);
5764 Widget_Data *wd = elm_widget_data_get(obj);
5767 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5770 /* for gengrid as of now */
5772 _elm_genlist_page_size_set(Evas_Object *obj,
5773 Evas_Coord h_pagesize,
5774 Evas_Coord v_pagesize)
5779 ELM_CHECK_WIDTYPE(obj, widtype);
5780 Widget_Data *wd = elm_widget_data_get(obj);
5782 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5783 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5787 /* for gengrid as of now */
5789 _elm_genlist_current_page_get(const Evas_Object *obj,
5793 ELM_CHECK_WIDTYPE(obj, widtype);
5794 Widget_Data *wd = elm_widget_data_get(obj);
5796 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5799 /* for gengrid as of now */
5801 _elm_genlist_last_page_get(const Evas_Object *obj,
5805 ELM_CHECK_WIDTYPE(obj, widtype);
5806 Widget_Data *wd = elm_widget_data_get(obj);
5808 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5811 /* for gengrid as of now */
5813 _elm_genlist_page_show(const Evas_Object *obj,
5817 ELM_CHECK_WIDTYPE(obj, widtype);
5818 Widget_Data *wd = elm_widget_data_get(obj);
5820 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5823 /* for gengrid as of now */
5825 _elm_genlist_page_bring_in(const Evas_Object *obj,
5829 ELM_CHECK_WIDTYPE(obj, widtype);
5830 Widget_Data *wd = elm_widget_data_get(obj);
5832 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5836 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5839 Evas_Object *content;
5841 if (!it->realized) return;
5842 if (it->wd->reorder_it == it) return;
5844 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5846 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5849 ecore_timer_del(it->long_timer);
5850 it->long_timer = NULL;
5853 elm_widget_stringlist_free(it->texts);
5855 elm_widget_stringlist_free(it->contents);
5856 it->contents = NULL;
5857 elm_widget_stringlist_free(it->states);
5860 EINA_LIST_FREE(it->content_objs, content)
5861 evas_object_del(content);
5863 it->unrealize_cb(it);
5865 it->realized = EINA_FALSE;
5866 it->want_unrealize = EINA_FALSE;
5867 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5868 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5872 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5874 elm_widget_item_pre_notify_del(it);
5875 it->generation = it->wd->generation - 1; /* This means that the item is deleted */
5876 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5878 if (it->itc->func.del)
5879 it->itc->func.del((void *)it->base.data, WIDGET(it));
5883 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5885 _elm_genlist_item_del_notserious(it);
5886 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5887 if (it->tooltip.del_cb)
5888 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5889 it->wd->walking -= it->walking;
5890 if (it->long_timer) ecore_timer_del(it->long_timer);
5892 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5896 eina_inlist_sorted_state_free(it->wd->state);
5897 it->wd->state = NULL;
5899 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5900 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5904 if (it->wd->last_selected_item == (Elm_Object_Item *) it)
5905 it->wd->last_selected_item = NULL;
5906 it->wd->item_count--;